STM32+ESP8266+MQTT协议连接OneNet物联网平台

简介: STM32+ESP8266+MQTT协议连接OneNet物联网平台

一、环境介绍

单片机采用:STM32F103C8T6


上网方式:采用ESP8266,也可以使用其他设备代替,只要支持TCP协议即可。比如:GSM模块、有线网卡等。


开发软件:keil5


硬件连接功能:ESP8266接在STM32的串口3上。通过AT指令与ESP8266进行通信。


注意:本篇文章没有贴ESP8266的底层编程代码,如果不会ESP8266底层编程,请看这里:


https://blog.csdn.net/xiaolong1126626497/article/details/107379554


如果需要了解ESP8266+MQTT协议连接阿里云物联网服务器请看这里:https://blog.csdn.net/xiaolong1126626497/article/details/107311897



工程完整源码下载: https://download.csdn.net/download/xiaolong1126626497/15803518



二、功能介绍

2.1 功能说明

通过OneNet物联网服务器实现设备数据远程上传、下发,实现数据交互(不清楚OneNet物联网服务器功能的可以百度一下进入官网看简介)。之前的OneNet服务器不支持标准MQTT协议登录的,现在官网更新之后支持标准的MQTT协议,本篇文章介绍使用STM32+ESP8266使用标准MQTT协议登录Onenet服务器,实现数据交互。实现步骤OneNet官方提供了很详细的文档,可以参考一下。


文档地址:https://open.iot.10086.cn/devdoc/

image.png

image.png

2.2 硬件资源

在当前使用的开发板上有4盏LED灯、一个蜂鸣器、4个按键,ESP8266型号是ESP-12F,STM32型号是:STM32F103C8T6。

image.png

三、OneNet支持的MQTT协议版本

目前OneNet服务器支持MQTT 3.1.1版本,MQTT协议官网: http://mqtt.org/?spm=a2c4g.11186623.2.11.19083f86gxhJ7h


报文支持情况:  支持connect、subscribe、publish、ping、unsubscribe、disconnect等报文,不支持pubrec、pubrel、pubcomp报文。

image.png

四、登录OneNet服务器创建物联网产品

没有注册账号的,需要提前登录官网注册账号,再进入下面步骤:

image.png

image.png

image.png

这里根据自己产品情况填写。

image.png

image.png

image.png

产品创建成功之后,点击产品名称,跳转页面,继续添加设备。

image.png

image.png

image.png

image.png

image.png

image.png

image.png

image.png

image.png

image.png

image.png

image.png

image.png

image.png

image.png

image.png

下面选择仪表盘的数据来源,根据自己创建的数据点选择。

image.png

创建一个文本控件,显示数据点更新的时间,方便调试。

image.png

image.png

image.png

image.png

OneNte有手机版本的APP,登录之后也可以看到该页面。

下载地址:https://open.iot.10086.cn/doc/book/device-develop/multpro/sdk-doc-tool/APP.html

image.png

image.png

下面是手机上登录APP看到的界面效果:

image.png

image.png

五、OneNet服务器MQTT登录地址与订阅主题相关格式介绍

官网介绍文档地址: https://open.iot.10086.cn/doc/mqtt/book/get-start/connect.html

image.png

5.1 MQTT服务器登录地址

image.png

目前MQTT协议支持两个IP地址和端口号,一个需要加密、一个不需要加密。

注意:单片机上移植加密算法很麻烦,这里采用不需要加密的端口。(IP地址: 183.230.40.96  端口: 1883)

image.png

5.2 MQTT登录的:设备ID、用户名称、密码 格式参数

image.png

image.png

image.png

上面图片里说明了,OneNet的设备参数与标准MQTT协议的登录参数对应关系。 OneNet的设备参数,在设备页面可以去查看。

 

登录密码生成看下面步骤:

image.png

image.png

image.png

注意:该工具在win10系统运行可能会提示非信任程序,点击任要运行即可。

下面是生成MQTT登录密匙的工具使用示例。

image.png

注意:工具中填的参数说明请看文档介绍。


res选项参数的格式: products/{产品ID}/devices/{设备名称}


et是设置token过期时间:算出1970-1-1到你想要设置的到期时间,单位是秒,填入即可。


比如: 超时时间设置为2020-07-20 ,那么,这里填入的秒就是:1970-1-1到2020-07-20之间的秒单位时间。


Linux下代码:

#include <stdio.h>
#include <time.h>
 #include <time.h>
