『瀚思彼岸』» 智能家居技术论坛

 找回密码
 立即注册
查看: 275|回复: 10

[技术探讨] 小白教小白-用大夏龙雀CT511N-A模块自制车载gps

[复制链接]

33

主题

312

帖子

1847

积分

金牌会员

Rank: 6Rank: 6

积分
1847
金钱
1530
HASS币
40
发表于 前天 10:53 | 显示全部楼层 |阅读模式
本帖最后由 lione95678 于 2024-11-19 11:10 编辑

  起因:最早只是想买一个4g串口透传模块,后来看到大夏龙雀的CT511N-A模块,新手套餐价格19.9,还包1年360m的流量(每月30m),想想干脆做一个车载gps也不错,放在老爷子的车上,也就有了这篇内容。
  说明:车载端使用大夏龙雀CT511N-A模块,搭配stc8g1k08a单片机使用,服务器端使用traccar和mqtt搭配node-red的mqtt接收和http get使用。
  原理:大夏龙雀CT511N-A模块在设置好gps后,大概会以每秒1次的频率通过串口发送gps信息,通过stc8g1k08a单片机的串口接收这些数据,刷选出我们需要的,然后串口发送给大夏龙雀CT511N-A模块,让大夏龙雀CT511N-A模块通过mqtt的方式发送给mqtt服务器,nod-red的mqtt接收到这些数据后发送给traccar服务端。注意,这里你自己的mqtt服务器必须是可以外网连接到的。(其实可以直接通过大夏龙雀CT511N-A模块的http get方式连接到traccar服务器,但是我这里没有使用,我是小白。另外,好像看到帖子说mqtt方式也可以直接连接traccar服务器)
硬件连接方面:买到的CT511N-A模块有6个引脚,我是用了其中4个,即vcc、gnd、rx、tx,将vcc、gnd连接到stc8g1k08a的vcc、gnd后,连接到外部5v电源(车载的话搞一个12v转5v的降压模块),CT511N-A的rx连接stc8g1k08a的tx,CT511N-A的tx连接stc8g1k08a的rx,最基本的硬件连接这样就可以了。后续考究点的,可以使用嘉立创打板后连接,我是偷懒了,又急着用,就直接用一块SOP8贴片转DIP直插的转接板焊接stc8g1k08a,然后用切了一小块洞洞板,用排母连接。  这里我提供了stc8g1k08a单片机的相关文件,你将文件解压缩,然后需要使用Keil打开gps.uvproj文件后,修改main文件的第63、65、69、185行的内容,修改成你自己的mqtt服务器地址和mqtt-topic等,然后编译下载到stc8g1k08a单片机即可使用。
  关于stc8g1k08a单片机的使用,小白可以看一下bilibili网站的教学视频,这里推荐一个,看了以后最基本的刷机,使用就没有什么大问题了,我这里就用了他的uart库函数,也使用了他的串口信息处理方式。https://www.bilibili.com/video/BV1gE411H7Nb?spm_id_from=333.788.videopod.sections&vd_source=cc2d0ed5f6c37d0a6598b20d7cabe37c
  稍微说一下stc8g1k08a单片机的main文件,大家可以用Keil打开gps.uvproj文件或者直接用vscode打开main.c文件。我用了官方库函数中的gpio库函数和上面视频中的库函数中的uart库函数和延时库函数。第一步:使用了库函数和定义了几个常量;第二步:主函数中,先初始化GPIO和串口,然后延时20秒,让4g模块可以收到4g信号(这一步不知道有没有必要,没有多测试),再让单片机通过发送AT命令,让4g模块打开网络,并配置mqtt信息,同时向mqtt服务器发送一条信息,表明4g-gps模块已上线了。然后死循环中就是毫无意义的延时(实际上死循环中应该可以不用写内容)第三步:使用串口的中断触发,当单片机串口收到4g-gps模块的gps数据后,只选取以“$GNGGA”开头的70个字符,然后把这些数据发送给4g-gps模块,让4g-gps模块使用mqtt发送给mqtt服务器。(因为gps模块会以大概每秒一次的频率发送一大段 “$GNRMC,081906.000,A,3111.123456,N,12345.123456,E,0.042,0.00,091124,,E,A*01”、“$GNGGA$GNGGA,081906.000,3111.123456,N,12345.123456,E,1,25,0.66,17.716,M,0,M,,*60”等数据,我们需要选取所需要的数据)。
  后续配置一下node-red,使用node-red的mqttin节点,接收这些数据,再把这些数据转给traccar服务器,traccar服务器的搭建,可以看一下论坛里bg6rsh的帖子,我就是用的他的https://bbs.hassbian.com/forum.php?mod=viewthread&tid=11353&highlight=traccar
  流量方面,30m/月的流量基本够你使用了,按照现在的价格,后续流量包年,5元/年,是30m/月。7元/年,是100m/月。流量叠加包的话,是100m/月的价格1.2元。

  大夏龙雀CT511N-A模块资料下载地址:http://www.szdx-smart.com/zlxz/4Gmk/4Gmokuai/407.htmlnode-red节点:
[
    {
        "id": "3843de2a8ce37b65",
        "type": "function",
        "z": "eb91aafe711c13c9",
        "name": "提取经纬度等信息",
        "func": "msg.zuobiao = msg.payload.split(',');\nmsg.topic1 = msg.zuobiao[0];\nmsg.time1 = msg.zuobiao[1];\nmsg.lat = msg.zuobiao[2];\nmsg.long = msg.zuobiao[4];\nvar id;\nif (msg.topic ==='gps/a88888'){\n    id = "123456";\n}\nmsg.id = id;\nreturn msg;\n//上面的'gps/a88888'要配合你单片机发送的“mqtt标题”来写\n//上面的"123456"要配合你traccar服务器中的设备id来写,这里写了什么数字,traccar添加新设备时,id号也要这么写\n",
        "outputs": 1,
        "timeout": 0,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 750,
        "y": 280,
        "wires": [
            [
                "71f7b33471dd5d7c"
            ]
        ]
    },
    {
        "id": "5e01de19f50b84f9",
        "type": "inject",
        "z": "eb91aafe711c13c9",
        "name": "",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "gps/550g08",
        "payload": "$GNGGA,084213.000,3104.147644,N,12131.553192,E,1,19,0.93,-17.558,M,0,M",
        "payloadType": "str",
        "x": 570,
        "y": 360,
        "wires": [
            [
                "3843de2a8ce37b65"
            ]
        ]
    },
    {
        "id": "46de3ec344d01f19",
        "type": "mqtt in",
        "z": "eb91aafe711c13c9",
        "name": "",
        "topic": "gps/#",
        "qos": "0",
        "datatype": "auto-detect",
        "broker": "",
        "nl": false,
        "rap": true,
        "rh": 0,
        "inputs": 0,
        "x": 270,
        "y": 280,
        "wires": [
            [
                "3843de2a8ce37b65",
                "62cce39ea438f052"
            ]
        ]
    },
    {
        "id": "71f7b33471dd5d7c",
        "type": "function",
        "z": "eb91aafe711c13c9",
        "name": "经纬度十进制转换",
        "func": "var lat = msg.lat;\nvar long = msg.long;\nvar latd;\nvar latf;\nvar lats;\nvar longd;\nvar longf;\nvar longs;\n\nvar latitude;\nvar longitude;\n\nlatd = lat.substring(0, 2);\nlatf = lat.substring(2);\nlats = latf/60;\n\nlatitude = parseFloat(latd) + parseFloat(lats);\n\nlongd = long.substring(0, 3);\nlongf = long.substring(3);\nlongs = longf/60;\n\nlongitude = parseFloat(longd) + parseFloat(longs);\n// msg.latd = latd;\n// msg.latf = latf;\n// msg.lats = lats;\n\n// msg.longd = longd;\n// msg.longf = longf;\n// msg.longs = longs;\n\nmsg.latitude = latitude;\nmsg.longitude = longitude;\nmsg.timestamp = new Date().getTime();\nreturn msg;\n\n//这个节点的内容不需要修改",
        "outputs": 1,
        "timeout": 0,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 990,
        "y": 280,
        "wires": [
            [
                "f42155c1a3d97fbd"
            ]
        ]
    },
    {
        "id": "f42155c1a3d97fbd",
        "type": "function",
        "z": "eb91aafe711c13c9",
        "name": "发送给traccar",
        "func": "var time = msg.timestamp;\nvar lan = msg.latitude;\nvar lon = msg.longitude;\nvar id = msg.id;\n\nvar url = "http://192.168.1.244:5055/?id="+id+"&lat="+lan+"&lon="+lon+"×tamp="+time;\n\n//global.set("token",msg.payload.token);\n//global.set("s_cookie",msg.responseCookies)\nvar _msg = {};\n_msg.url = url;\n_msg.method = "GET";\n//_msg.cookies = global.get("s_cookie")\n//_msg.payload = JSON.stringify({ \n //                       "deviceId": 12345000,\n //                       "description": "MSG",\n //                       "type": "custom",\n  //                      "attributes": {\n //                           "data":   "CETest" \n //                           }\n //                       }  )  \n//_msg.headers = {"content-type": "application/json"};\n//msg.headers["X-Requested-With"] = "XMLHttpRequest"\nreturn _msg;\n\n\n//上面http://192.168.1.244:5055要修改成你traccar服务器的地址和端口号\n",
        "outputs": 1,
        "timeout": "",
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 1200,
        "y": 280,
        "wires": [
            [
                "749acf0987f58444"
            ]
        ]
    },
    {
        "id": "749acf0987f58444",
        "type": "http request",
        "z": "eb91aafe711c13c9",
        "name": "",
        "method": "use",
        "ret": "obj",
        "paytoqs": "ignore",
        "url": "",
        "tls": "",
        "proxy": "",
        "authType": "",
        "x": 1380,
        "y": 280,
        "wires": [
            []
        ]
    },
    {
        "id": "62cce39ea438f052",
        "type": "debug",
        "z": "eb91aafe711c13c9",
        "name": "debug 6",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "false",
        "statusVal": "",
        "statusType": "auto",
        "x": 360,
        "y": 340,
        "wires": []
    },
    {
        "id": "52be647418a619d9",
        "type": "comment",
        "z": "eb91aafe711c13c9",
        "name": "这里的'gps/#要配合你单片机发送的“mqtt标题”来写",
        "info": "",
        "x": 410,
        "y": 120,
        "wires": []
    },
    {
        "id": "e98bb2f66bd8ea76",
        "type": "comment",
        "z": "eb91aafe711c13c9",
        "name": "比如你单片机里写的mqtt标题是gps/a88888,那么这个节点就可以收到",
        "info": "",
        "x": 470,
        "y": 160,
        "wires": []
    },
    {
        "id": "0e0953cdbfa0e7cc",
        "type": "comment",
        "z": "eb91aafe711c13c9",
        "name": "我是为了方便后续使用多个4g-gps模块,打算统一以标题“gps/车牌号”的方式来发送mqtt信息,所以这么写的",
        "info": "",
        "x": 580,
        "y": 200,
        "wires": []
    }
]

