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

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

  • 编程语言 >

  • 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 图标 Vue - Ant Design官方
三菱 欧姆龙 西门子 施耐德 松下 台达
IOTSharp IOTGateway ABP FRAMEWORK Docker
亚克力音响 编程仙途:智驭万法
面试题与技巧 Python入门技能树 微软C#教程
首页 编程之美 工具下载 全国就业 流量地图 文心一言
GPS定位-EC-01G
ASP.NET GPS定位系统介绍(物联网) GPS定位EC-01G模块系列教程源码下载页(物联网) 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、asp.net发布\winform\wpf版本操作流程 18、GPS协议与AT命令流程说明
14、添加TCP通讯功能(发送)
16、设备链接状态检测与提示
激萌の小宅 小宅博客 GPS定位-EC-01G

文章作者:激萌の小宅

促销:¥0

价格:¥0

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

    有效期

  • 0

    总销量

  • 0

    累计评价

模拟GPRS数据通讯

参考视频如下,视频来源《GPS定位系统-MVC-模拟GPRS数据通讯》

备注:视频中的部分操作可能会因为Visual Studio的版本差异有所不一样,总体操作流程都是一样的,请自行尝试。视频中采用的是安信可的A9G模块,和当前系列使用的EC-01G模块在AT指令上可能存在差异,这里以博客内容为主,视频主要是讲操作流程。


工程源码下载:GPS定位EC-01G模块系列教程源码下载页(物联网)

IDE环境:Visual Studio 2022


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();
}

        界面如下:

微信截图_20250403160421.jpg

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

用户ID要和数据库中的ID保持一致

QQ截图20220918124751.jpg


设置百度坐标,然后选择本地发送。

微信截图_20250403160635.jpg


3、运行效果演示

1 (1).gif


报表数据如下:

QQ截图20220918125832.jpg


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

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

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

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

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

文章作者:激萌の小宅

促销:¥0

价格:¥0

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

    有效期

  • 0

    总销量

  • 0

    累计评价

模拟GPRS数据通讯

参考视频如下,视频来源《GPS定位系统-MVC-模拟GPRS数据通讯》

备注:视频中的部分操作可能会因为Visual Studio的版本差异有所不一样,总体操作流程都是一样的,请自行尝试。视频中采用的是安信可的A9G模块,和当前系列使用的EC-01G模块在AT指令上可能存在差异,这里以博客内容为主,视频主要是讲操作流程。


工程源码下载:GPS定位EC-01G模块系列教程源码下载页(物联网)

IDE环境:Visual Studio 2022


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();
}

        界面如下:

微信截图_20250403160421.jpg

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

用户ID要和数据库中的ID保持一致

QQ截图20220918124751.jpg


设置百度坐标,然后选择本地发送。

微信截图_20250403160635.jpg


3、运行效果演示

1 (1).gif


报表数据如下:

QQ截图20220918125832.jpg