int main()
{
    time_t time_sec;
    time_sec=time(NULL);  //当前的秒单位时间--UTC时间
  printf("当前时间(秒):%ld\n",time_sec);
  printf("加30天的时间(秒):%ld\n",time_sec+30*24*60*60);
  return 0;
}

key的参数格式: 就是设备创建之后,在设备详情页的key


工具生成的结果值,直接当做MQTT登录的密码。



5.3 主题订阅格式

文档地址:https://open.iot.10086.cn/doc/mqtt/book/device-develop/protocol.html

image.png

image.png

5.4 设备保活时间

image.png

image.png

5.5 向服务器传数据点

image.png

image.png

image.png

六、核心代码

6.1 matt.c代码

#include "mqtt.h"
u8 *mqtt_rxbuf;
u8 *mqtt_txbuf;
u16 mqtt_rxlen;
u16 mqtt_txlen;
u8 _mqtt_txbuf[256];//发送数据缓存区
u8 _mqtt_rxbuf[256];//接收数据缓存区
typedef enum
{
  //名字      值       报文流动方向  描述
  M_RESERVED1 =0  , //  禁止  保留
  M_CONNECT   , //  客户端到服务端 客户端请求连接服务端
  M_CONNACK   , //  服务端到客户端 连接报文确认
  M_PUBLISH   , //  两个方向都允许 发布消息
  M_PUBACK    , //  两个方向都允许 QoS 1消息发布收到确认
  M_PUBREC    , //  两个方向都允许 发布收到(保证交付第一步)
  M_PUBREL    , //  两个方向都允许 发布释放(保证交付第二步)
  M_PUBCOMP   , //  两个方向都允许 QoS 2消息发布完成(保证交互第三步)
  M_SUBSCRIBE   , //  客户端到服务端 客户端订阅请求
  M_SUBACK    , //  服务端到客户端 订阅请求报文确认
  M_UNSUBSCRIBE , //  客户端到服务端 客户端取消订阅请求
  M_UNSUBACK    , //  服务端到客户端 取消订阅报文确认
  M_PINGREQ   , //  客户端到服务端 心跳请求
  M_PINGRESP    , //  服务端到客户端 心跳响应
  M_DISCONNECT  , //  客户端到服务端 客户端断开连接
  M_RESERVED2   , //  禁止  保留
}_typdef_mqtt_message;
//连接成功服务器回应 20 02 00 00
//客户端主动断开连接 e0 00
const u8 parket_connetAck[] = {0x20,0x02,0x00,0x00};
const u8 parket_disconnet[] = {0xe0,0x00};
const u8 parket_heart[] = {0xc0,0x00};
const u8 parket_heart_reply[] = {0xc0,0x00};
const u8 parket_subAck[] = {0x90,0x03};
void MQTT_Init(void)
{
    //缓冲区赋值
  mqtt_rxbuf = _mqtt_rxbuf;
    mqtt_rxlen = sizeof(_mqtt_rxbuf);
  mqtt_txbuf = _mqtt_txbuf;
    mqtt_txlen = sizeof(_mqtt_txbuf);
  memset(mqtt_rxbuf,0,mqtt_rxlen);
  memset(mqtt_txbuf,0,mqtt_txlen);
  //无条件先主动断开
  MQTT_Disconnect();
    delay_ms(100);
  MQTT_Disconnect();
    delay_ms(100);
}
/*
函数功能: 登录服务器
函数返回值: 0表示成功 1表示失败
*/
u8 MQTT_Connect(char *ClientID,char *Username,char *Password)
{
    u8 i,j;
    int ClientIDLen = strlen(ClientID);
    int UsernameLen = strlen(Username);
    int PasswordLen = strlen(Password);
    int DataLen;
  mqtt_txlen=0;
  //可变报头+Payload  每个字段包含两个字节的长度标识
    DataLen = 10 + (ClientIDLen+2) + (UsernameLen+2) + (PasswordLen+2);
  //固定报头
  //控制报文类型
    mqtt_txbuf[mqtt_txlen++] = 0x10;    //MQTT Message Type CONNECT
  //剩余长度(不包括固定头部)
  do
  {
    u8 encodedByte = DataLen % 128;
    DataLen = DataLen / 128;
    // if there are more data to encode, set the top bit of this byte
    if ( DataLen > 0 )
      encodedByte = encodedByte | 128;
    mqtt_txbuf[mqtt_txlen++] = encodedByte;
  }while ( DataLen > 0 );
  //可变报头
  //协议名
    mqtt_txbuf[mqtt_txlen++] = 0;         // Protocol Name Length MSB    
    mqtt_txbuf[mqtt_txlen++] = 4;           // Protocol Name Length LSB    
    mqtt_txbuf[mqtt_txlen++] = 'M';         // ASCII Code for M    
    mqtt_txbuf[mqtt_txlen++] = 'Q';         // ASCII Code for Q    
    mqtt_txbuf[mqtt_txlen++] = 'T';         // ASCII Code for T    
    mqtt_txbuf[mqtt_txlen++] = 'T';         // ASCII Code for T    
  //协议级别
    mqtt_txbuf[mqtt_txlen++] = 4;           // MQTT Protocol version = 4   对于 3.1.1 版协议,协议级别字段的值是 4(0x04)   
  //连接标志
    mqtt_txbuf[mqtt_txlen++] = 0xc2;          // conn flags 
    mqtt_txbuf[mqtt_txlen++] = 0;           // Keep-alive Time Length MSB    
    mqtt_txbuf[mqtt_txlen++] = 100;         // Keep-alive Time Length LSB  100S心跳包    保活时间
    mqtt_txbuf[mqtt_txlen++] = BYTE1(ClientIDLen);// Client ID length MSB    
    mqtt_txbuf[mqtt_txlen++] = BYTE0(ClientIDLen);// Client ID length LSB   
  memcpy(&mqtt_txbuf[mqtt_txlen],ClientID,ClientIDLen);
    mqtt_txlen += ClientIDLen;
    if(UsernameLen > 0)
    {   
        mqtt_txbuf[mqtt_txlen++] = BYTE1(UsernameLen);    //username length MSB    
        mqtt_txbuf[mqtt_txlen++] = BYTE0(UsernameLen);      //username length LSB    
    memcpy(&mqtt_txbuf[mqtt_txlen],Username,UsernameLen);
        mqtt_txlen += UsernameLen;
    }
    if(PasswordLen > 0)
    {    
        mqtt_txbuf[mqtt_txlen++] = BYTE1(PasswordLen);    //password length MSB    
        mqtt_txbuf[mqtt_txlen++] = BYTE0(PasswordLen);      //password length LSB  
    memcpy(&mqtt_txbuf[mqtt_txlen],Password,PasswordLen);
        mqtt_txlen += PasswordLen; 
    }    
    memset(mqtt_rxbuf,0,mqtt_rxlen);
    MQTT_SendBuf(mqtt_txbuf,mqtt_txlen);
    for(j=0;j<10;j++)
    {
        delay_ms(50);
        if(USART3_RX_FLAG)
        {
            memcpy((char *)mqtt_rxbuf,USART3_RX_BUFFER,USART3_RX_CNT);
            //memcpy
             for(i=0;i<USART3_RX_CNT;i++)USART1_Printf("%#x ",USART3_RX_BUFFER[i]);
            USART3_RX_FLAG=0;
            USART3_RX_CNT=0;
        }
        //CONNECT
        if(mqtt_rxbuf[0]==parket_connetAck[0] && mqtt_rxbuf[1]==parket_connetAck[1]) //连接成功        
        {
            return 0;//连接成功
        }
    }
  return 1;
}
/*
函数功能: MQTT订阅/取消订阅数据打包函数
函数参数:
    topic       主题   
    qos         消息等级 0:最多分发一次  1: 至少分发一次  2: 仅分发一次
    whether     订阅/取消订阅请求包 (1表示订阅,0表示取消订阅)
返回值: 0表示成功 1表示失败
*/
u8 MQTT_SubscribeTopic(char *topic,u8 qos,u8 whether)
{    
    u8 i,j;
  mqtt_txlen=0;
    int topiclen = strlen(topic);
  int DataLen = 2 + (topiclen+2) + (whether?1:0);//可变报头的长度(2字节)加上有效载荷的长度
  //固定报头
  //控制报文类型
    if(whether)mqtt_txbuf[mqtt_txlen++] = 0x82; //消息类型和标志订阅
    else  mqtt_txbuf[mqtt_txlen++] = 0xA2;    //取消订阅
  //剩余长度
  do
  {
    u8 encodedByte = DataLen % 128;
    DataLen = DataLen / 128;
    // if there are more data to encode, set the top bit of this byte
    if ( DataLen > 0 )
      encodedByte = encodedByte | 128;
    mqtt_txbuf[mqtt_txlen++] = encodedByte;
  }while ( DataLen > 0 ); 
  //可变报头
    mqtt_txbuf[mqtt_txlen++] = 0;     //消息标识符 MSB
    mqtt_txbuf[mqtt_txlen++] = 0x0A;        //消息标识符 LSB
  //有效载荷
    mqtt_txbuf[mqtt_txlen++] = BYTE1(topiclen);//主题长度 MSB
    mqtt_txbuf[mqtt_txlen++] = BYTE0(topiclen);//主题长度 LSB   
  memcpy(&mqtt_txbuf[mqtt_txlen],topic,topiclen);
    mqtt_txlen += topiclen;
    if(whether)
    {
       mqtt_txbuf[mqtt_txlen++] = qos;//QoS级别
    }
    for(i=0;i<10;i++)
    {
        memset(mqtt_rxbuf,0,mqtt_rxlen);
    MQTT_SendBuf(mqtt_txbuf,mqtt_txlen);
        for(j=0;j<10;j++)
        {
            delay_ms(50);
            if(USART3_RX_FLAG)
      {
                memcpy((char *)mqtt_rxbuf,(char*)USART3_RX_BUFFER,USART3_RX_CNT);
        USART3_RX_FLAG=0;
        USART3_RX_CNT=0;
      }
      if(mqtt_rxbuf[0]==parket_subAck[0] && mqtt_rxbuf[1]==parket_subAck[1]) //订阅成功        
      {
        return 0;//订阅成功
      }
        }
    }
  return 1; //失败
}
//MQTT发布数据打包函数
//topic   主题 
//message 消息
//qos     消息等级 
u8 MQTT_PublishData(char *topic, char *message, u8 qos)
{  
    int topicLength = strlen(topic);    
    int messageLength = strlen(message);     
    static u16 id=0;
  int DataLen;
  mqtt_txlen=0;
  //有效载荷的长度这样计算:用固定报头中的剩余长度字段的值减去可变报头的长度
  //QOS为0时没有标识符
  //数据长度             主题名   报文标识符   有效载荷
    if(qos) DataLen = (2+topicLength) + 2 + messageLength;       
    else  DataLen = (2+topicLength) + messageLength;   
    //固定报头
  //控制报文类型
    mqtt_txbuf[mqtt_txlen++] = 0x30;    // MQTT Message Type PUBLISH  
  //剩余长度
  do
  {
    u8 encodedByte = DataLen % 128;
    DataLen = DataLen / 128;
    // if there are more data to encode, set the top bit of this byte
    if ( DataLen > 0 )
      encodedByte = encodedByte | 128;
    mqtt_txbuf[mqtt_txlen++] = encodedByte;
  }while ( DataLen > 0 ); 
    mqtt_txbuf[mqtt_txlen++] = BYTE1(topicLength);//主题长度MSB
    mqtt_txbuf[mqtt_txlen++] = BYTE0(topicLength);//主题长度LSB 
  memcpy(&mqtt_txbuf[mqtt_txlen],topic,topicLength);//拷贝主题
    mqtt_txlen += topicLength;
  //报文标识符
    if(qos)
    {
        mqtt_txbuf[mqtt_txlen++] = BYTE1(id);
        mqtt_txbuf[mqtt_txlen++] = BYTE0(id);
        id++;
    }
  memcpy(&mqtt_txbuf[mqtt_txlen],message,messageLength);
    mqtt_txlen += messageLength;
  MQTT_SendBuf(mqtt_txbuf,mqtt_txlen);
    return mqtt_txlen;
}
void MQTT_SentHeart(void)
{
  MQTT_SendBuf((u8 *)parket_heart,sizeof(parket_heart));
}
void MQTT_Disconnect(void)
{
  MQTT_SendBuf((u8 *)parket_disconnet,sizeof(parket_disconnet));
}
void MQTT_SendBuf(u8 *buf,u16 len)
{
  USARTx_DataSend(USART3,buf,len);
} 