以后你还可以添加单片机的其他功能,让这个模块扩展更多玩法,比如我后续会增加几个按键,让单片机通过外部中断的方式,发送信息开关车库门等等。看来要学学单片机的知识了,价格便宜,玩法较多。stc8g1k08a只要7毛钱。



评分

参与人数 2金钱 +24 收起 理由
zouguo + 8 墙都不扶,就服楼主!
sorrypqa + 16 高手,这是高手!

查看全部评分

回复

使用道具 举报

33

主题

312

帖子

1847

积分

金牌会员

Rank: 6Rank: 6

积分
1847
金钱
1530
HASS币
40
 楼主| 发表于 前天 10:58 | 显示全部楼层
这是单片机的相关文件,解压缩后使用keil修改后重新编译

控制gps模块.rar

193.25 KB, 下载次数: 2

回复

使用道具 举报

33

主题

312

帖子

1847

积分

金牌会员

Rank: 6Rank: 6

积分
1847
金钱
1530
HASS币
40
 楼主| 发表于 前天 10:59 | 显示全部楼层
这是单片机main.c文件内容
/*****************************************************************************
* 例程名称                 : 空工程
* 说明         : 新建项目可以直接复制空工程开始编程。
* 接线方式     : ---
* 注意                     : ---
*******************************************************************************/

//--包含你要使用的头文件--//
#include "config.h"          //通用配置头文件

//--声明一些要使用的常量--//
uchar UART2_FLAG =0;     //状态机   初始状态=0  收到第一个符合条件的字符后 =1  等待第二个符合条件的字符后 =>3 第几个数据

uchar GPS_Data[90];    //接受到的完整数据
unsigned char f;
uchar a;






