您好,
会员登录 快速注册
退出 ( 条未读消息)
关于本站 意见反馈 首页

公告:小宅博客网可以开发票了,需要发票的,去群里找群主哈!!
全部文章分类
  • 人工智能 >

  • 编程语言 >

  • WPF系列 >

  • ASP.NET系列 >

  • Linux >

  • 数据库 >

  • 嵌入式 >

  • WEB技术 >

  • PLC系列 >

  • 微服务与框架 >

  • 小宅DIY >

  • 学习资料 >

OpenCv基础 ANN车牌识别 yolov5车牌识别 指针式仪表识别 ROS系列 YOLO Halcon Detectron2 昇腾AI ChatGPT在线体验 英伟达JETSON ChatGLM ChatTTS FunASR 地平线 ByteTrack 魔搭社区 LangChain
C C# C++ Python Java Go
WPF
ASP.NET小功能 GPS定位系统-MVC GPS定位系统-VUE ASP.NET WebRTC
Linux Linux内核 Shell MakeFile
MySql SqlServer Oracle
STM8 STM32 51单片机
VUE入门 HTML JavaScript CSS layui镜像网站 ElementUi中文官网 element-plus 图标
三菱 欧姆龙 西门子 施耐德 松下 台达
IOTSharp IOTGateway ABP FRAMEWORK Docker
亚克力音响 编程仙途:智驭万法
面试题与技巧 Python入门技能树 微软C#教程
首页 编程之美 工具下载 全国就业 流量地图 文心一言
GPS定位系统-MVC
.NET6.0 GPS定位系统介绍(物联网) 系列源码下载 1、新建.net core web工程 2、添加自定义登录页面 3、添加百度地图页面 4、添加后台日志系统 5、添加mysql数据存储 6、添加SqlServer数据存储(额外内容) 7、用户注册与登录功能实现 8、添加坐标报表页面(用于遍历地图坐标) 9、前后端数据交互与报表数据展示 10、报表数据的编辑与修改 11、用户登录与退出 12、自定义GPRS通讯协议 13、添加TCP通讯功能(接收) 14、添加TCP通讯功能(发送) 15、模拟GPRS数据通讯 16、设备链接状态检测与提示 17、新建Windows Server虚拟机 18、服务器IIS运行环境配置 19、服务器.net程序发布 20、关于如何配置.net3.1框架 21、关于如何配置.net5.0框架 22、WinForm版地图上位机(带数据库和TCP功能) 23、WPF版地图上位机(带数据库和TCP功能) 24、公网映射与外网通讯 25、GPS协议与AT命令流程说明 26、GPRS协议与AT命令流程说明 27、STM32、A9G硬件连接图 28、STM32开发环境搭建 29、STM32 GPS/GPRS通讯功能实现 30、STM32 GPS定位数据上报服务器 31、室外最终效果演示 32、结束语
14、添加TCP通讯功能(发送)
16、设备链接状态检测与提示
激萌の小宅 小宅博客网 GPS定位系统-MVC

文章作者:激萌の小宅

促销:¥0

价格:¥0

配送方式: 购买后立即生效(如购买异常,请联系站长)
付款之后一定要等待自动跳转结束,否则购买可能会失败
  • 0 天

    有效期

  • 0

    总销量

  • 0

    累计评价

模拟GPRS数据通讯 - (第十五讲)

视频讲解如下:


工程源码下载:GPS定位系统系列教程源码下载


1、代码修改

        到目前为止,我们整个项目已经实现了上位机与模拟器的基本通讯,接下来,我们需要完善通讯协议中的数据载体部分,将我们需要上报的GPS坐标通过模拟器上传至上位机程序。

        我们的载体定义如下:

WORD

用户ID

DWORD

经度

DWORD

纬度

    

        由于是进行模拟测试,所以我们下位机是采用模拟的方式进行测试。模拟程序采用《如何实现TCP通信》原程序进行修改,源码我会放在工程包里面,供大家参考。上位机的主要修改的文件,以及修改内容说明如下:

QQ截图20220918123246.jpg


_GpsAnalysis.cs:添加对载荷数据的解析,解析出用户ID和经纬度