6.2 mqtt.h代码

#ifndef __FY_MQTT_H_
#define __FY_MQTT_H_
#include "stm32f10x.h"
#include "string.h"
#include "stdio.h"
#include "stdlib.h"
#include "stdarg.h"
#include "delay.h"
#include "usart.h"
#define BYTE0(dwTemp)       (*( char *)(&dwTemp))
#define BYTE1(dwTemp)       (*((char *)(&dwTemp) + 1))
#define BYTE2(dwTemp)       (*((char *)(&dwTemp) + 2))
#define BYTE3(dwTemp)       (*((char *)(&dwTemp) + 3))
//用户名初始化
void OneNet_LoginInit(char *ProductKey,char *DeviceName,char *DeviceSecret);
//MQTT协议相关函数声明
u8 MQTT_PublishData(char *topic, char *message, u8 qos);
u8 MQTT_SubscribeTopic(char *topic,u8 qos,u8 whether);
void MQTT_Init(void);
u8 MQTT_Connect(char *ClientID,char *Username,char *Password);
void MQTT_SentHeart(void);
void MQTT_Disconnect(void);
void MQTT_SendBuf(u8 *buf,u16 len);
#endif

6.3 main.c 主函数代码

#include "stm32f10x.h"
#include "led.h"
#include "delay.h"
#include "key.h"
#include "usart.h"
#include <string.h>
#include "timer.h"
#include "esp8266.h"
#include "mqtt.h"
/*
序号  符号  编码
1 + %2B
2 空格%20
3 / %2F
4 ? %3F
5 % %25
6 # %23
7 & %26
8 = %3D
*/
//OneNet物联网服务器的设备信息
#define MQTT_ClientID "mq2"
#define MQTT_UserName "361594"
#define MQTT_PassWord "version=2018-10-31&res=products%2F361594%2Fdevices%2Fmq2&et=1597492895&method=sha1&sign=uqvA0KkjXw0FlN01aT6fWrGBLGw%3D"
//订阅与发布的主题
//格式:$sys/{产品ID}/{设备名称}/#
#define SET_TOPIC  "$sys/361594/mq2/#"  //订阅设备所有信息
//格式: $sys/{产品ID}/{设备名称}/dp/post/json
#define POST_TOPIC "$sys/361594/mq2/dp/post/json"  //发布
char mqtt_message[200];//上报数据缓存区
int main()
{
   u32 time_cnt=0;
   u32 i;
   u8 key;
   LED_Init();
   BEEP_Init();
   KEY_Init();
   USART1_Init(115200);
   TIMER1_Init(72,20000); //超时时间20ms
   USART3_Init(115200);//串口-WIFI
   TIMER3_Init(72,20000); //超时时间20ms
   USART1_Printf("正在初始化WIFI请稍等.\n");
   if(ESP8266_Init())
   {
      USART1_Printf("ESP8266硬件检测错误.\n");  
   }
   else
   {
      //加密端口
      //USART1_Printf("WIFI:%d\n",ESP8266_STA_TCP_Client_Mode("OnePlus5T","1126626497","183.230.40.16",8883,1));
      //非加密端口
      USART1_Printf("WIFI:%d\n",ESP8266_STA_TCP_Client_Mode("OnePlus5T","1126626497","183.230.40.96",1883,1));
   }
    //2. MQTT协议初始化  
    MQTT_Init(); 
    //3. 连接OneNet服务器        
    while(MQTT_Connect(MQTT_ClientID,MQTT_UserName,MQTT_PassWord))
    {
        USART1_Printf("OneNet服务器连接失败,正在重试...\n");
        delay_ms(500);
    }
    USART1_Printf("OneNet服务器连接成功.\n");
    //3. 订阅主题
    if(MQTT_SubscribeTopic(SET_TOPIC,0,1))
    {
        USART1_Printf("主题订阅失败.\n");
    }
    else
    {
        USART1_Printf("主题订阅成功.\n");
    }        
    while(1)
    {    
        key=KEY_Scan(0);
        if(key==2)
        {
            time_cnt=0;
            sprintf(mqtt_message,"{\"id\":1,\"dp\":{\"mq2\":[{\"v\":50}]}}");
            MQTT_PublishData(POST_TOPIC,mqtt_message,0);
            USART1_Printf("发送状态1\r\n");
        }
        else if(key==3)
        {
            time_cnt=0;
            sprintf(mqtt_message,"{\"id\":1,\"dp\":{\"mq2\":[{\"v\":80}]}}");
            MQTT_PublishData(POST_TOPIC,mqtt_message,0);
            USART1_Printf("发送状态0\r\n");
        }  
        if(USART3_RX_FLAG)
        {
            USART3_RX_BUFFER[USART3_RX_CNT]='\0';
            for(i=0;i<USART3_RX_CNT;i++)
            {
                USART1_Printf("%c",USART3_RX_BUFFER[i]);
            }
            USART3_RX_CNT=0;
            USART3_RX_FLAG=0;
        }
        //定时发送心跳包,保持连接
        delay_ms(10);
        time_cnt++;
        if(time_cnt==500)
        {
            MQTT_SentHeart();//发送心跳包
            time_cnt=0;
        }
    }
}