/******************* IO配置函数 *******************/
void        GPIO_config(void)
{
        GPIO_InitTypeDef        GPIO_InitStructure;                //结构定义

        GPIO_InitStructure.Pin  = GPIO_Pin_2 | GPIO_Pin_3;                //指定要初始化的IO, GPIO_Pin_0 ~ GPIO_Pin_7
        GPIO_InitStructure.Mode =GPIO_OUT_PP;        //指定IO的输入或输出方式,GPIO_PullUp,GPIO_HighZ,GPIO_OUT_OD,GPIO_OUT_PP
        GPIO_Inilize(GPIO_P3,&GPIO_InitStructure);        //初始化
}


/*******************************************************************************
* 函 数 名         : main
* 函数功能                     : 主函数
* 输    入         : 无
* 输    出         : 无
*******************************************************************************/
void main(void)
{ 

  GPIO_config();  //gpio初始化
        delay_X_ms(10);
        
        UART_init(1,115200,1);  //串口1初始化
        delay_X_ms(10);
        P32 = 1;         //这里安装了2个led,一个用作电源指示灯,当单片机启动后就亮灯,一个用作gps指示灯,每发送一次gps信息指示灯闪烁一次
        P33 = 1;


  for( a = 1; a < 20; a = a + 1 ) //循环20次执行等待1秒,即等待20秒
        {
                delay_X_ms(1000);
        }
        //每隔1秒向4g模块发送以下命令,用于开启模块4g和mqtt
        UART_Send_string(1,"ATE0\r\n"); //关闭gps模块的指令回显
        delay_X_ms(1000);
        UART_Send_string(1,"AT+QICSGP=1,2\r\n"); //配置APN,连接标识符,连接类型,访问点名称,用户名,密码(不想填写的就不用写进去,后面也一样)
        delay_X_ms(1000);
        UART_Send_string(1,"AT+NETOPEN\r\n");  //打开数据网络开关
        delay_X_ms(1000);
        UART_Send_string(1,"AT+MCONFIG=设备id,用户名,密码,0\r\n"); //填写MQTT服务器信息1、设备id,用户名,密码,遗嘱开关,遗嘱qos,保留标志,遗嘱内容,前面的内容请自行修改
        delay_X_ms(1000);
        UART_Send_string(1,"AT+MIPSTART=服务器地址,1883,3\r\n"); //填写MQTT服务器信息2、服务器地址,端口号,mqtt协议版本,前面的内容请自行修改
        delay_X_ms(1000);
        UART_Send_string(1,"AT+MCONNECT=1,60\r\n"); //连接MQTT服务器
        delay_X_ms(1000);
        UART_Send_string(1,"AT+MPUB=mqtt标题,0,0,mqtt内容\r\n"); //发送MQTT信息,前面的内容请自行修改
        delay_X_ms(1000);
        UART_Send_string(1,"AT+MGPSC=1\r\n"); //打开GPS开关
        delay_X_ms(1000);
        
        
        
        
        
 
        
        
        while(1)
        {
                delay_X_ms(1000);
                delay_X_ms(1000);
                delay_X_ms(1000);

                
        }
}