/// <summary>
/// 接收GPS数据
/// </summary>
/// <param name="p"></param>
/// <returns></returns>
public bool Abnormal()
{
    try
    {
        // 接收数据处理
        c.user = (int)p.context.Skip(0).Take(2).ToArray().ByteToInt(); // 当前用户ID
        c.Longitude = (Int32)p.context.Skip(2).Take(4).ToArray().ByteToInt() / (decimal)100000; // 经度
        c.Latitude = (Int32)p.context.Skip(6).Take(4).ToArray().ByteToInt() / (decimal)100000; // 纬度

        System.Diagnostics.Debug.WriteLine($"接收到GPS数据了:{c.user} {c.Longitude},{c.Latitude}");

        // 将最新的数据发送到前端
        Res.SenseDataMsg?.Invoke((int)p.equipmentNo.ByteToInt(), c.user, c.Longitude, c.Latitude);
        return true;
    }
    catch { return false; }
}


GpsModel.cs:新增用户ID和经纬度的存储变量

/// <summary>
/// 用户id
/// </summary>
public int user { get; set; }

/// <summary>
/// 经度
/// </summary>
public decimal Longitude { get; set; }

/// <summary>
/// 纬度
/// </summary>
public decimal Latitude { get; set; }


TcpSocketConnection.cs:链接断开的log文字写错了,写成“端开”了。。。

 

Link.Res.cs:新增数据回调的参数

// 下位机消息:设备号,用户ID,经度、纬度
public static Action<int ,int, decimal, decimal> SenseDataMsg = null;


HomeController.cs:新增获取最新的坐标的API:GetMap()

/// <summary>
/// 获取最新的坐标
/// </summary>
/// <returns></returns>
public ActionResult GetMap()
{
    AjaxResult res = new AjaxResult() { Success = false };
    try
    {
        User user = HttpContext.Session.GetString("user").ToObject<User>();
        if (user != null)
        {
            foreach(var p in Res.NewMap)
            {
                // 只获取当前用户的坐标信息
                if(p.user == user.ID)
                {
                    res.Data = new List<decimal>() { p.Longitude, p.Latitude }; //new List<double>() { 119.246, 26.08125 };
                    res.Success = true;
                    break;
                }
            }
        }
    }
    catch (Exception e)
    {
        res.ErrorCode = e.Message;
    }
    return Content(res.ToJson());
}


map.cshtml:新增post请求,向后端的GetMap(),不断获取最新的gps坐标

<script src="/js/jquery.min 1.11.3.js"></script>
<script>
    var Longitude = 0;
    var Latitude = 0;
    setInterval(function(){
        $.post('GetMap', null, function (resJson) {
            var res = JSON.parse(resJson);
            if (res.Success) {
                var data = res.Data;
                if (Longitude != data[0] || Latitude != data[1]) {
                    console.log(data);
                    Longitude = data[0];
                    Latitude = data[1];
                    ListLocation(data[0], data[1]);
                }
            }
        });
    }, 1000);
</script>


WebApplicationGPS.Res.cs:新增最新GPS坐标的缓存:NewMap

using DbEntity;

namespace WebApplicationGPS
{
    public static class Res
    {
        /// <summary>
        /// 数据库链接字符串
        /// </summary>
        public static string? SqlStr { set; get; }

        /// <summary>
        /// 数据库
        /// </summary>
        public static MyDbContext MyDb { set; get; }

        /// <summary>
        /// 最新坐标:用户ID,经度、纬度
        /// </summary>
        public static List<MapPack> NewMap { set; get; } = new List<MapPack>();
    }

    public class MapPack
    {
        public int user { set; get; }
        public decimal Longitude { set; get; }
        public decimal Latitude { set; get; }
    }
}

ServerInit.cs:修改回调

