基于STM32的Air780连接Onenet平台
ONENET 是中国移动提供的物联网开放平台,支持设备接入、数据管理、应用开发、增值服务等能力,为城市、行业、生活等场景提供智能化解决方案。本文为大家介绍 Air780E 如何接入 ONENET,并且会介绍如何进行一次完整的 ONENET 的上下行交互处理。模块为银尔达的M100P模块Air780e_淘宝搜索//TCP//socket编号//TCP服务器(MQTT服务器)端口号//MQTT// 地
若该文为原创文章,转载请注明原文出处。
Onenet平台创建参考STM32+ESP8266连接onenet新平台-CSDN博客
记录使用Air780模块连接Onenet平台,协议MQTT,上传数据和下发数据。
参考:ONENET - at@air780e - 合宙文档中心
一、介绍
ONENET 是中国移动提供的物联网开放平台,支持设备接入、数据管理、应用开发、增值服务等能力,为城市、行业、生活等场景提供智能化解决方案。
本文为大家介绍 Air780E 如何接入 ONENET,并且会介绍如何进行一次完整的 ONENET 的上下行交互处理。
模块为银尔达的M100P模块
二、接线
VIN | 5V |
GND | GND |
RXD | PA2 |
TXD | PA3 |
RST | PA1 |
把模块和STM32F103RCT6的PA1 PA2 PA3接在一起。
三、NET LED 状态描述
四、MQTT控制流程
特别注意:4G模块在上电、重启的时候,主动发出开机日志,这些日志一般需要过滤。然后再去执行AT命令。
参考:AT固件MQTT测试实例
五、AT 命令与 ONENET 建立连接
ATE0 //关闭命令回显
OK
ATI //查询版本号
AirM2M_780E_V1170_LTE_AT
OK
AT+CGREG? //查询当前GPRS注册状态
+CGREG: 0,1 //<stat>=1,标识已经注册GPRS网络,而且是本地网
OK
AT+CGATT? //查看当前GPRS附着状态
+CGATT: 1 //<state>=1,标明当前GPRS已经附着
OK
AT+MCONFIG=868327075408114,Sr8K21BjHb,version=2018-10-31&res=products%2FSr8K21BjHb%2Fdevices%2F868327075408114&et=98102959372322222&method=md5&sign=tbU%2FAsjnRkQw88SW6qKNmw%3D%3D
//填写clientid、用户名、密码;可以带引号可以不带
OK
AT+MIPSTART="mqtts.heclouds.com","1883"
//填写mqtt服务器的域名和端口号
OK
CONNECT OK
AT+MCONNECT=1,120 //建立mqtt会话;注意需要返回CONNECT OK后才能发此条指令,并且要立即发,否则就会被服务器踢掉
OK
CONNACK OK //连接成功,成功后才能发布消息或者订阅消息
AT+MSUB="post/reply" //订阅主题
OK
AT+MSUB="$sys/Sr8K21BjHb/868327075408114/thing/#",0 //订阅主题
OK
SUBACK
AT+MPUB="$sys/Sr8K21BjHb/868327075408114/thing/property/post",0,0,"{\\22id\\22:\\22123\\22,\\22version\\22:\\221.0\\22,\\22params\\22:{\\22voltage\\22:{\\22value\\22:2792},\\22temp\\22:{\\22value\\22:28.1},\\22Light\\22:{\\22value\\22:true}}}" //发布主题
OK
+MSUB: "$sys/Sr8K21BjHb/868327075408114/thing/property/post/reply",39 byte,{"id":"123","code":200,"msg":"success"} //收到服务器下发的消息,+MSUB的URC上报
//最大4100个字节。字符串类型,须用双引号括住。
注:消息中内嵌的
双引号请用\22表达;
控制字符回车\r(0x0D)请用\0D表达;
控制字符换行\n(0x0A)请用\0A表达;
控制字符反斜杠(0x5C)请用\5C表达
如果是MCU发消息,可能需要用\\22,\\0D,\\0A,\\5C来表达,即\需要转义成\\
"{\\22temp\\22:\\2225.00\\22}"
AT+MDISCONNECT //模块需要先关闭mqtt连接
OK
AT+MIPCLOSE //关闭tcp连接
OK
这里需要注意的是Onenet的鉴权
六、STM32代码片段
1、AIR780E初始化
switch(ConfigModuleNoBlockCaseValue)
{
case 0://关闭GPRS模块 ,延时500ms
ConfigModuleNoBlockFlage = 0;
network_module_rst_set(1); ConfigModuleRunNext(CompareValue-1500); break;
case 1://启动GPRS模块 ,延时3000ms
network_module_rst_set(0); ConfigModuleRunNext(CompareValue-3000); break;
case 2://发送AT
SendConfigFunction("AT\r\n",NULL,"OK",NULL,FunctionParseCompare,CompareValue);break;
case 3://关闭回显
SendConfigFunction("AT&F\r\n",NULL,"OK",NULL,FunctionParseCompare,CompareValue);break;
case 4://获取IMEI
SendConfigFunction("AT+CSQ\r\n",NULL,"OK",NULL,FunctionParseCompare,CompareValue);break;
case 5://读取SIM状态正常
SendConfigFunction("AT+CPIN?\r\n",NULL,"OK",NULL,FunctionParseCompare,CompareValue);break;
case 6://设置短信服务
SendConfigFunction("AT+COPS?\r\n",NULL,"OK",NULL,FunctionParseCompare,CompareValue);break;
case 7://设置消息格式为TEXT模式
SendConfigFunction("AT+CREG?\r\n",NULL,"OK",NULL,FunctionParseCompare,CompareValue);break;
case 8://设置TEXT模式参数中文模式
SendConfigFunction("AT+CIPSHUT\r\n",NULL,"OK",NULL,FunctionParseCompare,CompareValue);break;
case 9://是否附着了GPRS
SendConfigFunction("AT+CGATT?\r\n",NULL,"+CGATT: 1",NULL,FunctionParseCompare,CompareValue);break;
case 10://设置APN
SendConfigFunction("AT+CSTT\r\n",NULL,"OK",NULL,FunctionParseCompare,CompareValue);break;
case 11://激活移动场景
SendConfigFunction("AT+CIICR\r\n",NULL,"OK",NULL,FunctionParseCompare,CompareValue);break;
case 12://查询分配的IP地址
SendConfigFunction("AT+CIFSR\r\n",NULL,".",NULL,FunctionParseCompare,CompareValue);
break;
case 13:// 创建设置MQTT参数
len = sprintf(ConfigModuleNoBlockBuff,"AT+MCONFIG=\"%s\",\"%s\",\"%s\"\r\n", mqtt_user_name, mqtt_client_id, mqtt_password);
ConfigModuleNoBlockBuff[len]=0;
SendConfigFunction(ConfigModuleNoBlockBuff,NULL,"OK",NULL,FunctionParseCompare,CompareValue);
break;
case 14://连接TCP 服务器
len = sprintf(ConfigModuleNoBlockBuff,"AT+MIPSTART=\"%s\",%d\r\n", tcp_mqtt_addr, tcp_mqtt_port);
ConfigModuleNoBlockBuff[len]=0;
SendConfigFunction(ConfigModuleNoBlockBuff,NULL,"CONNECT OK",NULL,FunctionParseCompare,CompareValue);
break;
case 15:
SendConfigFunction("AT+MCONNECT=1,120\r\n",NULL,"CONNACK OK",NULL,FunctionParseCompare,CompareValue);
break;
case 16:
len = sprintf(ConfigModuleNoBlockBuff,"AT+MSUB=\"%s\",0\r\n", mqtt_subscribe_model_topic);
ConfigModuleNoBlockBuff[len]=0;
SendConfigFunction(ConfigModuleNoBlockBuff,NULL,"SUBACK",NULL,FunctionParseCompare,CompareValue);
ConfigModuleRunNext(CompareValue-1500);
break;
default:
SendConfigFunction(NULL,NULL,NULL,NULL,NULL,CompareValue); //这句必须加,清除所有的执行函数
DataReturnFlage=0;
ConfigModuleNoBlockFlage=1; break;
}
2、参数定义
//TCP
int tcp_mqtt_index=0;//socket编号
int tcp_mqtt_port = 1883;//TCP服务器(MQTT服务器)端口号
//MQTT
char tcp_mqtt_addr[100]="mqtts.heclouds.com"; // 地址
char mqtt_client_id[100]="VvZ1Q5qW46";
char mqtt_user_name[100] = "device_01";//用户名
char mqtt_password[200] = "version=2018-10-31&res=products%2FVvZ1Q5qW46%2Fdevices%2Fdevice_01&et=1786844404&method=md5&sign=H3cf2FpNBWT9nUheK9dvIA%3D%3D";//密码
char mqtt_keepalive = 60;//心跳包时间
char mqtt_publish_model_topic[100]="$sys/VvZ1Q5qW46/device_01/thing/property/post";//存储发布的主题
char mqtt_subscribe_model_topic[100]="$sys/VvZ1Q5qW46/device_01/thing/property/set";//存储订阅的主题
这是用的主题和上面的不一样,可以根据需求修改
3、发布主题
void publishDataToServer(void)
{
char send_buf[200] = {0};
char tmp[200] = {0};
memset(send_buf, 0, 200); //清空
memset(tmp, 0, 200); //清空
strcat(send_buf, "AT+MPUB=\"");
strcat(send_buf, mqtt_publish_model_topic);
strcat(send_buf, "\", 0, 0,\"");
sprintf(tmp, "{\\22id\\22:\\22123\\22,\\22params\\22:{\\22temp\\22:{\\22value\\22:%d},\\22hum\\22:{\\22value\\22:%d}}}\"\r\n",
11, 22);
strcat(send_buf, tmp);
usart2_send(send_buf, sizeof(send_buf));
delay_ms(100);
}
写的比较简单,没有判断返回的值,直接发送了数据,但要注意转义
注:消息中内嵌的
双引号请用\22表达;
控制字符回车\r(0x0D)请用\0D表达;
控制字符换行\n(0x0A)请用\0A表达;
控制字符反斜杠(0x5C)请用\5C表达
如果是MCU发消息,可能需要用\\22,\\0D,\\0A,\\5C来表达,即\需要转义成\\
"{\\22temp\\22:\\2225.00\\22}"
4、订阅数据处理
使用API发送数据,接收到的数据格式为
+MSUB: "$sys/VvZ1Q5qW46/device_01/thing/property/set",51 byte, {"id": 1", "version":"1.0", "params":{"set_temp":12}}
/*获取TCP数据*/
{
start = strstr((char*)&usart2_read_buff_copy[20], "set_temp");
if (start != NULL) {
// 移动到冒号位置(跳过键名)
start = strchr(start, ':');
if (start != NULL) {
start++; // 跳过冒号
// 跳过可能存在的空格/制表符
while (*start == ' ' || *start == '\t') start++;
// 提取整数值(处理多位数字)
value = (int)strtol(start, &end, 10);
// 验证转换有效性
if (end != start) {
// 成功解析到整数 value
}
}
} else {
}
经测试,数据下行和上行正常。
如有侵权,或需要完整代码,请及时联系博主。
更多推荐
所有评论(0)