单片机使用C语言实现MQTT协议
单片机使用C语言实现MQTT协议
在单片机使用MQTT协议非常普遍,特别是在物联网相关领域,在阿里云,华为云等公有云都提供MQTT协议连接物联网平台。
本篇介绍如何用C语言实现MQTT的连接
MQTT连接主要有五步骤:
1. 连接云平台
2. 登录用户名密码等
3. 订阅主题
4. 发送心跳包
5. 发布主题
1. 连接云平台跟其他网站一样,只要有服务器地址和端口号就行,在这里我使用了以太网口去连接
代码如下:
u16 AnalyTarIp(u8 *TarIp,u16 port,u8 i)
{static u8 dnsSel = 0;u16 stateStamp;uip_ipaddr_t ipaddr;u8 ip[4];g_mconn[i].flag = 0;stateStamp = GetSecCnt();//Á¬½Ó·þÎñÆ÷g_mconn[i].port = port; //端口//IP还是域名if(IsIPaVailable(TarIp)) //IP{if(str2ip(ip, TarIp)) //str To num{uip_ipaddr(&ipaddr, ip[0], ip[1], ip[2], ip[3]);uip_ipaddr_copy(g_mconn[i].ip, ipaddr); //记录IPS282_Log("uip connecting...");g_mconn[i].tcp = uip_connect(&g_mconn[i].ip, htons(g_mconn[i].port)); g_mconn[i].state = TcpClient_Connectting;stateStamp = GetSecCnt();} }else //域名{ u8 HaveDns = 0;if(DhcpOk == 0){if(dnsSel == 0){ if(SysInfo.DnsIp1[1] != 0 && SysInfo.DnsIp1[0] != 0xff){uip_ipaddr(ipaddr, SysInfo.DnsIp1[0],SysInfo.DnsIp1[1],SysInfo.DnsIp1[2],SysInfo.DnsIp1[3]);HaveDns = 1;}if(SysInfo.DnsIp2[1] !=0 || SysInfo.DnsIp1[2] !=0 ) {dnsSel = 1;}}if((HaveDns == 0) && dnsSel){ //DNS2dnsSel = 0;if(SysInfo.DnsIp2[1] != 0 && SysInfo.DnsIp2[0] != 0xff) { uip_ipaddr(ipaddr, SysInfo.DnsIp2[0],SysInfo.DnsIp2[1],SysInfo.DnsIp2[2],SysInfo.DnsIp2[3]);HaveDns = 1;}}}if(HaveDns || DhcpOk){//进行域名解析g_mconn[i].state = TcpClient_DnsRequest;g_mconn[i].flag &= ~e_Dns_found;S282_Log("Analy Target Server ip");if(resolv_getserver() == NULL){resolv_conf(ipaddr); //配置DNS服务器}g_mconn[i].dnsno = resolv_query((char*)&TarIp[0]);//请求域名解析g_mconn[i].dnsno |= 0x80;stateStamp = GetSecCnt();} }return stateStamp;
}
域名解析成功后直接连接g_mconn[i].tcp = uip_connect(&g_mconn[i].ip, htons(g_mconn[i].port));g_mconn[i].state = TcpClient_Connectting;
- 登录用户 需要用户名 密码和设备ID
代码如下:
/*MQTT 连接入参 mode: 0 GPRS网络 1 以太网网络
*/
void MqttConnect(u8 mode)
{u8 i;u16 len;MQTTPacket_connectData mqttConnDat = MQTTPacket_connectData_initializer;GetMqttConnectData(m_mqttBuf,M_CLIENT);if(SysInfo.MqttDeviceID[MQT_TXT_DATLEN] == 0){//设备ID为空使用IMEI码for(i = 0; i < 15; i++){m_mqttBuf[i] = g_IMEI[i];}m_mqttBuf[i] = '\0';}if(SysInfo.MqttUserName[MQT_TXT_DATLEN] == 0){//MQTT用户名为空 用默认值for(i = 0; i < 4; i++){m_mqttBuf[i + MQTT_PWD] = mqttDef[i];}m_mqttBuf[i] = '\0';}if(SysInfo.MqttPwd[MQT_TXT_DATLEN] == 0){//MQTT密码为空 用默认值for(i = 0; i < 4; i++){m_mqttBuf[i + MQTT_PWD * 2] = mqttDef[i];}m_mqttBuf[i] = '\0';}mqttConnDat.clientID.cstring = (char *)m_mqttBuf;//心跳存活时间根据平台需求设置mqttConnDat.keepAliveInterval = SysInfo.MqttRepTim;mqttConnDat.cleansession = 1;mqttConnDat.username.cstring = (char *)&m_mqttBuf[MQTT_PWD];mqttConnDat.password.cstring = (char *)&m_mqttBuf[MQTT_PWD * 2];len = MQTTSerialize_connect(m_sendBuf,MQTT_PWD * 3,&mqttConnDat);if(mode == 0){SendGprsDat(m_sendBuf,len);}else{UipClient2Server(m_sendBuf,len);}
}
- 订阅主题 这里我以tlink物联网平台为准
/*MQTT订阅主题
*/
void MqttSubscribe(u8 mode)
{//·服务质量int qos = 0;u16 len,i;GetMqttConnectData(m_mqttBuf,M_SUBSCRIBE);if(!ISASCCHAR(m_mqttBuf[0])){//tlink平台要求订阅主题为序列号+"/+"GetMqttConnectData(m_mqttBuf,M_CLIENTID);if(!ISASCCHAR(m_mqttBuf[0])){for(i = 0; i < 15; i++){m_mqttBuf[i] = g_IMEI[i];}m_mqttBuf[i] = '\0';}for(i = 0; i < 60; i++){if(!ISASCCHAR(m_mqttBuf[i])){break;}}m_mqttBuf[i++] = '/';m_mqttBuf[i++] = '+';m_mqttBuf[i++] = '\0';}topicString.cstring = (char *)m_mqttBuf;len = MQTTSerialize_subscribe(m_sendBuf,MQTT_PWD * 3,0,PacketId,1,&topicString,&qos);PacketId++;if(mode == 0){SendGprsDat(m_sendBuf,len);}else{UipClient2Server(m_sendBuf,len);}
}
- 发送心跳包,根据自己要求隔段时间发送
/*MQTT Ping防止MQTT断开连接
*/
void MqttPingReq(u8 mode)
{u16 len;len = MQTTSerialize_pingreq(m_mqttBuf,MQTT_PWD * 3);if(mode == 0){SendGprsDat(m_mqttBuf,len);}else{UipClient2Server(m_mqttBuf,len);}
}
- 发布主题 根据自己要求处理
/*MQTT 发布主题入参: InBuf 要发送的数据len 发送数据长度 mode 发送方式
*/
void MqttPublish(u8 *InBuf,u16 len,u8 mode)
{u8 qos = 1;u16 i;GetMqttConnectData(m_mqttBuf,M_PUBLISH);if(!ISASCCHAR(m_mqttBuf[0])){//没有填写发布主题 用IMEI码GetMqttConnectData(m_mqttBuf,M_CLIENTID);if(!ISASCCHAR(m_mqttBuf[0])){for(i = 0; i < 15; i++){m_mqttBuf[i] = g_IMEI[i];}m_mqttBuf[i] = '\0';} }memset(m_sendBuf,0,1000);topicString.cstring = (char *)m_mqttBuf;len = MQTTSerialize_publish(m_sendBuf, 1000, 0, qos, 0, PacketId, topicString, InBuf, len);PacketId++;if(mode == 0){SendGprsDat(m_sendBuf,len);}else{UipClient2Server(m_sendBuf,len);}
}
以上是MQTT实现步骤,只要按步骤实现,基本可以完成,但也需要根据个人要求更改。
单片机使用C语言实现MQTT协议相关推荐
- C语言实现MQTT协议(一)协议讲解
MQTT介绍 MQTT是一个客户端服务端架构的发布/订阅模式的消息传输协议.它的设计思想是轻巧.开放.简单.规范,易于实现.这些特点使得它对很多场景来说都是很好的选择,特别是对于受限的环境如机器与机器 ...
- 12 .IIC协议(51单片机和C语言模拟I2C协议)
文章目录 一:什么是i2c 1.1 协议概述 1.2 特点 简单性和有效性. 多主控(multimastering) 1.3 构成 二 如何实现I2C 2.1 起始信号 2.2 终止信号 2.3 应答 ...
- (过程超详细)适合新手的ATK-ESP8266+STM32F103系列单片机通过MQTT协议直连阿里云的教程
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言 一.所用到的硬件设备 二.调试步骤 1.固件的烧录 2.创造阿里云的产品 3.代码修改 4.最终的硬件连接及效果图 总 ...
- 合泰32-Onenet-WiFi模块-合泰单片机通过MQTT协议数据上云(一)
本篇目标 一.调通合泰单片机串口(成功接收和发送数据) 二.通过WiFi模块连接到Onenet_MQTT服务器 合泰32串口 HT32F5XXX串口 如下表所示,HT32F52352芯片USART0. ...
- 52单片机连接ESP8266烧入固件使用MQTT协议将温湿度上传至OneNET云平台
52单片机连接ESP8266烧入固件使用MQTT协议连接OneNET云平台 参考: ---------------------------------------------------------- ...
- mosquitto c语言编程,MQTT通讯协议(mosquitto)发布订阅例子C语言实现
1.前言 前面对MQTT进行了简单的介绍,并了解了如何在Linux上搭建MQTT 的运行 环境,参考连接:MQTT通讯协议(mosquitto)在Linux上的环境构建与测试,那些仅仅是经过命令去测试 ...
- 合泰32-Onenet-WiFi模块-合泰单片机通过MQTT协议数据上云(二)
本篇目标 一.学习MQTT协议 二.发送温度湿度数据到OneNET 准备材料 感觉麻烦的小伙伴请移步到文末,那里有整个工程的链接. (关于串口和WiFi部分的内容,可以查看前一篇博文,链接:这个是传送 ...
- IoT:MQTT协议详解
IoT -- (七)MQTT协议详解 转自:https://blog.csdn.net/anxianfeng55555/article/details/80908795 MQTT是什么? MQTT(M ...
- 手机控制的esp8266利用mqtt协议接入百度云智能插座
手机控制的esp8266利用mqtt协议接入百度云智能插座 19年的春节,相信大家和我一样都待在家里,利用在家的时间现学现卖,制作了一款手机控制的智能插座,网上资料很多,我在查询资料中发现,esp82 ...
最新文章
- 华西生物医学大数据中心俞鹏课题组博士后招聘启事
- uchome 模板引擎
- 推荐一款非常好用的java反编译工具(转)
- POJ3522Slim Span(最大边与最小边差值最小的生成树)
- 用计算机图形学画字母,r 语言快速出图——单因素方差带字母显著性标记
- 【学习笔记】多重背包相关优化——二进制优化/单调队列优化
- Java IO: 文件
- 【6.0】组合主键映射
- dede首页调用会员积分和头像代码
- $(document).ready()和onload区别
- java 打包运行环境_Jar 打包 EXE文件,可以脱离java环境运行 Jsmooth的使用
- 169、多数元素(python)
- 字体的样式设置和字体分类
- 计算机学会a类论文是sci吗,sci分区和ccf分区的区别
- 图像处理(十三)LBP特征提取
- 微信小程序常见的几种UI组件库
- js日期格式化的两种方法
- Power BI应用案例:淘宝用户行为分析实战
- android su程序分析
- UNtubu16安装hive(一)