/// <summary>
/// 事件初始化
/// </summary>
private void EventInit()
{
    // 保存GPS数据
    Link.Res.SenseDataMsg = (dev, a, b, c) =>
    {
        System.Diagnostics.Debug.WriteLine($"SenseDataMsg 接收到数据:{a},{b},{c}");

        // 如果用户不存在,属于非法数据,可以忽略
        User user = Res.MyDb.Tb_User.FirstOrDefault(x => x.ID == a);
        if (user == null) return;

        // 将接收到的数据更新到缓存中,供前端显示
        MapPack p = Res.NewMap.FirstOrDefault(x => x.user == a);
        if(p != null)
        {
            p.Longitude = b;
            p.Latitude = c;
        }
        else
        {
            Res.NewMap.Add(new MapPack() {
                user = a,
                Longitude = b,
                Latitude = c
            });
        }

        // 将接收到的数据保存到数据库
        using (MyDbContext db = new MyDbContext() { config = Res.SqlStr })
        {
            GpsData data = new GpsData()
            {
                CreateTime = DateTime.Now,
                UpdateTime = DateTime.Now,
                UserId = user.UserId,
                gps = $"{b},{c}"
            };
            db.Tb_GpsData.Add(data);
            db.SaveChanges();
        }
    };

    // 后面可以扩展
    /* ... */
}


2、关于模拟器

        拟程序采用《如何实现TCP通信》原程序进行修改,模拟器上报的主要数据组装代码如下:

/// <summary>
/// 组装数据
/// </summary>
/// <param name="oData"></param>
/// <returns></returns>
private byte[] order_11()
{
    byte[] oData = new byte[500];
    int ret = 0;
    oData[ret++] = 0xCC; // 网络识别码
    oData[ret++] = 0x01; // 设备类型
    oData[ret++] = 0x00; // 设备号H
    oData[ret++] = 0x01; // 设备号L
    int PackNum = 0    ; // 包号应该是按累加处理的,我这里测试,直接写死
    oData[ret++] = (byte)(PackNum >> 8);     //  包号H
    oData[ret++] = (byte)(PackNum & 0x00FF); //  包号L
    oData[ret++] = 0x11; // 功能码
    // 用户ID 
    int user = (int)numericUpDown1.Value;
    oData[ret++] = (byte)(user >> 8);     //  用户ID H
    oData[ret++] = (byte)(user & 0x00FF); //  用户ID L

    // 经度
    long a = (long)((decimal)numericUpDown2.Value * 100000);
    oData[ret++] = (byte)((a >> 24) & 0x000000FF);
    oData[ret++] = (byte)((a >> 16) & 0x000000FF);
    oData[ret++] = (byte)((a >> 8) & 0x000000FF);
    oData[ret++] = (byte)(a & 0x000000FF);

    // 纬度
    long b = (long)((decimal)numericUpDown3.Value * 100000);
    oData[ret++] = (byte)((b >> 24) & 0x000000FF);
    oData[ret++] = (byte)((b >> 16) & 0x000000FF);
    oData[ret++] = (byte)((b >> 8) & 0x000000FF);
    oData[ret++] = (byte)(b & 0x000000FF);

    // 校验
    oData[ret++] = GetSum(oData);
    return oData.Take(ret).ToArray();
}

        界面如下:

QQ截图20220918124520.jpg

        这里要注意了,模拟器必须是作为客户端使用,端口为2233,这个端口、设备类型、设备号等信息在上位机LinkInit()函数中有定义:

QQ截图20220918124751.jpg


3、运行效果演示

1 (1).gif


报表数据如下:

QQ截图20220918125832.jpg

14、添加TCP通讯功能(发送)
16、设备链接状态检测与提示

友情链接: CSDN激萌の小宅 95知识库 自考题库 罗分明个人网络博客 精益编程leanboot

小宅博客  www.bilibili996.com All Rights Reserved. 备案号: 闽ICP备2024034575号

网站经营许可证  福建省福州市 Copyright©2021-2025 版权所有

小宅博客
首页 智能家居 地图定位
公告:小宅博客网可以开发票了,需要发票的,去群里找群主哈!!

文章作者:激萌の小宅

促销:¥0

价格:¥0

配送方式: 购买后立即生效(如购买异常,请联系站长)
付款之后一定要等待自动跳转结束,否则购买可能会失败
  • 0 天

    有效期

  • 0

    总销量

  • 0

    累计评价