七、设备登录运行效果

登录成功之后,网页会显示在线状态。

image.png

按下开发按键上传烟雾数据到服务器效果:

image.png

image.png


相关实践学习
阿里云AIoT物联网开发实战
本课程将由物联网专家带你熟悉阿里云AIoT物联网领域全套云产品,7天轻松搭建基于Arduino的端到端物联网场景应用。 开始学习前,请先开通下方两个云产品,让学习更流畅: IoT物联网平台:https://iot.console.aliyun.com/ LinkWAN物联网络管理平台:https://linkwan.console.aliyun.com/service-open
目录
相关文章
|
消息中间件 存储 数据采集
4步实现状态机驱动的MQTT客户端,快速接入OneNet (1)
本文介绍了基于状态机驱动的MQTT客户端快速接入OneNet平台的实现方法,通过4步完成模块设计。文章以开源项目`Sparrow`为基础,引入`OneNetMqtt`业务模块,采用事件驱动模型和双层状态机设计,实现设备状态管理、消息处理及定时任务等功能。模块分为三层:`OneNetManager`负责核心逻辑,`OneNetDevice`管理设备信息,`OneNetDriver`处理Socket与MQTT通信。验证结果显示设备连接、数据上报及下线功能正常,稳定性良好。该设计简化了复杂条件判断,增强了系统灵活性与可扩展性,适用于实际项目参考。文末提供源码获取方式,助力读者实践与学习。
778 119
|
数据可视化 关系型数据库 MySQL
嵌入式C++、STM32、MySQL、GPS、InfluxDB和MQTT协议数据可视化
通过本文的介绍,我们详细讲解了如何结合嵌入式C++、STM32、MySQL、GPS、InfluxDB和MQTT协议,实现数据的采集、传输、存储和可视化。这种架构在物联网项目中非常常见,可以有效地处理和展示实时数据。希望本文能帮助您更好地理解和应用这些技术,构建高效、可靠的数据处理和可视化系统。
843 82
|
传感器 数据采集 监控
基于阿里云MQTT服务,设计一个STM32的智能光伏控制系统
这篇文章详细介绍了利用STM32F103C8T6单片机实现光伏发电系统的关键技术。全文分为四章:第一章阐述了光伏发电的背景、意义及应用场景,强调其在绿色能源领域的重要性。第二章介绍了如何通过STM32F103C8T6及光敏电阻和伺服电机实现光线追踪系统,详细描述了硬件选择、连接及使用HAL库编写的单片机程序。第三章讲解了最大功率点追踪(MPPT)的原理,并展示了如何利用STM32F103C8T6和相关传感器、DC-DC转换器实现MPPT功能。第四章描述了如何通过STM32F103C8T6与SIM7600CE 4G模块连接到阿里云MQTT服务,实现设备状态数据的远程传输和控制。本文提供了全面的硬
18489 5
|
Java 物联网 网络安全
mqtt问题之STM32F103GPRS模组如何接入物理网平台
MQTT接入是指将设备或应用通过MQTT协议接入到消息服务器,以实现数据的发布和订阅;本合集着眼于MQTT接入的流程、配置指导以及常见接入问题的解决方法,帮助用户实现稳定可靠的消息交换。
403 2
|
传感器 数据采集 编解码
基于STM32的物联网环境监测系统
基于STM32的物联网环境监测系统
1175 0
基于STM32的物联网环境监测系统
|
缓存 自然语言处理 网络协议
STM32CubeMX | | 使用小熊派串口驱动峰汇ETH-01以太网模块上传数据到OneNet
STM32CubeMX | | 使用小熊派串口驱动峰汇ETH-01以太网模块上传数据到OneNet
364 0
|
传感器 监控 网络协议
STM32配合W5500网卡连接MQTT服务器
W5500是一种基于TCP/IP协议的网络通讯芯片,可以提供网络连接功能,相当于是一种嵌入式以太网控制器,具有低功耗、高速传输、易于集成等特点。
1993 1
|
传感器 网络架构 智能硬件
STM32通过esp8266连接WiFi接入MQTT服务器
STM32通过esp8266连接WiFi接入MQTT服务器
2378 1
|
智能硬件
STM32智能家居项目(5)MQTT基础
STM32智能家居项目(5)MQTT基础
487 0
|
传感器 物联网 智能硬件
STM32智能家居项目(6)MQTT的移植
STM32智能家居项目(6)MQTT的移植
845 0

相关产品

  • 物联网平台