STM32+ESP8266+MQTT协议连接腾讯物联网开发平台

简介: STM32+ESP8266+MQTT协议连接腾讯物联网开发平台

一、环境介绍

单片机采用:STM32F103C8T6


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


开发软件:keil5


物联网平台: 腾讯IOT物联网物联网平台。腾讯的物联网平台比起其他厂家的物联网平台更加有优势,腾讯物联网平台可以将数据推到微信小程序上,用户可以直接使用小程序绑定设备,完成与设备之间交互,现在用户基本都会使用微信,所以使用起来非常方便。


本文章配套使用的STM32设备端完整源代码下载地址:   https://download.csdn.net/download/xiaolong1126626497/18785807



STM32+ESP8266使用MQTT协议连接OneNET 中国移动物联网开发平台:https://blog.csdn.net/xiaolong1126626497/article/details/107385118


STM32+ESP8266使用MQTT协议连接阿里云物联网开发平台:https://blog.csdn.net/xiaolong1126626497/article/details/107311897



二、功能介绍

本文章接下会介绍如何在腾讯物联网平台上创建设备、配置设备、推送到微信小程序、并编写STM32设备端代码,使用ESP8266联网登录腾讯物联网平台,完成数据交互。


功能:  STM32采集环境温度、湿度、光照强度实时上传至物联网平台,在微信小程序页面上,用户可以实时查看这些数据,并且可以通过界面上的按钮控制设备端的电机、LED灯的开关,完成数据上传和远程控制。  


说明:  STM32设备端所有代码均有自己全部编写,没有使用任何厂家的SDK,MQTT协议也是参考MQTT官方文档编写;ESP8266也没有使用任何专用固件,所以代码的移植性非常高。 任何能够联网的设备都可以参考本篇文章代码连接腾讯物联网平台,达到相同的效果。

image.png

image.pngimage.png

三、登录腾讯物联网平台创建设备

腾讯云官网:  https://cloud.tencent.com/

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

image.png

image.png

image.png

image.png

image.png

image.png

image.png

image.png

image.png

下面是手机上的截图:操作过程

image.pngimage.pngimage.png

image.pngimage.png

现在设备是离线状态,是无法查看的,接下来就使用MQTT客户端模拟设备,登录测试。



四、使用MQTT客户端模拟设备--测试

4.1  下载MQTT客户端

MQTT客户端可执行文件下载地址(.exe):  https://download.csdn.net/download/xiaolong1126626497/18784012


这个MQTT客户端采用QT开发,如果需要了解它的源码,请看这里: https://blog.csdn.net/xiaolong1126626497/article/details/116779490


4.2  查看物联网平台端口号与域名(IP地址)

官方文档:  https://cloud.tencent.com/document/product/634/32546

image.png

通过这里得到信息:   如果是广州域的设备(其实哪里都一样,只是服务器距离的远近),就填入  <产品ID>.iotcloud.tencentdevices.com  ,端口号是 1883(这是密匙认证的端口号,如果是证书认证就是另一个)。

查看产品ID的方法:

image.png

image.png

得打产品ID之后,那么要连接我的设备,域名就填:  8O76VHCU7Y.iotcloud.tencentdevices.com     端口就填: 1883



由于我的测试用的MQTT客户端不支持域名输入,只支持IP地址输入,所有我这里需要先将域名转为IP地址在进行下面的测试,ESP8266内部支持域名解析的,所有可以直接输入域名即可,不需要做这一步。


在线解析域名的网址: https://site.ip138.com/8O76VHCU7Y.iotcloud.tencentdevices.com/

image.png

得到广州腾讯云的IP地址为:  106.55.124.154



4.3  生成MQTT登录参数

就像我们登录QQ、登录微信需要账号密码一样,设备登录物联网平台也需要类似的东西。


官方文档地址: https://cloud.tencent.com/document/product/634/32546

image.png

image.png

image.png

上面需要的参数,在设备调试页面,点击具体的设备进行查看:

image.png

Python源代码:

#!/usr/bin/python
# -*- coding: UTF-8 -*-
import base64
import hashlib
import hmac
import random
import string
import time
import sys
# 生成指定长度的随机字符串
def RandomConnid(length):
    return  ''.join(random.choice(string.ascii_uppercase + string.digits) for _ in range(length))