模拟GPRS数据通讯 - (第十五讲)

视频讲解如下:


工程源码下载:GPS定位系统系列教程源码下载


1、代码修改

        到目前为止,我们整个项目已经实现了上位机与模拟器的基本通讯,接下来,我们需要完善通讯协议中的数据载体部分,将我们需要上报的GPS坐标通过模拟器上传至上位机程序。

        我们的载体定义如下:

WORD

用户ID

DWORD

经度

DWORD

纬度

    

        由于是进行模拟测试,所以我们下位机是采用模拟的方式进行测试。模拟程序采用《如何实现TCP通信》原程序进行修改,源码我会放在工程包里面,供大家参考。上位机的主要修改的文件,以及修改内容说明如下:

QQ截图20220918123246.jpg


_GpsAnalysis.cs:添加对载荷数据的解析,解析出用户ID和经纬度

/// <summary>
/// 接收GPS数据
/// </summary>
/// <param name="p"></param>
/// <returns></returns>
public bool Abnormal()
{
    try
    {
        // 接收数据处理
        c.user = (int)p.context.Skip(0).Take(2).ToArray().ByteToInt(); // 当前用户ID
        c.Longitude = (Int32)p.context.Skip(2).Take(4).ToArray().ByteToInt() / (decimal)100000; // 经度
        c.Latitude = (Int32)p.context.Skip(6).Take(4).ToArray().ByteToInt() / (decimal)100000; // 纬度

        System.Diagnostics.Debug.WriteLine($"接收到GPS数据了:{c.user} {c.Longitude},{c.Latitude}");

        // 将最新的数据发送到前端
        Res.SenseDataMsg?.Invoke((int)p.equipmentNo.ByteToInt(), c.user, c.Longitude, c.Latitude);
        return true;
    }
    catch { return false; }
}


GpsModel.cs:新增用户ID和经纬度的存储变量

/// <summary>
/// 用户id
/// </summary>
public int user { get; set; }

/// <summary>
/// 经度
/// </summary>
public decimal Longitude { get; set; }

/// <summary>
/// 纬度
/// </summary>
public decimal Latitude { get; set; }


TcpSocketConnection.cs:链接断开的log文字写错了,写成“端开”了。。。

 

Link.Res.cs:新增数据回调的参数

// 下位机消息:设备号,用户ID,经度、纬度
public static Action<int ,int, decimal, decimal> SenseDataMsg = null;


HomeController.cs:新增获取最新的坐标的API:GetMap()

/// <summary>
/// 获取最新的坐标
/// </summary>
/// <returns></returns>
public ActionResult GetMap()
{
    AjaxResult res = new AjaxResult() { Success = false };
    try
    {
        User user = HttpContext.Session.GetString("user").ToObject<User>();
        if (user != null)
        {
            foreach(var p in Res.NewMap)
            {
                // 只获取当前用户的坐标信息
                if(p.user == user.ID)
                {
                    res.Data = new List<decimal>() { p.Longitude, p.Latitude }; //new List<double>() { 119.246, 26.08125 };
                    res.Success = true;
                    break;
                }
            }
        }
    }
    catch (Exception e)
    {
        res.ErrorCode = e.Message;
    }
    return Content(res.ToJson());
}


map.cshtml:新增post请求,向后端的GetMap(),不断获取最新的gps坐标

<script src="/js/jquery.min 1.11.3.js"></script>
<script>
    var Longitude = 0;
    var Latitude = 0;
    setInterval(function(){
        $.post('GetMap', null, function (resJson) {
            var res = JSON.parse(resJson);
            if (res.Success) {
                var data = res.Data;
                if (Longitude != data[0] || Latitude != data[1]) {
                    console.log(data);
                    Longitude = data[0];
                    Latitude = data[1];
                    ListLocation(data[0], data[1]);
                }
            }
        });
    }, 1000);
</script>


WebApplicationGPS.Res.cs:新增最新GPS坐标的缓存:NewMap

using DbEntity;

namespace WebApplicationGPS
{
    public static class Res
    {
        /// <summary>
        /// 数据库链接字符串
        /// </summary>
        public static string? SqlStr { set; get; }

