W5100S——MQTT连接百度天工云平台 - Go语言中文社区

W5100S——MQTT连接百度天工云平台


上篇文章主要讲解了W5100S特色功能——SOCKET - less PING功能。

文章链接 - W5100S——SOCKET - less PING功能解析(可以了解下W5100S硬件PING功能如何使用)

本篇文章则是讲解,如何让W5100S 通过MQTT连接百度天工云平台。

STM32+W5100S_百度云天工MQTT 例程下载------------>www.w5100s.com

1. 准备

  • 软件环境:Windows

  • 硬件环境:STM32F103+W5100S

  • 开发工具:Keil uVision5

  • 调试工具:串口调试助手

  • 连接平台:百度云天工(https://cloud.baidu.com/

2. MQTT简介

MQTT官网地址:(http://mqtt.org/

2.1 MQTT协议特点

MQTT是一个基于客户端-服务器的消息发布/订阅传输协议。MQTT协议是轻量、简单、开放和易于实现的,这些特点使它适用范围非常广泛。在很多情况下,包括受限的环境中,如:机器与机器(M2M)通信和物联网(IoT)。其在,通过卫星链路通信传感器、偶尔拨号的医疗设备、智能家居、及一些小型化设备中已广泛使用。

MQTT协议当前版本为,2014年发布的MQTT v3.1.1。除标准版外,还有一个简化版MQTT-SN,该协议主要针对嵌入式设备。

MQTT协议运行在TCP/IP或其他网络协议,提供有序、可靠、双向连接。其特点包括:

  • 使用的发布/订阅消息模式,它提供了一对多消息分发,以实现与应用程序的解耦。
  • 对负载内容屏蔽的消息传输机制。
  • 对传输消息有三种服务质量(QoS):
  • 最多一次,这一级别会发生消息丢失或重复,消息发布依赖于底层TCP/IP网络。即:<=1
  • 至多一次,这一级别会确保消息到达,但消息可能会重复。即:>=1
  • 只有一次,确保消息只有一次到达。即:=1。在一些要求比较严格的计费系统中,可以使用此级别

数据传输和协议交换的最小化(协议头部只有2字节),以减少网络流量

通知机制,异常中断时通知传输双方

2.2 MQTT协议原理及实现方式

实现MQTT协议需要:客户端和服务器端

MQTT协议中有三种身份:发布者(Publish)、代理(Broker)(服务器)、订阅者(Subscribe)。其中,消息的发布者和订阅者都是客户端,消息代理是服务器,消息发布者可以同时是订阅者。

MQTT传输的消息分为:主题(Topic)和消息的内容(payload)两部分

Topic,可以理解为消息的类型,订阅者订阅(Subscribe)后,就会收到该主题的消息内容(payload)

payload,可以理解为消息的内容,是指订阅者具体要使用的内容

2.3 百度云天工MQTT连接步骤

2.3.1.进入管理控制台请提前登录);

2.3.2. 选择“物接入IoT Hub”板块

2.3.3. 创建项目

(例程搭配数据型设备使用,详细数据型与设备型差异,请前往百度云天工查询)

2.3.4. 项目提交后,进入项目创建子用户

名称:MQTT连接报文中的用户名

身份:确定访问形式,可以使用密钥连接。

策略:绑定对应权限与主题。

密钥:请妥善保管,此为连接的密码。(遗忘可在身份列表重置)


项目创建成功后,记录下:名称、身份、密钥。即可通过例程修改对应字符串连接自己所创建的设备。


3. 例程实验现象

首选我们查看烧录程序后,应有的实验现象。

注:测试W5100S订阅主题后的接收消息和向主题发布消息,是在百度云建立了第二个设备B。B设备发布消息和接收W5100S发的主题消息。以此检验是否W5100S能收到主题消息或发送主题消息。

3.1.串口打印信息显示“连接成功”或者“连接失败的具体原因”。

3.2.订阅主题

3.3.接收主题消息

3.4.发布主题消息

4. 例程代码

由于代码内涉及MQTT的拆包组包部分,详细讲解太过冗杂。

故此次解析,仅从函数功能及代码框架解析,不对函数实现做过多拆解。

4.1.主函数整体框架流程

#include <stdio.h>
#include <string.h>  
#include "stm32f10x.h"

#include "bsp_usart1.h"
#include "bsp_fsmc.h"
#include "bsp_spi.h"

#include "w5100s.h"
#include "W5100s_conf.h"
#include "wizchip_conf.h"
#include "w5100s_conf.h"

#include "utility.h"
#include "tcp_demo.h"
#include "MqttKit.h"

int main(void)
{ 	 
  systick_init(72);                     // 初始化滴答定时器
  USART1_Config();                      // 初始化USART1:115200@8-N-1 
  reset_break_gpio_init();              // 复位与中断管脚初始化
#if (_WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_SPI_)
  spi_gpio_init();                      // SPI管脚初始化
  spiinitailize();                      // SPI配置初始化
  reg_wizchip_spi_cbfunc(spi_read_byte,spi_send_byte);          // SPI读写数据函数映射
  reg_wizchip_cs_cbfunc(cs_low,cs_high);                        // SPI片选控制函数映射
#elif (_WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_BUS_INDIR_)
  FSMC_gpio_init();                     // FSMC管脚初始化c
  FSMCInitialize();                     // FSMC配置初始化
#endif
  printf("rn 炜世科技--WIZnet W5100S官方代理商。全程技术支持,价格优势大!rnrn");
  reset_w5100s();                       // W5100S硬件复位 
  PHY_check();                          // 网线检测程序
  set_w5100s_mac();                     // 设置W5100SMAC地址
  set_w5100s_netinfo();                 // 设置W5100S网络参数
  wizchip_init(txsize,rxsize);          // 初始化4个Socket的发送接收缓存大小
  printf("rn W5100S网络参数配置完成,请使用电脑 'PING' W5100SIP地址,检查网络是否畅通。");
	
  while(1)                              /*循环执行的函数*/ 
  {
    do_tcp_client();                    // TCP 客户端数据回环测试 
		
    delay_ms(100);

    if(User1 == 0)                      //订阅
    {
       while(User1 == 0);
       MQTT_STATE = MQTT_PKT_SUBSCRIBE;
    }
//  if(KEY_5 == 0)                      //取消订阅
//  {
//     MQTT_STATE = MQTT_PKT_UNSUBSCRIBE;
//  }
    else if(User0 == 0)                 //发布
    {
       while(User0 == 0);
       MQTT_STATE =MQTT_PKT_PUBLISH;
    }	
  }
} 

主函数部分,代码整体框架还是十分明了的。

main函数之前是单片机和W5100S使用前的初始化部分。

main内则是基本的TCP客户端程序和按键检测,不同按键改变MQTT_STATE的不同状态。

接下来详细进一步探究do_tcp_client()函数。

4.2.do_tcp_client()函数

uint8 buff[2048];                                   /*定义一个2KB的缓存*/
uint8  BD_TG_server_ip[4] = {163,177,150,12};       //BD_TG服务器IP地址
uint16 BD_TG_server_port  = 1883;                   //BD_TG服务器端口号
  

int MQTT_STATE = MQTT_PKT_CONNECT;                  //连接
const char *topics[] = {"test"};                    //主题
uint8 BD_TG_ping_pak[2] = {0xC0,0x00};              //心跳报文

unsigned char *data_ptr = NULL;                     //指针指空
/**
*@brief    TCP Client回环演示函数。
*@param    无
*@return   无
*/
void do_tcp_client(void)
{  
  uint16 len=0;  

  switch(getSn_SR(SOCK_TCPC))                                   /*获取socket的状态*/
  {
    case SOCK_CLOSED:                                           /*socket处于关闭状态*/
      socket(SOCK_TCPC,Sn_MR_TCP,local_port++,Sn_MR_ND);
    break;

    case SOCK_INIT:                                             /*socket处于初始化状态*/
      connect(SOCK_TCPC,BD_TG_server_ip,BD_TG_server_port);     /*socket连接服务器*/ 
    break;

    case SOCK_ESTABLISHED:                                      /*socket处于连接建立状态*/
      if(getSn_IR(SOCK_TCPC) & Sn_IR_CON)
      {
        setSn_IR(SOCK_TCPC, Sn_IR_CON);                         /*清除接收中断标志位*/
      }

      len=getSn_RX_RSR(SOCK_TCPC);                              /*定义len为已接收数据长度*/
      if(len>0)
      {
        recv(SOCK_TCPC,buff,len);                               /*接收来自Server的数据*/      
        data_ptr = buff;
        if(data_ptr != NULL)
          BD_TG_RevPro(data_ptr);
        if(publish_buf[0] == 0x31)
        {  
          LED_ALL_ON;
        }      
        else if(publish_buf[0] == 0x32)  
        {  
          LED_ALL_OFF;
        }  
      }  
    
      switch(MQTT_STATE)
      {
        /*MQTT协议连接BD_TG代理平台*/
        case MQTT_PKT_CONNECT:
          BD_TG_DevLink();
          MQTT_STATE = MQTT_PKT_PINGREQ;
        break;
        /*订阅主题*/
        case MQTT_PKT_SUBSCRIBE:
          BD_TG_Subscribe(topics,1);
          MQTT_STATE = MQTT_PKT_PINGREQ;
        break;  
        /*Qos2级别发布消息*/
        case MQTT_PKT_PUBLISH:      
          
          BD_TG_Publish(*topics, "MQTT Publish Test"); //发布消息
          delay_ms(300);                               //等待平台响应    
          /*接收平台发送的PubRec并回复PubRel响应*/     
          len=getSn_RX_RSR(SOCK_TCPC); 
          recv(SOCK_TCPC,buff,len); 
          data_ptr = buff;
          if(data_ptr != NULL)
            BD_TG_RevPro(data_ptr);
          delay_ms(100);                               //PubRel响应等待平台响应
          len=getSn_RX_RSR(SOCK_TCPC); 
          recv(SOCK_TCPC,buff,len); 
          data_ptr = buff;
          if(data_ptr != NULL)
            BD_TG_RevPro(data_ptr);
          MQTT_STATE = MQTT_PKT_PINGREQ;
          /*120秒发送一次Ping响应保持长连接*/
        break;
        case MQTT_PKT_UNSUBSCRIBE:
          MQTT_UnSubscribe(topics,1);
          MQTT_STATE = MQTT_PKT_PINGREQ;
        break;
        case MQTT_PKT_PINGREQ:
          if(BD_TG_ping_time > 120)
          {
            send(SOCK_TCPC,BD_TG_ping_pak,2);
            BD_TG_ping_time = 0;
          }
        break;
      }  
    break;

    case SOCK_CLOSE_WAIT:                              /*socket处于等待关闭状态*/
      close(SOCK_TCPC);
    break;
  }
}

主要是个状态机的编写格式,基本的TCP建立连接(SOCK_ESTABLISHED状态)后,通过MQTT_STATE变量的状态,判断是发送MQTT连接报文、MQTT订阅报文、MQTT消息发布、MQTT取消订阅、MQTT心跳报文等不同的case。

最开始会先默认进入MQTT_PKT_CONNECT,发送连接报文,我们连接百度云,主要有以下参数需要更改

#define PROID		"7321ph4/w5500"         // 设备全称

#define AUTH_INFO	"23h0wtzkmmti982q"      // API密钥
	
#define DEVID		"qwe"                   // 身份

以上信息,在百度云建立设备时,会让客户设置。我们只需要把设置的复制,替换上述字符串即可。

而我们MQTT的功能实现,则替换以下函数相应的传参字符即可。

const char *topics[] = {"test"};                    //主题

BD_TG_Subscribe(topics,1);                          //订阅主题,数量 1

BD_TG_Publish(*topics, "MQTT Publish Test");        //发布的主题,发布的消息

MQTT_UnSubscribe(topics,1);                         //取消订阅的主题,数量 1

对于MQTT基本的订阅、发布,修改上述参数即可完成。

其他功能,则需要根据组包函数的说明,修改相应传参。


上述的代码,均是www.w5100s.com内17.MQTT_BDTG例程内的,该例程已经过实测,可正常连接百度天工云平台,实现MQTT订阅、发布等相关功能。


W5100S目前已经到货,炜世已经正式调通并将配套的资料例程补充完毕。

相关资料炜世已经整理上传至www.w5100s.com网址内,欢迎各位前往浏览。

WIZnet W5100S技术交流群:579842114,群内有“大神”为大家答疑解惑。

后续我将会陆续发布关于W5100S各类功能测试博文,有兴趣的朋友欢迎关注。

炜世是WIZnet的的的官方代理商,W5100S可提供模块/评估板供客户测试。

如需详细资料/样品申请/技术支持等,欢迎与我们联系。

炜世为客户提供全程的技术支持与优异的价格优势。

 

网址:深圳炜世科技 - 物联网系统解决方案提供商&WIZnet授权代理商

电话:13798261264

QQ:2571856470

邮箱:jason@wisioe.com

版权声明:本文来源CSDN,感谢博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/qq_41528102/article/details/82843044
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。
  • 发表于 2020-06-06 09:46:08
  • 阅读 ( 2297 )
  • 分类:职场

0 条评论

请先 登录 后评论

官方社群

GO教程

猜你喜欢