# 生成接入物联网通信平台需要的各参数
def IotHmac(productID, devicename, devicePsk):
     # 1. 生成 connid 为一个随机字符串,方便后台定位问题
     connid   = RandomConnid(5)
     # 2. 生成过期时间,表示签名的过期时间,从纪元1970年1月1日 00:00:00 UTC 时间至今秒数的 UTF8 字符串
     expiry   = int(time.time()) + 30*24*60 * 60
     # 3. 生成 MQTT 的 clientid 部分, 格式为 ${productid}${devicename}
     clientid = "{}{}".format(productID, devicename)
     # 4. 生成 MQTT 的 username 部分, 格式为 ${clientid};${sdkappid};${connid};${expiry}
     username = "{};12010126;{};{}".format(clientid, connid, expiry)
     # 5. 对 username 进行签名,生成token
     secret_key = devicePsk.encode('utf-8')  # convert to bytes
     data_to_sign = username.encode('utf-8')  # convert to bytes
     secret_key = base64.b64decode(secret_key)  # this is still bytes
     token = hmac.new(secret_key, data_to_sign, digestmod=hashlib.sha256).hexdigest()
     # 6. 根据物联网通信平台规则生成 password 字段
     password = "{};{}".format(token, "hmacsha256")
     return {
        "clientid" : clientid,
        "username" : username,
        "password" : password
     }
if __name__ == '__main__':
    # 参数分别填入: 产品ID,设备名称,设备密匙
    print(IotHmac("8O76VHCU7Y","SmartAgriculture","OHXqYLklNBU4xLqqoZbXMQ=="))

image.png

得到的登录信息如下:

clientid: 8O76VHCU7YSmartAgriculture
username: 8O76VHCU7YSmartAgriculture;12010126;J4MCD;1623766532
password: a962b484079864239148b255281d54372aa66247aa8d6259d11aa6fef650fd5b;hmacsha256

4.4 了解主题上报和订阅的格式

登录之前需要先了解如何订阅设备的主题和上报的数据流格式。

image.png

如果设备端想要得到APP页面的按钮状态就需要订阅属性下发和属性上报的响应,主题格式就是这样的:

格式:
$thing/down/property/8O76VHCU7Y/设备名称
示例:
$thing/down/property/8O76VHCU7Y/SmartAgriculture

如果设备端想要像APP页面上传数据,那么就需要使用属性上报--发布主题:

格式:
$thing/up/property/8O76VHCU7Y/${deviceName}
示例:
$thing/up/property/8O76VHCU7Y/SmartAgriculture

设备端向APP页面上报属性时,需要上传具体的数据,数据流的格式如下:

官方文档:  https://cloud.tencent.com/document/product/1081/34916

image.png

比如: 我的产品里有温度、湿度、电机三个设备,我可以选择一次上传3个设备的信息,数据格式就这样写:

{"method":"report","clientToken":"123","params":{"temperature":20.23,"humidity":50,"Motor":1}}

其中:  "temperature"、"humidity"、"Motor"  是设备的标识符,根据自己的情况修改,冒号后面就是给这个设备上传的具体数据。

image.png

4.5 使用MQTT客户端登录设备测试

万事俱备,下面就使用MQTT客户端进行登录测试。

image.png

image.png

image.png

MQTT客户端操作步骤:

1. 填写相关参数

2. 点击登录

3. 订阅主题

4. 发布主题

5. 去APP页面查看信息

 

4.6 微信小程序效果

已经收到MQTT客户端上传的数据,点击按钮,MQTT客户端也会收到按钮下发的数据。

image.pngimage.png

五、STM32设备端代码

本文章配套使用的STM32设备端完整源代码下载地址:   https://download.csdn.net/download/xiaolong1126626497/18785807

5.1 下载程序

image.png

image.png

5.2  连接状态

image.png

image.png

STM32设备上按下按键后,手机打开微信小程序可以看到实时上传的数据,速度非常快。

 

