最近有个朋友找到我,让我调试一个程序,由于之前项目的硬件采用sim800c的gsm模块,由于现场的信号太差,所以找了个sim7080g模块进行替换。底层设计采用at指令集,中间通信协议层也是我一年多前完成的,上层业务基本不会变化。本以为只会通过修改底层的at指令集就好了,但实际在这个过程中也遇到一些问题。特此记录此次调试过程,避免同样的错误再次出现。
由于我对该项目也相当熟悉了,所以按照模块化的方式进行程序设计。
从整个架构上来看,此时整体架构的变化不大,仅仅是将sim7080g的模块使用起来就好了。protocal
层则是按照之前的处理方式处理。其实也就是将模块recv到的数据组合成一个包,然后交给协议层去处理就可以了。
由于本方案采用的是tcp client传输模式,而且未开启透传模式,而且需要使用到gps功能。
这里主要介绍sim7080g的使用流程以及其中调试的注意事项。
按照模块的使用方式,与TCP相关的AT列表可以分为:
其初始化流程如下所示:
按照上述的初始化流程进行初始步骤即可。一旦一条指令的顺序不对都需要重新进行连接。
对此,我也整理出如下的表格
指令 | 成功返回值 | 备注 |
---|---|---|
AT | OK | AT测试指令 |
AT+CPIN? | READY | 检查sim卡状态指令 |
AT+CNMP=38 | OK | 选择网络制式 |
AT+CSQ | +CSQ: 26,99 | 检查信号质量 |
AT+CPSMS=0 | OK | 关闭PCM |
AT+CEDRXS=0 | OK | 关闭eDRX |
AT+CGREG? | +CGREG: 0,1 | 查询网络附着 |
AT+CGNAPN | OK | 获取网络APN |
AT+CPSI? | OK | 请求UE系统信息 |
AT+CNACT=0,1 | OK | 激活应用网络(只能发送一次) |
AT+CNACT? | 查询网络IP | |
AT+CACID=0 | 设置索引(只能发送一次) | |
AT+CASSLCFG=0,"SSL",0 | OK | 设置SSL参数 |
AT+CAOPEN=0,0,"TCP","iot-as-mqtt.cn-shanghai.aliyuncs.com",1883 | OK | 打开一个TCP链接 |
AT+CASWITCH=0,1 | OK | 设置透传模式 |
AT+CASTATE? | OK | 查询连接状态 |
为了测试方便,我是在本地用内网穿透进行测试调试。内网穿透采用花生壳进行本地内网端口映射。
这样调试起来就非常的方便了。
连接服务器采用
AT+CAOPEN=0,0,\"TCP\",\"iot-as-mqtt.cn-shanghai.aliyuncs.com\",1883
进行TCP连接,连接上后,通过
AT+CASTATE?
查询TCP的连接状态,直到连接上就可以发送数据了。
数据发送
模块数据发送时,首先输入要发送数据的长度,下面的10即为10个字节的数据长度。
AT+CASEND=0,10,10000
此时模块会返回>
符号回来,接着向串口写数据就可以了。
一定需要注意,结束的标志\r\n
。所以不满10个字节当遇到\r\n
则退出输入模式。
数据接收
该模块在使用的使用,需要主动去查询有没有数据接收到。
AT+CARECV=0,100
表示最大接收100个字节,当然,接收时也会提示接收到多少数据。
返回:
+CARECV: 10,GET / HTTP
这个模块TCP连接和GPS同时工作时,会造成TCP断开的现象,这个应该是这个模块设计的BUG,我当时也排查了好久。终于在网上找到与我遇到的同意的问题。
当然,这个问题肯定不是很好解决,目前最好的用法就是两者之中只能使用一个模块进行使用。
该模块与sim800c的指令和访问方式都有一些不同,在使用时也需要充分的理解设计方式。特别是在做物联网应用时,第一是保证连接的可靠性,第二就是需要设计断网重连机制。上述的过程其实还是比较简单,直接查询连接状态即可。其实复杂的还有心跳包等。
嵌入式物联网应用的设备端,其中间的协议层一定要设计完善,如果设计的一塌糊涂,都是if...else
结构,那么这个项目换了模块则无法维护了,这时中间件的作用就体现出来了。在做方案设计的时候,一定考虑清楚模块之间的耦合层次关系,设计出来的架构才清晰明确。