void UART1_isr(void)  //说明收到数据了
{
        uchar Dat = SBUF;    //读到这次的数据
        
        //UART_Send_byte(1,UART2_FLAG); //用串口1把串口2的数据发出来
        //gps的数据示例:
        //$GNGGA,081906.000,3111.123456,N,12345.123456,E,1,25,0.66,17.716,M,0,M,,*60
        //$GNRMC,081906.000,A,3111.123456,N,12345.123456,E,0.042,0.00,091124,,E,A*01
        
        switch(UART2_FLAG)
        {
                case 0:
                {
                        if(Dat == 0x24)     //判断第一个字符是不是“$”
                        {
                                GPS_Data[UART2_FLAG] = Dat;   //存起来
                                UART2_FLAG=1;       //状态置1
                        }
                        break;
                }
                case 1:
                {
                        if(Dat == 0x47)    //判断第二个字符是不是“G”
                        {
                                GPS_Data[UART2_FLAG] = Dat;   //存起来
                                UART2_FLAG=2;       //状态置2
                        }
                        else
                        {
                                UART2_FLAG = 0;       //状态置0
                        }
                        break;
                }
                case 2:
                {
                        if(Dat == 0x4E)    //判断第三个字符是不是“N”
                        {
                                GPS_Data[UART2_FLAG] = Dat;   //存起来
                                UART2_FLAG=3;       //状态置2
                        }
                        else
                        {
                                UART2_FLAG = 0;       //状态置0
                        }
                        break;
                }
                case 3:
                {
                        if(Dat == 0x47)    //判断第四个字符是不是“G”
                        {
                                GPS_Data[UART2_FLAG] = Dat;   //存起来
                                UART2_FLAG=4;       //状态置2
                        }
                        else
                        {
                                UART2_FLAG = 0;       //状态置0
                        }
                        break;
                }
                case 4:
                {
                        if(Dat == 0x47)    ////判断第五个字符是不是“G”
                        {
                                GPS_Data[UART2_FLAG] = Dat;   //存起来
                                UART2_FLAG=5;       //状态置2
                        }
                        else
                        {
                                UART2_FLAG = 0;       //状态置0
                        }
                        break;
                }
                case 5:
                {
                        if(Dat == 0x41)    ////判断第六个字符是不是“A”
                        {
                                GPS_Data[UART2_FLAG] = Dat;   //存起来
                                UART2_FLAG=6;       //状态置2
                        }
                        else
                        {
                                UART2_FLAG = 0;       //状态置0
                        }
                        break;
                }
                

                default:
                {
                        GPS_Data[UART2_FLAG] = Dat;
                        UART2_FLAG++;
                        if(UART2_FLAG>70)  //判断终止条件,这里截取了70个字符
                        {
                                UART2_FLAG = 0;       //状态置0
                                UART_Send_string(1,"AT+MPUB=mqtt标题,0,0,");//请将mqtt标题修改为你自己需要的
                                UART_Send_byte(1,0x22);
                                for( a = 0; a < 70; a = a + 1 )
                                {
                                        UART_Send_byte(1,GPS_Data[a]);
                                }

        UART_Send_byte(1,0x22);
                    UART_Send_byte(1,0x0D);
                    UART_Send_byte(1,0x0A);
                                P32 = !P32;


                          }
                        break;
                }
        }
}
回复

使用道具 举报

4

主题

327

帖子

2454

积分

金牌会员

Rank: 6Rank: 6

积分
2454
金钱
2127
HASS币
0
发表于 前天 17:10 | 显示全部楼层
30M够用不?
回复

使用道具 举报

24

主题

579

帖子

2679

积分

金牌会员

Rank: 6Rank: 6

积分
2679
金钱
2100
HASS币
0
发表于 前天 17:11 | 显示全部楼层
这个难度感觉还是高了
回复

使用道具 举报

0

主题

57

帖子

552

积分

高级会员

Rank: 4

积分
552
金钱
495
HASS币
0
发表于 前天 17:31 | 显示全部楼层
很不错啊,谢谢分享,可以搞下
回复

使用道具 举报

55

主题

299

帖子

5045

积分

元老级技术达人

积分
5045
金钱
4736
HASS币
80
发表于 前天 18:37 | 显示全部楼层
模块支持二次开发的话可以省掉单片机
回复

使用道具 举报

33

主题

312

帖子

1847

积分

金牌会员

Rank: 6Rank: 6

积分
1847
金钱
1530
HASS币
40
 楼主| 发表于 5 小时前 | 显示全部楼层

看你怎么用了,我这老爷子前几天自驾游海南,开了2300公里,按每小时100公里的时速算,用时23小时,用了大概13m的流量
回复

使用道具 举报

33

主题

312

帖子

1847

积分

金牌会员

Rank: 6Rank: 6

积分
1847
金钱
1530
HASS币
40
 楼主| 发表于 5 小时前 | 显示全部楼层
ryanh7 发表于 2024-11-19 18:37
模块支持二次开发的话可以省掉单片机

这个模块使用说明里明确需要另外的mcu,都是固定死的。我一开始觉得每秒1次发送gps信息太快,问了一下客服,他说通过串口发送gps信息的频率不能修改。
回复

使用道具 举报

55

主题

299

帖子

5045

积分

元老级技术达人

积分
5045
金钱
4736
HASS币
80
发表于 5 小时前 | 显示全部楼层
对自己好点,考虑一下air780eg
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|Hassbian

GMT+8, 2024-11-21 15:25 , Processed in 0.980331 second(s), 35 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表