『瀚思彼岸』» 智能家居技术论坛
标题: 小白教小白-用大夏龙雀CT511N-A模块自制车载gps [打印本页]
作者: lione95678 时间: 2024-11-19 10:53
标题: 小白教小白-用大夏龙雀CT511N-A模块自制车载gps
本帖最后由 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毛钱。
作者: lione95678 时间: 2024-11-19 10:58
这是单片机的相关文件,解压缩后使用keil修改后重新编译
作者: lione95678 时间: 2024-11-19 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;
- }
- }
- }
复制代码
作者: wbdownn 时间: 2024-11-19 17:10
30M够用不?
作者: kjjuhfv 时间: 2024-11-19 17:11
这个难度感觉还是高了
作者: wenghy 时间: 2024-11-19 17:31
很不错啊,谢谢分享,可以搞下
作者: ryanh7 时间: 2024-11-19 18:37
模块支持二次开发的话可以省掉单片机
作者: lione95678 时间: 2024-11-21 09:43
看你怎么用了,我这老爷子前几天自驾游海南,开了2300公里,按每小时100公里的时速算,用时23小时,用了大概13m的流量
作者: lione95678 时间: 2024-11-21 09:47
这个模块使用说明里明确需要另外的mcu,都是固定死的。我一开始觉得每秒1次发送gps信息太快,问了一下客服,他说通过串口发送gps信息的频率不能修改。
作者: ryanh7 时间: 2024-11-21 10:21
对自己好点,考虑一下air780eg
作者: ryanh7 时间: 2024-11-21 10:21
对自己好点,考虑一下air780eg
作者: rz12345 时间: 2025-1-25 11:38
学习学习
欢迎光临 『瀚思彼岸』» 智能家居技术论坛 (https://bbs.hassbian.com/) |
Powered by Discuz! X3.5 |