物联网实战--驱动篇之(六)4G通讯(Air780E)

news/2024/4/30 1:28:10/文章来源:https://blog.csdn.net/ypp240124016/article/details/137581016

目录

一、4G模块简介

二、AIR780E驱动程序

三、AIR780使用注意事项

四、结合MQTT传输测试


一、4G模块简介

        4G应该是我们日常生活最常见的一种互联网通讯方式了,每个智能手机都配置了,不过手机的4G跟我们物联网领域要用的4G有点区别。首先是物联网采用模块化4G,手机是CPU内部直接集成了4G基带,技术水平肯定高很多了;其次是网速,手机为了满足日常看视频的需求,速度比较快,理论下载速率是150M,采用CAT4标准;而我们要用的物联网4G模块采用CAT1标准,下载速率10M左右,从成本和需求上来讲比较适合。

        基于CAT1标准的4G模组没出来之前,4G模块一般是作为网关与服务器的通讯链路,因为成本比较高,一个都要150左右;后来基于CAT1的4G模块出来后价格来到了60元左右,随着用量的增长以及技术的更新,成本在不断地降低,前两年AIR720差不多40元左右,如今我们的测试型号AIR780E单纯模组TB价格也就差不多20块左右。就这4G成本,用在设备端作为通讯链路应该没什么问题了,比如充电宝、共享单车、按摩椅等等,而且AIR780E还有一定的低功耗水平,根据手册(目前还没测试过),极致低功耗可以达到2uA,已经差不多SX1278的水平了。

        总体来讲,基于CAT1的4G模组可以满足绝大多数的应用需求,所以需要好好学习,我们这里以合宙的AIR780E为例,写个驱动程序。

二、AIR780E驱动程序

        AIR780的驱动跟之前的esp8266 WiFi驱动很类似,可以参考。物联网实战--入门篇之(六)嵌入式-WIFI驱动(ESP8266)-CSDN博客     

以及AT指令手册Luat社区  

        首先来了解下4G模块的入网流程,模块上电后首先会进行网络注册,就是看下有没有信号了,这时候属于基站跟4G模组底层之间的事情,有没有4G卡暂时不影响;第二步就是PDP上下文移动场景创建,简单理解就是创建一个可以用于互联网通讯的身份,这时候需要你的4G模组里有可用的4G卡;第三步是网络附着,4G模组和基站相互交换认证信息,只有附着了网络,后续才能分配IP地址,进行网络通讯。到这一步为止,只要你的卡能用,每个步骤都是自动完成的,驱动程序只要间隔几秒查询下各个步骤的执行情况就行了。

        接下来就是配置一些网络参数了,比如多路连接、快发模式和APN,这里的APN相当于VIP等级了,跟开的卡有关系,有的卡保密等级比较高,会有专门的APN账户密码,普通卡就默认就行了。

        剩下就是最后一步,激活移动场景,获取IP地址就行了,其它网络连接部分跟esp8266是一样的,对于4G模组一般不作为服务端的,所以不必关系服务端的问题,都是作为客户端连接。接下来先从头文件开始:

       

         基本上都有注释了,AIR780E支持6个客户端连接,基本够用了。状态值就是刚才说明的那些了,入网成功后就可以进行连接操作了。客户端的定义跟esp8266的一样,整体工作的结构体有些区别,首先这里少了服务器相关的内容,其次是多了信号强度、模块序列号IMEI、卡号ICCID和定位信息,其中定位信息其他型号的4G模组不一定有,这个型号有的,我们主要采用了经纬度和海拔,其他暂时忽略。

        下面主要看下注册流程和接收处理,代码如下:


/*		
================================================================================
描述 : 网络注册函数
输入 : 
输出 : 
================================================================================
*/
void drv_air780_reg_process(void)
{static u32 last_sec_time=0, wait_time=2;
//  static char cmd_buff[100]={0};u32 now_sec_time=drv_get_sec_counter();if(now_sec_time-last_sec_time>wait_time){switch(g_sAir780Work.state){case AIR780_STATE_START:{drv_air780_uart_send("ATE0\r\n");delay_os(200);         drv_air780_send_at("RESET");//复位模块        g_sAir780Work.state=AIR780_STAT_INIT;		wait_time=5;			break;}case AIR780_STAT_INIT:{drv_air780_uart_send("ATE0\r\n");delay_os(200);     drv_air780_send_at("CSQ");//查询信号强度delay_os(200);     drv_air780_send_at("CGNSPWR=1");//打开GPS       delay_os(200);     drv_air780_send_at("CGNSAID=31,1,1,1");//使能位置辅助定位           g_sAir780Work.state=AIR780_STAT_CGREG;break;}          case AIR780_STAT_CGREG://查询网络注册状态{drv_air780_send_at("CGREG?");//查询网络连接信息wait_time=3;break;}case AIR780_STAT_CGACT://查询PDP状态{drv_air780_send_at("CGACT?");//查询网络连接信息wait_time=3;break;}      case AIR780_STAT_CGATT0://查询附着状态{drv_air780_send_at("CGATT?");//查询网络连接信息wait_time=3;break;}   case AIR780_STAT_CGATT1://已附着{drv_air780_send_at("CIPMUX=1");//多路连接delay_os(200);drv_air780_send_at("CIPQSEND=0");//快发模式delay_os(200);drv_air780_send_at("CSTT");//设置APN      =\"cmnet\",\"\",\"\"     wait_time=2;g_sAir780Work.state=AIR780_STAT_CIICR;break;}    case AIR780_STAT_CIICR:{drv_air780_send_at("CIICR");激活移动场景,获取IP地址delay_os(1000);drv_air780_send_at("CIFSR");//查询IP地址           g_sAir780Work.state=AIR780_STAT_OK;wait_time=3;break;}   case AIR780_STAT_OK://入网成功{static u8 counts=0;if(counts++%2==0){if(g_sAir780Work.imei_buff[0]==0){drv_air780_send_at("CGSN");}else if(g_sAir780Work.iccid_buff[0]==0){drv_air780_send_at("ICCID");}else{static u8 flag=0;if(flag++%2==0){drv_air780_send_at("CSQ");//查询信号强度}else{drv_air780_send_at("CGNSINF");//查询GPS信息}}}else{drv_air780_connect_process();}wait_time=3;break;}         }last_sec_time=drv_get_sec_counter();}
}

           在起始状态下我们直接复位了模块,这样可以避免与之前的状态冲突,这个模块的启动速度很快,2~3秒就完成了;在初始化阶段,把回显关掉,避免影响接收解析,同时打开定位的相关功能,定位功能要几十秒甚至几分钟才能有效果,而且最好天线要靠窗户边或者户外才行;接下去几步都是查询状态,接收处理等等,这里先跳到入网成功后的状态。分别分时进行了网络连接、请求IMEI、请求ICCID、查询信号强度和查询定位信息等任务,其中IMEI和ICCID只要请求到后就不再重复执行了,剩下就是信号强度和定位信息不断更新。

        接下来是接收处理的代码:


/*		
================================================================================
描述 : 接收处理
输入 : 
输出 : 
================================================================================
*/
void drv_air780_recv_process(void)
{u16 recv_len;char *pData=NULL;if(g_sAir780Work.pUART->iRecv>0){recv_len=0;while(recv_len<g_sAir780Work.pUART->iRecv){recv_len=g_sAir780Work.pUART->iRecv;delay_ms(5);}char *pBuff=(char*)g_sAir780Work.pUART->pBuff;printf("air780 recv=%s\n", g_sAir780Work.pUART->pBuff);if( (pData=strstr(pBuff, "+RECEIVE,"))!=NULL )//接收到数据{pData=pBuff;while((pData=strstr(pData, "+RECEIVE,"))!=NULL){pData+=strlen("+RECEIVE,");u8 sock_id=atoi(pData);
//        printf("sock_id=%d\n", sock_id);if(sock_id<AIR780_MAX_LINK_NUM && (pData=strstr(pData, ","))!=NULL ){pData+=1;u16 data_len=atoi(pData);if( (pData=strstr(pData, ":"))!=NULL ){pData+=3;//: 0D 0Ag_sAir780Work.client_list[sock_id].keep_time=drv_get_sec_counter();printf_hex("air780 data buff= ", (u8*)pData, data_len);if(g_sAir780Work.fun_recv_parse!=NULL){g_sAir780Work.fun_recv_parse(sock_id, (u8*)pData, data_len);//接收处理}pData+=data_len;}}		        }}		else if( (pData=strstr(pBuff, "+CSQ: "))!=NULL )//信号强度{pData+=strlen("+CSQ: ");g_sAir780Work.rssi=atoi(pData);printf("***rssi=%d\n", g_sAir780Work.rssi);}else if( (pData=strstr(pBuff, "+CGNSINF:"))!=NULL )//定位信息{pData+=strlen("+CGNSINF:");
//      printf("GPS=%s", pBuff);for(u8 i=0; i<5; i++){if( (pData=strstr(pData, ","))!=NULL ){pData+=1;switch(i){case 2:{g_sAir780Work.deg_sn=atof(pData);//纬度break;}case 3:{g_sAir780Work.deg_we=atof(pData);//经度break;}    case 4:{g_sAir780Work.hight=atof(pData);//海拔break;}            } }else{break;}}printf("GPS: WE=%.3f deg, SN=%.3f deg, H=%.3f m\n", g_sAir780Work.deg_we, g_sAir780Work.deg_sn, g_sAir780Work.hight);}    else if((pData=strstr((char*)pBuff, "+CGEV: "))!=NULL)//PDP变化{pData+=strlen("+CGEV: ");if(strstr(pData, "DEACT")!=NULL)//移动场景去活{drv_air780_send_at("CIPSHUT");//去激活delay_os(100);g_sAir780Work.state=AIR780_STATE_START;printf("===RDY net_state=AIR780_STATE_START\n");			}else if(strstr(pData, "ACT")!=NULL)//移动场景激活{if(g_sAir780Work.state==AIR780_STAT_CIICR){g_sAir780Work.state=AIR780_STAT_OK;}}						}	    else if((pData=strstr((char*)pBuff, "+CGREG:"))!=NULL)//注册查询{pData+=strlen("+CGREG:");if((pData=strstr((char*)pBuff, ",1"))!=NULL || (pData=strstr((char*)pBuff, ",5"))!=NULL)//注册成功{g_sAir780Work.state=AIR780_STAT_CGACT;printf("=== +CGREG:1\n");}}			else if((pData=strstr((char*)pBuff, "+CGACT: "))!=NULL && (pData=strstr((char*)pBuff, ",1"))!=NULL)//PDP查询{g_sAir780Work.state=AIR780_STAT_CGATT0;printf("=== AIR780_STAT_CGATT0\n");} else if((pData=strstr((char*)pBuff, "+CGATT: 1"))!=NULL)//附着查询{g_sAir780Work.state=AIR780_STAT_CGATT1;printf("=== +CGATT: 1\n");}	    else if((pData=strstr((char*)pBuff, ", CONNECT OK"))!=NULL)//连接检测  || (pData=strstr((char*)pBuff, ", ALREADY CONNECT"))!=NULL{u8 sock_id=0;pData--;printf("### pData=%s\n", pData);if(pData[0]>='0' && pData[0]<='9'){sock_id=pData[0]-'0';printf("=== air780 sock_id=%d connect ok!\n", sock_id);if(sock_id<AIR780_MAX_LINK_NUM){g_sAir780Work.client_list[sock_id].conn_state=true;g_sAir780Work.client_list[sock_id].keep_time=drv_get_sec_counter();}}}		else if((pData=strstr((char*)pBuff, ",CLOSE OK"))!=NULL)//关闭{u8 sock_id=0;pData--;if(pData[0]>='0' && pData[0]<='9'){sock_id=pData[0]-'0';printf("=== sock_id=%d close ok!\n", sock_id);if(sock_id<AIR780_MAX_LINK_NUM){g_sAir780Work.client_list[sock_id].conn_state=false;}}}		else if((pData=strstr((char*)pBuff, "+PDP: DEACT"))!=NULL)//PDP失效{		drv_air780_send_at("CIPSHUT");//去激活delay_os(100);g_sAir780Work.state=AIR780_STATE_START;printf("===RDY net_state=AIR780_STATE_START\n");			}	 else if(pBuff[2]>='0' && pBuff[2]<='9' && g_sAir780Work.imei_buff[0]==0)//IMEI检测{bool is_number=true;pBuff+=2;for(u8 i=0; i<15; i++){if(pBuff[i]<'0' || pBuff[i]>'9'){is_number=false;break;}}if(is_number==true){memset(g_sAir780Work.imei_buff, 0, sizeof(g_sAir780Work.imei_buff));memcpy(g_sAir780Work.imei_buff, pBuff, 15);printf("imei=%s\n", g_sAir780Work.imei_buff);}}else if((pData=strstr((char*)pBuff, "+ICCID: "))!=NULL)//ICCID检测{pData+=strlen("+ICCID: ");memset(g_sAir780Work.iccid_buff, 0, sizeof(g_sAir780Work.iccid_buff));memcpy(g_sAir780Work.iccid_buff, pData, 20);printf("iccid=%s\n", g_sAir780Work.iccid_buff);}    UART_Clear(g_sAir780Work.pUART);}
}

        接收处理的基本思路是根据AT指令返回的关键字进行匹配,得到对应动作的状态值并解析。这里要注意的点是,数据接收"+RECEIVE,"要放在第一个,这样才不会被数据区的内容干扰;定位信息要根据AT指令手册去对应解析,我们只获取了经度、纬度和海拔3个信息,有需要详细的自行添加;还有一个比较重要的场景去激活,简单讲就是信号比较差,4G模组跟基站暂时断开了,这时候是需要重新走一遍流程注册的,所以这个状态要检测,不然数据发送和网络连接都会发生错误的,在产品应用的时候如果忽略这个问题那么很可能导致的后果是大面积失联,客户投诉,市场丢失等问题,这个事件在一些共享充电宝厂商身上发生过的。

        其它也没有什么大问题了,模块的功能很丰富,我们这里只是基本应用,有需要可以根据AT指令手册自己扩展,剩下的就是回调函数注册、初始化等常规操作了。

  

三、AIR780使用注意事项

        最基本的是天线要插,而且要4G的,不要433M的天线插一根,没啥用的,很多胶棒天线长得都一样,自己要记得标识;然后就是4G卡的问题,很多物联网卡是专用的,不能放在手机使用,不能换设备使用,跟第一个4G模块是绑定的,换设备是不能用的,需要联系开卡的客户经理解除绑定,这么做主要是怕卡被拿去非法使用。

        电源问题也是容易被忽略的,模块在网络注册的时候峰值电流比较大,如果电源芯片功率不够的话会导致模块一直重启,在电路设计的时候要严格对照手册进行。

        我这里使用的是串口2进行驱动,自己接线要注意,PA2接模块的RX,PA3接模块的RX,我购买的模块供电是5V的,接线就是5V-TX-RX-GND 4根线就行了,很简单,具体购买链接如下,可作参考。https://item.taobao.com/item.htm?_u=apfmfmg56fd&id=720428359893&spm=a1z09.2.0.0.20d42e8dQqVw5W&skuId=5332410429413

        

四、结合MQTT传输测试

        之前的净化器项目是用WiFi作为网络链路的,我们现在改成4G,操作很简单,这也是为什么我们要模块化封装驱动程序的原因,分级分层,实际做项目的时候根据用户需求随时可以切换方案,维护起来不容易出错,下面看下代码,只要改几行就足够了。      ​​​

        就是把app_mqtt.c文件中的WIFI参数配置改成4G的配置就行了,4G的配置更为简单,不要账户密码什么的。这里因为4G模块必须连接互联网,所以MQTT的服务器用EMQ官方的测试服务器,域名是broker.emqx.io,端口1883,MQTT账户密码随便设置一个就行了,服务器不做检查。用户端我们就不用手机了,直接用客户端工具看下有没有数据发过来就行了。

        很明显这些数据就是从设备端发送出来的。

        4G模组AIR780E的驱动程序暂时就这些了,驱动代码在这里下载:https://download.csdn.net/download/ypp240124016/89110607

本项目的交流QQ群:701889554

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_1046042.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

芯来科技、IAR和MachineWare携手加速符合ASIL标准RISC-V汽车芯片创新

支持软件开发团队在虚拟硬件平台上进行固件和MCAL开发 芯来科技&#xff08;Nuclei&#xff09;、IAR和MachineWare紧密合作&#xff0c;加速RISC-V ASIL合规汽车解决方案的创新。此次合作简化了汽车电子的固件和MCAL开发&#xff0c;提供了虚拟和物理硬件平台之间的无缝集成。…

Harmony鸿蒙南向驱动开发-SDIO

SDIO&#xff08;Secure Digital Input and Output&#xff09;由SD卡发展而来&#xff0c;与SD卡统称为MMC&#xff08;MultiMediaCard&#xff09;&#xff0c;二者使用相同的通信协议。SDIO接口兼容以前的SD卡&#xff0c;并且可以连接支持SDIO接口的其他设备。 运作机制 …

SpringBoot --pagehelper分页

目录 1.建立数据库 2.页面显示 3.基本逻辑 4.配置依赖 5.使用pagehelper 6.页面列表 页面 效果 1.建立数据库 create database if not exists my_book; use my_book; create table if not exists myBook (id int primary key auto_increment,name varchar(50) not …

Node.js常用快捷键

1.常用的终端命令&#xff1a; &#xff08;1&#xff09;del 文件名&#xff1a; 删除文件 &#xff08;2&#xff09;ipconfig: 查看IP命令 &#xff08;3&#xff09;mkdir 目录名 &#xff1a;在当前目录新建指定目录 &#xff08;4&#xff09;rd 目录名&#xff1a;在当前…

【opencv】示例-ela.cpp JPEG图像的错误等级分析(ELA) 通过分析图像压缩后的差异来检测图像是否被篡改过...

ela_modified.jpg 原始ela_modified压缩后再解压得到compressed_img 差异图像Ela 这段代码的功能是实现JPEG图像的错误等级分析&#xff08;ELA&#xff09;&#xff0c;通过分析图像压缩后的差异来检测图像是否被篡改过。程序会首先读取一张图片&#xff0c;然后对其应用质量…

PHP自助建站系统,小白也能自己搭建网站

无需懂代码&#xff0c;用 自助建站 做企业官网就像做PPT一样简单&#xff0c;您可以亲自操刀做想要的效果&#xff01; 自助建站是一款简单、快捷、高效的工具&#xff0c;可以帮助您制作响应式网站。我们的自助建站系统&#xff0c;将传统的编码工作转化为直观的拖拽操作和文…

Qt | 元对象系统

一、QByteArray 类简介 1、QByteArray 类简介  该类是一个用于处理字符串的类似于 C++的 string 类型的类,在 Qt 中,对字符串的处理,经常使用的是 QString 类,该类保证字符串以\0结尾,并使用隐式共享(copy-on-write)来减少内存用量和不必要的数据复制。  QByteArra…

Web3 的社会影响:数字社会的新时代

随着科技的不断进步和创新&#xff0c;人类社会正逐步进入数字化时代的新阶段。Web3 技术作为数字社会的重要组成部分&#xff0c;正在以前所未有的方式重塑着我们的社会生活和交往方式。本文将探讨 Web3 技术对社会的影响&#xff0c;以及它所带来的数字社会的新时代。 1. Web…

Gitlab全量迁移

Gitlab全量迁移 一、背景1.前提条件 一、背景 公司研发使用的Gitlab由于服务器下架需要迁移到新的Gitlab服务器上。Gitlab官方推荐了先备份然后再恢复的方法。个人采用官方的另外一种方法&#xff0c;就写这篇文章给需要的小伙伴参考。 源Gitlab: http://old.mygitlab.com #地…

数据应用OneID:ID-Mapping Spark GraphX实现

前言 说明 以用户实体为例&#xff0c;ID 类型包含 user_id 和 device_id。当然还有其他类型id。不同id可以获取到的阶段、生命周期均不相同。 device_id 生命周期通常指的是一个设备从首次被识别到不再活跃的整个时间段。 user_id是用户登录之后系统分配的唯一标识&#xff…

3D数据发布工具HOOPS Publish如何将3D模型转换成PDF格式?

在现代科技发展的推动下&#xff0c;3D技术在各个行业中扮演着越来越重要的角色。从工程设计到医疗保健&#xff0c;从建筑规划到教育培训&#xff0c;3D模型都成为了理解、沟通和展示复杂数据的主要工具。而将这些3D模型转换成PDF格式&#xff0c;能够使其更易于共享、存档和展…

配置交换机端口安全

1、实验目的 通过本实验可以掌握&#xff1a; 交换机管理地址配置及接口配置。查看交换机的MAC地址表。配置静态端口安全、动态端口安全和粘滞端口安全的方法。 2、实验拓扑 配置交换机端口安全的实验拓扑如图所示。 配置交换机端口安全的实验拓扑 3、实验步骤 &#xff…

nginx配置证书和私钥进行SSL通信验证

文章目录 一、背景1.1 秘钥和证书是两个东西吗&#xff1f;1.2 介绍下nginx配置文件中参数ssl_certificate和ssl_certificate_key1.3介绍下nginx支持的证书类型1.4 目前nginx支持哪种证书格式&#xff1f;1.5 nginx修改配置文件目前方式也会有所不同1.6 介绍下不通格式的证书哪…

《由浅入深学习SAP财务》:第2章 总账模块 - 2.6 定期处理 - 2.6.3 月末操作:外币评估

2.6.3 月末操作&#xff1a;外币评估 企业的外币业务在记账时一般使用期初的汇率或者即时汇率&#xff0c;但在月末&#xff0c;需要按照月末汇率对外币的余额或者未清项进行重估&#xff08;revaluation&#xff09;。 企业在资产负债表日&#xff0c;应当按照下列规…

【springboot开发】Gradle VS Maven

前言&#xff1a; java构建工具的主要作用是依赖管理和构建的生命周期管理。gradle和maven是目前java中最流行的两个构建工具&#xff0c;springboot常用maven&#xff0c;Android studio使用gradle。 目录 1. 简介2. Maven2.1 安装2.2 依赖管理2.3 构建生命周期管理 3. Gradle…

VirusTaxo:病毒物种注释

https://github.com/omics-lab/VirusTaxo 安装 git clone https://github.com/omics-lab/VirusTaxo mamba create -n VirusTaxo python3.10 mamba activate VirusTaxo cd VirusTaxo python3 -m venv environment source ./environment/bin/activate pip install -r require…

SpringCloud系列(2)--SpringCloud和SpringBoot技术选型

前言&#xff1a;SpringCloud是微服务架构的一揽子解决方案&#xff0c;SpringBoot是一种技术&#xff0c;要使用SpringCloud&#xff0c;也需要使用到SpringBoot&#xff0c;所以要使用SpringCloud时&#xff0c;必须也要考虑到SpringBoot的适配问题 1、查看SpringCloud和与之…

最好的 iPhone 解锁器解决方案功能、优点和缺点

现最受好评的 iPhone 解锁器&#xff0c;例如 奇客解锁、iPassGo 等。深入了解它们的优缺点和兼容性&#xff0c;以做出明智的决定。了解如何解锁 iPhone 并解决有关解锁方法、PIN 绕过和潜在风险的常见问题。 1、奇客手机解锁 奇客手机解锁是一款适用于 iOS 的多功能解锁工具…

2024春算法训练4——函数与递归题解

一、前言 感觉这次的题目都很好&#xff0c;但是E题....&#xff08;我太菜了想不到&#xff09;&#xff0c;别人的题解都上百行了&#xff0c;晕&#xff1b; 二、题解 A-[NOIP2010]数字统计_2024春算法训练4——函数与递归 (nowcoder.com) 这种题目有两种做法&#xff1a;…

网站SEO关键词规划时如何筛选出合适的关键词?

在网站SEO优化过程中&#xff0c;关键词布局是一个至关重要的环节。首先&#xff0c;我们需要确定核心关键词&#xff0c;然后通过各种策略和方法对关键词进行扩展。完成关键词扩展后&#xff0c;接下来的任务就是对这些扩展后的关键词进行筛选。那么&#xff0c;如何进行有效的…