        /// <summary>
        /// 数据库
        /// </summary>
        public static MyDbContext MyDb { set; get; }

        /// <summary>
        /// 最新坐标:用户ID,经度、纬度
        /// </summary>
        public static List<MapPack> NewMap { set; get; } = new List<MapPack>();
    }

    public class MapPack
    {
        public int user { set; get; }
        public decimal Longitude { set; get; }
        public decimal Latitude { set; get; }
    }
}

ServerInit.cs:修改回调

/// <summary>
/// 事件初始化
/// </summary>
private void EventInit()
{
    // 保存GPS数据
    Link.Res.SenseDataMsg = (dev, a, b, c) =>
    {
        System.Diagnostics.Debug.WriteLine($"SenseDataMsg 接收到数据:{a},{b},{c}");

        // 如果用户不存在,属于非法数据,可以忽略
        User user = Res.MyDb.Tb_User.FirstOrDefault(x => x.ID == a);
        if (user == null) return;

        // 将接收到的数据更新到缓存中,供前端显示
        MapPack p = Res.NewMap.FirstOrDefault(x => x.user == a);
        if(p != null)
        {
            p.Longitude = b;
            p.Latitude = c;
        }
        else
        {
            Res.NewMap.Add(new MapPack() {
                user = a,
                Longitude = b,
                Latitude = c
            });
        }

        // 将接收到的数据保存到数据库
        using (MyDbContext db = new MyDbContext() { config = Res.SqlStr })
        {
            GpsData data = new GpsData()
            {
                CreateTime = DateTime.Now,
                UpdateTime = DateTime.Now,
                UserId = user.UserId,
                gps = $"{b},{c}"
            };
            db.Tb_GpsData.Add(data);
            db.SaveChanges();
        }
    };

    // 后面可以扩展
    /* ... */
}


2、关于模拟器

        拟程序采用《如何实现TCP通信》原程序进行修改,模拟器上报的主要数据组装代码如下:

/// <summary>
/// 组装数据
/// </summary>
/// <param name="oData"></param>
/// <returns></returns>
private byte[] order_11()
{
    byte[] oData = new byte[500];
    int ret = 0;
    oData[ret++] = 0xCC; // 网络识别码
    oData[ret++] = 0x01; // 设备类型
    oData[ret++] = 0x00; // 设备号H
    oData[ret++] = 0x01; // 设备号L
    int PackNum = 0    ; // 包号应该是按累加处理的,我这里测试,直接写死
    oData[ret++] = (byte)(PackNum >> 8);     //  包号H
    oData[ret++] = (byte)(PackNum & 0x00FF); //  包号L
    oData[ret++] = 0x11; // 功能码
    // 用户ID 
    int user = (int)numericUpDown1.Value;
    oData[ret++] = (byte)(user >> 8);     //  用户ID H
    oData[ret++] = (byte)(user & 0x00FF); //  用户ID L

    // 经度
    long a = (long)((decimal)numericUpDown2.Value * 100000);
    oData[ret++] = (byte)((a >> 24) & 0x000000FF);
    oData[ret++] = (byte)((a >> 16) & 0x000000FF);
    oData[ret++] = (byte)((a >> 8) & 0x000000FF);
    oData[ret++] = (byte)(a & 0x000000FF);

    // 纬度
    long b = (long)((decimal)numericUpDown3.Value * 100000);
    oData[ret++] = (byte)((b >> 24) & 0x000000FF);
    oData[ret++] = (byte)((b >> 16) & 0x000000FF);
    oData[ret++] = (byte)((b >> 8) & 0x000000FF);
    oData[ret++] = (byte)(b & 0x000000FF);

    // 校验
    oData[ret++] = GetSum(oData);
    return oData.Take(ret).ToArray();
}

        界面如下:

QQ截图20220918124520.jpg

        这里要注意了,模拟器必须是作为客户端使用,端口为2233,这个端口、设备类型、设备号等信息在上位机LinkInit()函数中有定义:

QQ截图20220918124751.jpg


3、运行效果演示

1 (1).gif


报表数据如下:

QQ截图20220918125832.jpg