本篇文章是自己用m26 mqtt协议链接阿里云的一些经验,以及遇到的一些问题及解决,如果有误,欢迎各位指正。
目录
M26简介:
第一步:阿里云创建设备
第二步:创建topic
第三步:获取设备三元组
第四步:确定自己手里的模组固件是否支持MQTT协议
第五步:用哈希算法推算出MQTT协议所需的数据
第六步:At指令发送注册阿里云
第七步:发布消息
第八步:接受消息
通信保证手段:状态检查
附录1:at指令发送表
附录2:at指令实际执行情况
M26 是一款超小的四频 LCC 封装 GSM/GPRS 模块,尺寸仅为15.8mm×17.7mm×2.3mm,最大限度地满足终端产品对小尺寸模块产品需求,有效帮助客户减小产品尺寸并优化产品成本。
凭借超小的尺寸、超低功耗和超宽工作温度范围,M26 是 M2M 应用的理想解决方案,适用于车载、可穿戴设备、工业级 PDA 、个人跟踪、无线 POS 、智能计量及其它 M2M 的应用,为其提供完善的短信、数据传输及语音等服务。
阿里云帮助文档
产品指某一类设备,创建完产品后,需要为设备创建身份。您可以创建单个设备,也可以批量创建设备。本文为您讲述单个设备的创建。
操作步骤
参数 |
描述 |
产品 |
选择产品。新创建的设备将继承该产品定义好的功能和特性。 说明 若该产品关联了其他平台,请确保您的账户下有足够的激活码用于创建设备。 |
DeviceName |
设置设备名称。 设备名称在产品内具有唯一性。 设备名称长度为4-32个字符,可包含英文字母、数字和特殊字符,包括连接号(-)、下划线(_)、at符号(@)、点号(.)和英文冒号(:)。 说明 DeviceName可以为空。为空时,由物联网平台生成一个全局唯一标识符作为设备的DeviceName。 |
备注名称 |
设置备注名称。备注名称长度为4-64个字符,可包含中文汉字、英文字母、数字和下划线(_)。一个中文汉字算2字符。 |
操作步骤
参数 |
描述 |
设备操作权限 |
设备对该Topic的操作权限,可设置为: 发布:设备可发布消息到该Topic。 订阅:设备可订阅该Topic,从该Topic获取消息,例如您在云端调用Pub接口发送到该Topic的消息。 发布和订阅:设备对该Topic同时具有发布和订阅权限。 |
Topic类 |
将Topic类填充完整。物联网平台根据您的产品和设备自动生成Topic的前段内容,您只需填入您的自定义部分。 说明 只有设备操作权限为订阅时,才可以使用通配符+和#自定义Topic类。 +代表本级所有类目。 #代表本级及下级所有类目。它只能出现在Topic类的最后一个类目。 使用带通配符的自定义Topic,请参见本文下一章。 |
描述 |
描述该Topic类。可以为空。 |
在IoT平台获取三元组ProductKey、DeviceName、DeviceSecret,这好比终端设备的身份证,有了它才能对接到阿里云平台上。
M26对MQTT协议栈的支持时从固件R01A07开始支持,发送AT指令查询一下,不支持的话要升级固件。
1、clientID:
自己随便定义字符串 我这里示例为“12345”
2、mqttClientId:
格式为”clientID“+”|securemode=3,signmethod=hmacsha1,timestamp=10|“
3、mqttUsername:
格式为”DeviceName+&+ProductKey“
4、mqttPassword:哈希算法,得出的,后面给出了C语言库
代码示例:
uint8_t M26_QMTCONN(void){
char clientid[] = "12345|securemode=3,signmethod=hmacsha1,timestamp=789|";
char username[60] = {0};
char sign[50];
char content[50]="clientId12345deviceName";
strcat(username,DeviceName); //设备名 //20
strcat(username,"&"); // 1
strcat(username,ProductKey);//产品名 32
strcat(content,DeviceName);// 加入设备名//21
strcat(content,"productKey");//10
strcat(content,ProductKey);//加入产品钥匙//10
strcat(content,"timestamp789");//12
lk=strlen(DeviceSecret);
ld=strlen(content);
aliyun_iot_common_hmac_sha1(content,ld,sign,DeviceSecret,lk);
sprintf(cmd,"AT+QMTCONN=0,\"%s\",\"%s\",\"%s\"\r\n",clientid,username,sign);
}
以上都是MQTT协议所需的连接参数。
关于最后的aliyun_iot_common_hmac_sha1函数,是计算mqttPassword的哈希算法。
网上可以找到封装好的C语言库。
1、发送 AT
发送多次之后如果还是没有返回ok的话,则需要将模块power脚拉低2s钟以上,对模块进行复位
2、 AT+IPR?
查询当前的波特率,如果和之后的目标波特率不一致的话,下一步需要设置波特率
3、AT+IPR=115200
设置波特率为115200
4、ATE0
关闭回显,如果不关闭回显的话,每次发送出去的指令会再次发回来,对数据处理造成干扰
5、AT&W
保存上一步的设置,不保存设置的话,上一步的关闭回显操作将不会成功
6、AT+CSQ
查询信号值,需要注意的是信号值需要多次查询之后可能才会成功,信号值在不等于99,并且大于12的情况下,才能进行下一步,否则之后的指令很可能执行失败
7、AT+QSIMSTAT?
查询sim卡注册,在返回+QSIMSTAT: 0,1 后,sim卡注册正常,可以进行下一步
8、AT+QMTCFG=\"KEEPALIVE\",0,60
设置mqtt心跳时间,以秒为单位,移远给的建议是120s,此处设置的是60s,正常运行
9、AT+QMTCFG=\"VERSION\",0
查询mqtt版本编号
10、AT+QMTCFG=\"ALIAUTH\",0
配置mqtt去链接阿里云服务器
11、AT+QMTOPEN=?
为客户机打开一个网络
12、AT+QMTOPEN=0,\"iot-as-mqtt.cn-shanghai.aliyuncs.com\",1883
打开阿里云华东区的服务器
13、AT+QMTCONN=0,\"%s\",\"%s\",\"%s\"
链接阿里云服务器,此处的消息较长,如果主控芯片有dma的话,推荐使用dma来进行数据的发送和接受,会减少一些误码,如果产生误码的话,m26模块很容易会报 3518错误。
14、AT+QMTSUB=0,1,\"/%s/%s/user/rrpc\",2
订阅topic,订阅指定权限的topic,不订阅的话,之后是收不到数据的
15、链接成功,这时在阿里云上看到设备已经上线了
这时可以用 AT+QMTSUB=0,1,\"/%s/%s/user/rrpc\",2 指令来进行数据的发送了
代码示例如下
uint16_t MQTTPublist(char *Buf, uint16_t Len, uint8_t qos)
{
memset(content_update,'\0',sizeof(content_update));//清空数组
strcat(content_update,"/ext/rrpc/");
strcat(content_update,messageId);
strcat(content_update,"/"); //产品名
strcat(content_update,ProductKey); //产品名
strcat(content_update,"/");
strcat(content_update,DeviceName); //设备名
strcat(content_update,"/user/rrpc");
printf("发送:");
if(qos == 0) msgid = 0;
else msgid++;
sprintf(cmd,"AT+QMTPUB=0,%d,%d,0,\"%s\",%d\r\n",msgid,qos,content_update,Len);
}
通过监听串口的接收端可以获得阿里云发送的数据
如果收到 "+QMTRECV: " 开头的数据,则是收到了阿里发送的消息,可以在收到之后对数据进行解析
如果收到"+QMTSTAT: " 开头的数据,则m26和阿里之间的链接出现了一些问题,需要进行重连,如果出现问题的次数比较多的话,很可能是模块电源供电的问题,之前有测试过,用手机电池给m26模块供电,可以48小时,都不会出问题,但是用自己设计的开关电源供电的话,一天会出现4次左右掉线。
if(strstr((const char *)&g_tGPRS.RxBuf,"+QMTSTAT: "))
{
NetWork_Error =1;
printf("%s\r\n",g_tGPRS.RxBuf);
//Uart3_SendArr(g_tGPRS.RxBuf,g_tGPRS.RxCount);
}
if(strstr((const char *)&g_tGPRS.RxBuf,"+QMTRECV: "))
{ //是PUBLISH包
printf("收到:");
}
在做产品的过程中,发现有时阿里云设备掉线了,但是设备没有执行重连,经过分析,觉得可能是错误字符"+QMTSTAT: "没有收到,或者中间串口有误码,造成问题,所以刚好使用阿里云的状态检测机制来做。具体如下:
链接如下:https://help.aliyun.com/document_detail/101125.html?spm=a2c4g.11186623.6.981.948c55e568rHyY
定义该topic(/yourProductKey/yourDeviceName/user/checkstatus)之后,阿里云收到该topic的消息之后,会自动的返回数据,不用进行干预
指令 |
返回值 |
功能 |
AT |
OK |
查询模块状态 |
AT+IPR? |
115200 |
查询波特率 |
AT+IPR=115200 |
OK |
设置波特率 |
ATE0 |
OK |
关闭回显 |
AT&W |
OK |
保存设置 |
AT+CSQ |
+CSQ |
查询信号值 |
AT+QSIMSTAT? |
+QSIMSTAT: 0,1 |
查询sim卡注册 |
AT+CREG? |
+CREG: 0,1 |
查询网络注册 |
AT+COPS? |
OK |
查询网络状态 |
AT+QMTCFG=\"KEEPALIVE\",0,60 |
OK |
配置心跳时间 |
AT+QMTCFG=\"VERSION\",0 |
OK |
查询版本号 |
AT+QMTCFG=\"ALIAUTH\",0 |
OK |
配置阿里云信息 |
AT+QMTOPEN=? |
OK |
为客户机打开一个网络 |
AT+QMTOPEN=0,\"iot-as-mqtt.cn-shanghai.aliyuncs.com\",1883 |
+QMTOPEN: 0,0 |
为客户机打开一个网络 |
AT+QMTCONN=0,\"%s\",\"%s\",\"%s\" |
+QMTCONN: |
连接到mqtt服务器 |
AT+QMTSUB=0,1,\"/%s/%s/user/rrpc\",2 |
+QMTSUB: |
订阅消息 |
AT+QCELLLOC=1 |
QCELLLOC |
获取地理位置 |
AT+QCCID |
OK |
获取sim卡号 |
AT+QMTPUB=0,%d,%d,0,\"%s\",%d |
OK |
发布消息 |