当前位置:   article > 正文

单片机使用C语言实现MQTT协议_单片机mqtt协议c语言

单片机mqtt协议c语言

单片机使用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);		//记录IP
			S282_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)
			{	//DNS2
				dnsSel = 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;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
					域名解析成功后直接连接
		g_mconn[i].tcp = uip_connect(&g_mconn[i].ip, htons(g_mconn[i].port));
		g_mconn[i].state = TcpClient_Connectting;
  • 1
  • 2
  • 3
  1. 登录用户 需要用户名 密码和设备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);
	}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  1. 订阅主题 这里我以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);
	}
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  1. 发送心跳包,根据自己要求隔段时间发送
/*
	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);
	}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  1. 发布主题 根据自己要求处理
/*
	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);
	}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36

以上是MQTT实现步骤,只要按步骤实现,基本可以完成,但也需要根据个人要求更改。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/繁依Fanyi0/article/detail/233337?site
推荐阅读
相关标签
  

闽ICP备14008679号