5.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 "bluetooth.h"
#include "esp8266.h"
#include "mqtt.h"
//腾讯物联网服务器的设备信息
#define MQTT_ClientID "8O76VHCU7YSmartAgriculture"
#define MQTT_UserName "8O76VHCU7YSmartAgriculture;12010126;J4MCD;1623766532"
#define MQTT_PassWord "a962b484079864239148b255281d54372aa66247aa8d6259d11aa6fef650fd5b;hmacsha256"
//订阅与发布的主题
#define SET_TOPIC  "$thing/down/property/8O76VHCU7Y/SmartAgriculture"  //订阅
#define POST_TOPIC "$thing/up/property/8O76VHCU7Y/SmartAgriculture"  //发布
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
   USART2_Init(9600);//串口-蓝牙
   TIMER2_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("CMCC-Cqvn","99pu58cb","106.55.124.154",1883,1));
   }
    //2. MQTT协议初始化  
    MQTT_Init(); 
    //3. 连接OneNet服务器        
    while(MQTT_Connect(MQTT_ClientID,MQTT_UserName,MQTT_PassWord))
    {
        USART1_Printf("服务器连接失败,正在重试...\n");
        delay_ms(500);
    }
    USART1_Printf("服务器连接成功.\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,"{\"method\":\"report\",\"clientToken\":\"123\",\"params\":{\"temperature\":20.23,\"humidity\":50,\"Motor\":1}}");
            MQTT_PublishData(POST_TOPIC,mqtt_message,0);
            USART1_Printf("发送状态1\r\n");
        }
        else if(key==3)
        {
            time_cnt=0;
            sprintf(mqtt_message,"{\"method\":\"report\",\"clientToken\":\"123\",\"params\":{\"temperature\":10.23,\"humidity\":60,\"Motor\":0}}");
            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;
        }
    }
}

5.4 mqtt.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);
} 


目录
相关文章
|
3月前
|
存储 物联网 关系型数据库
基于STM32和ESP8266的智慧考勤系统设计与实现【免费开源】
本文介绍了一个基于 STM32F103ZET6 + ESP8266 Mesh 的智慧考勤系统,涵盖了硬件架构、软件设计、网络组网、服务器端实现与数据导出。该系统不仅实现了考勤自动化,还支持多点分布式部署,具有良好的扩展性与应用价值。
|
3月前
|
传感器 数据采集 安全
基于STM32与ESP8266的智能家居控制系统【免费开源】
通过本项目的开发,不仅加深了对 STM32 外设编程的理解,还掌握了物联网系统的整体设计思路。从传感器数据采集,到通信协议实现,再到云端与APP交互,完整地体验了智能家居系统的开发流程。这为后续更复杂的 IoT 项目打下了坚实基础。
基于STM32与ESP8266的智能家居控制系统【免费开源】
|
3月前
|
传感器 前端开发 物联网
【免费开源】STM32+ESP8266 打造低成本智能家居物联网系统(附源码与硬件设计)
本项目基于STM32与ESP8266打造低成本智能家居系统,支持温度监测、远程控制与数据上传,附完整源码与硬件设计,适合物联网初学者与电子爱好者学习与扩展。
|
物联网 智能硬件
物联网技术:连接智能生活的桥梁
物联网技术:连接智能生活的桥梁
|
8月前
|
传感器 人工智能 物联网
健康监测设备的技术革命:AI+物联网如何让你随时掌握健康数据?
健康监测设备的技术革命:AI+物联网如何让你随时掌握健康数据?
1085 19
|
存储 安全 物联网
政府在推动物联网技术标准和规范的统一方面可以发挥哪些作用?
政府在推动物联网技术标准和规范的统一方面可以发挥哪些作用?
416 60
|
安全 物联网 物联网安全
制定统一的物联网技术标准和规范的难点有哪些?
制定统一的物联网技术标准和规范的难点有哪些?
459 58
|
存储 数据采集 物联网
物联网技术在物流领域的应用会遇到哪些挑战?
物联网技术在物流领域的应用会遇到哪些挑战?
679 60
|
供应链 物联网 区块链
探索未来技术潮流:区块链、物联网、虚拟现实的融合与创新
【10月更文挑战第41天】随着科技的不断进步,新技术如区块链、物联网、虚拟现实等正在逐步渗透到我们的日常生活中。本文将深入探讨这些技术的发展趋势和应用场景,以及它们如何相互融合,共同推动社会的进步。我们将通过具体的代码示例,展示这些技术在实际应用中的潜力和价值。无论你是科技爱好者,还是对未来充满好奇的探索者,这篇文章都将为你打开一扇通往未来的窗口。
231 56
|
供应链 监控 搜索推荐
物联网技术在物流领域的应用会带来哪些影响?
物联网技术在物流领域的应用会带来哪些影响?
1367 58

相关产品

  • 物联网平台