单片机通过GPRS模块利用MQTT协议上报设备数据流程

硬件设备

  1. STM32F407单片机
  2. 安信可A9 GPRS 模块

流程

1.建立连接

需要按照如下流程发送:

 AT+CGATT=1          //附着网络
 OK                 

 AT+CGDCONT=1,"IP","CMNET" //设置PDP参数
 OK

 AT+CGACT=1,1 //激活PDP,正确激活以后就可以上网了
 OK

AT+MQTTCONN="114.129.24.41",1883,"TEST",60,1,"LF","LF" //参数分别是: ip, 端口, clientid, keepalive时间,clearssion, 用户名,密码
 OK

注意:上述AT命令第二行的"OK"是GPRS模块正确接收单片机执行回复的字符串,下同。

2.订阅数据

AT+MQTTSUB="subtopic",1,0  //主题名,订阅或取消订阅,qos
OK

订阅成功后,服务器pub的消息会被GPRS模块收到,也就是单片机的串口会收到如下格式数据

+MQTTPUBLISH:消息id,topic名称,载荷长度,载荷信息
如下:


// 消息id:不断累加,
+MQTTPUBLISH:4,subtopic2,140,{
  "lcdDisString" : "wo shi ceshi de gongju  ",
  "relayState" : "open",
  "tempDangerVal" : 56,
  "ledState" : "open",
  "motorPwm" : 76
}

3.发布数据

单片机可主动上报信息,具体如下:

AT+MQTTPUB="pubtopic","i am payload",0,0,0    //topic名称,载荷数据,qos,重发标志,是否保留?
OK

实际通信中,Pub数据如下,

  1. topic 改为 IN/ECHO/1536558114123/1536558584545/1536728657044
  2. "i am payload"改为具体设备载荷数据,暂定格式如下

与服务器通信的载荷JSON方式封包,原数据格式如下:

{
    "deviceId": "F62802BFC2315E",
    "data": {
        "gpsData": {
            "gps": {
                "GPS_Longitude": 0,
                "GPS_Latitude": 0
            },
            "agps": {
                "AGPS_Longitude0": 0,
                "AGPS_Latitude0": 0
            }
        },
        "PH": 0,
        "Conductivity": 0,
        "ORP": 0,
        "Turbidity": 0,
        "O2": 0,
        "voltage": {
            "BatVoltage": 3.911444,
            "SolarVoltage": 0.59391,
            "SensorVoltage": 11.42429
        }
    }
}

考虑到8位单片机在进行JSON解包时,内存不够(32位单片机没有问题),因此将其简化,具体为:

{
    "deviceId": "F62802BFC2315E",
    "data": "GPS_Longitude=0.000000,GPS_Latitude=0.000000,AGPS_Longitude=0.000000,AGPS_Latitude=0.000000,PH=0.000000,Conductivity=0.000000,ORP=0.000000,Turbidity=0.000000,O2=0.000000,BatVoltage=3.911444,SolarVoltage=0.593910,SensorVoltage=11.424290"
}

也就是单片机向GPRS发送下列字符串即可上报:

AT+MQTTPUB="/World",{"deviceId": "F62802BFC2315E","data": "GPS_Longitude=0.000000,GPS_Latitude=0.000000,AGPS_Longitude=0.000000,AGPS_Latitude=0.000000,PH=0.000000,Conductivity=0.000000,ORP=0.000000,Turbidity=0.000000,O2=0.000000,BatVoltage=3.911444,SolarVoltage=0.593910,SensorVoltage=11.424290"},0,0,0

注意:

  1. 在实际使用过程中,上述字符串通过sprintf函数将具体的变量值打印到字符串中,
  2. 单片机在每个双引号前要加转义字符“\” ,上述为了演示没有加。
  3. java服务器在接收到单片机pub的数据后要去掉引号前面多余的转义字符符号,
String payload = message.getPayload().toString().replace('\\',' ');
System.out.println(payload);

4.断开链接

如果要节省电量,可在休眠时断开与服务器的连接,如下:

AT_MQTTDISCONN
OK

你可能感兴趣的:(物联网,电子电路,单片机)