打印
[应用相关]

STM32F103ZE+ESP8266+云物联网平台+微信小程序

[复制链接]
楼主: 自动化陈稳
手机看帖
扫描二维码
随时随地手机跟帖
21
自动化陈稳|  楼主 | 2021-5-29 23:34 | 只看该作者 |只看大图 回帖奖励 |倒序浏览

使用特权

评论回复
22
自动化陈稳|  楼主 | 2021-5-29 23:35 | 只看该作者

使用特权

评论回复
23
自动化陈稳|  楼主 | 2021-5-29 23:36 | 只看该作者

使用特权

评论回复
24
自动化陈稳|  楼主 | 2021-5-29 23:43 | 只看该作者

使用特权

评论回复
25
自动化陈稳|  楼主 | 2021-5-29 23:45 | 只看该作者

使用特权

评论回复
26
自动化陈稳|  楼主 | 2021-5-29 23:45 | 只看该作者

使用特权

评论回复
27
自动化陈稳|  楼主 | 2021-5-29 23:46 | 只看该作者

使用特权

评论回复
28
自动化陈稳|  楼主 | 2021-5-29 23:48 | 只看该作者
四、生成腾讯物联网平台的设备登录信息
使用MQTT协议登录需要一些参数信息,需要使用官网提供的方式生成。

使用特权

评论回复
29
自动化陈稳|  楼主 | 2021-5-29 23:48 | 只看该作者

使用特权

评论回复
30
自动化陈稳|  楼主 | 2021-5-29 23:50 | 只看该作者
#!/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("6142CX41XE", "SmartAgriculture","20Y/aAcmj+y6SDDh+ANR9g=="))
Python示例代码:

使用特权

评论回复
31
自动化陈稳|  楼主 | 2021-5-29 23:52 | 只看该作者
{'clientid': '6142CX41XESmartAgriculture', 'username': '6142CX41XESmartAgriculture;12010126;HUA2G;1624271589', 
'password': 'a8aadebe9721f70e6f9e14fe56ff1d2b5cac9625fa1f96af2f0e0098597fe78b;hmacsha256'}
输出的登录参数,用于MQTT协议填参数:

使用特权

评论回复
32
自动化陈稳|  楼主 | 2021-5-29 23:53 | 只看该作者
五、使用MQTT软件测试
MQTT客户端软件下载地址: https://download.csdn.net/download/xiaolong1126626497/18784012

该软件采用QT开发,源码地址: https://blog.csdn.net/xiaolong11 ... e/details/116779490

使用特权

评论回复
33
自动化陈稳|  楼主 | 2021-5-29 23:56 | 只看该作者

使用特权

评论回复
34
自动化陈稳|  楼主 | 2021-5-29 23:56 | 只看该作者
设备主题发布与定义的格式:

使用特权

评论回复
35
自动化陈稳|  楼主 | 2021-5-31 21:35 | 只看该作者
设备消息数据上传格式:
{"method":"report","clientToken":"123","params":{"light":78.4,"temperature":21.4,"humidity":60.8,"motor":1}}

使用特权

评论回复
36
自动化陈稳|  楼主 | 2021-5-31 21:39 | 只看该作者
登录成功之后,就可以看到设备在线:

使用特权

评论回复
37
自动化陈稳|  楼主 | 2021-5-31 21:41 | 只看该作者
打开微信小程序可以查看到设备上传的数据:

使用特权

评论回复
38
自动化陈稳|  楼主 | 2021-5-31 21:43 | 只看该作者
六、编写STM32设备端代码

使用特权

评论回复
39
自动化陈稳|  楼主 | 2021-5-31 21:49 | 只看该作者
6.1 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"
#include "oled.h"
#include "fontdata.h"
#include "bh1750.h"
#include "iic.h"
#include "sht3x.h"

/*
硬件连接方式:
ESP8266串口WIFI模块与STM32的串口3相连接。
PB10--RXD 模块接收脚
PB11--TXD 模块发送脚
GND---GND 地
VCC---VCC 电源(3.3V~5.0V)
OLED接线:
D0----SCK-----PB14
D1----MOSI----PB13
RES—复位(低电平有效)—PB12
DC---数据和命令控制管脚—PB1
CS---片选引脚-----PA7
微型直流电机:  PB8
紫光灯:        PB9
LED硬件连接: PB5 PE5
KEY硬件连接:PE3 PE4
*/

#define ESP8266_WIFI_AP_SSID  "CMCC-Cqvn"   //将要连接的路由器名称 --不要出现中文、空格等特殊字符
#define ESP8266_AP_PASSWORD "99pu58cb"     //将要连接的路由器密码


//腾讯物联网服务器的设备信息
#define MQTT_ClientID "6142CX41XESmartAgriculture"
#define MQTT_UserName "6142CX41XESmartAgriculture;12010126;HUA2G;1624271589"
#define MQTT_PassWord "a8aadebe9721f70e6f9e14fe56ff1d2b5cac9625fa1f96af2f0e0098597fe78b;hmacsha256"

//订阅与发布的主题
#define SET_TOPIC  "$thing/down/property/6142CX41XE/SmartAgriculture"  //订阅
#define POST_TOPIC "$thing/up/property/6142CX41XE/SmartAgriculture"  //发布


char mqtt_message[200];//上报数据缓存区
char OLED_ShowBuff[100];
u8 ESP8266_Stat=0;


/*
函数功能: 温湿度\光强度显示
*/
void ShowTemperatureAndHumidity(float temp,float humi,float light)
{
    sprintf(OLED_ShowBuff,"T: %.2f",temp);
        OLED_ShowString(40,16*0,16,OLED_ShowBuff);
    sprintf(OLED_ShowBuff,"H: %.2f%%",humi);
        OLED_ShowString(40,16*1,16,OLED_ShowBuff);
    sprintf(OLED_ShowBuff,"L: %.2f%%",light);
        OLED_ShowString(40,16*2,16,OLED_ShowBuff);
}

/*
函数功能: ESP8266显示页面
*/
void ESP8266_ShowPageTable(void)
{
    if(ESP8266_Stat)OLED_ShowString(0,16*0,16,"WIFI STAT:ERROR");
    else OLED_ShowString(0,16*0,16,"WIFI STAT:OK");

    //显示字符串
    sprintf((char*)OLED_ShowBuff,"%s",ESP8266_WIFI_AP_SSID);
    OLED_ShowString(0,16*1,16,OLED_ShowBuff);       
   
    sprintf((char*)OLED_ShowBuff,"%s",ESP8266_AP_PASSWORD);   
    OLED_ShowString(0,16*2,16,OLED_ShowBuff);   
}


int main()
{
   u32 time_cnt=0;
   u32 i;
   u8 key;
   u8 page=0;
   float temp=0;
   float humi=0;
   float light=0;
   u8 motor_state=0;
   float Humidity;
   float Temperature;
   
   delay_ms(1000);
   delay_ms(1000);
   
   LED_Init();
   KEY_Init();
   IIC_Init();
   
    //OLED初始化
   OLED_Init(0xc8,0xa1); //OLED显示屏初始化--正常显示;
     //清屏
   OLED_Clear(0);
   
   USART1_Init(115200);
   TIMER1_Init(72,20000); //超时时间20ms

   USART3_Init(115200);//串口-WIFI
   TIMER3_Init(72,20000); //超时时间20ms
   
   Init_SHT30();
   
   USART1_Printf("正在初始化WIFI请稍等.\n");
   
   if(ESP8266_Init())
   {
      ESP8266_Stat=1;
      USART1_Printf("ESP8266硬件检测错误.\n");  
   }
   else
   {
      //非加密端口
      USART1_Printf("WIFI:%d\n",ESP8266_STA_TCP_Client_Mode(ESP8266_WIFI_AP_SSID,ESP8266_AP_PASSWORD,"106.55.124.154",1883,1));
   }
   
    //2. MQTT协议初始化       
    MQTT_Init();
   
    //3. 连接腾讯云IOT服务器        
    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==1)
        {
            //清屏
            OLED_Clear(0);
            
            //翻页
            if(page>=1)
            {
                page=0;
            }
            else
            {
                 page++;
            }         
        
            LED1=!LED1;  //LEd状态灯
        }
        else if(key==2)
        {
            LED1=!LED1;  //LEd状态灯
            time_cnt=0;
            //电机状态改变
            MOTOR_DEV=!MOTOR_DEV;
            //电机状态
            motor_state=MOTOR_DEV;
            //补光灯
            LIGHT_DEV=!LIGHT_DEV;      
        }  
        
        //微信小程序开锁方式: 接收WIFI返回的数据
        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]);
            }
            
            //如果是下发了属性,判断是开锁还是关锁
            if(USART3_RX_CNT>5)
            {
                //使用字符串查找函数
                if(strstr((char*)&USART3_RX_BUFFER[5],"\"motor\":1"))
                {
                     LED1=0;  //亮灯
                     MOTOR_DEV=1; //开电机
                     motor_state=1;
                }
                else if(strstr((char*)&USART3_RX_BUFFER[5],"\"motor\":0"))
                {
                    LED1=1;  //灭灯
                    MOTOR_DEV=0; //关电机
                    motor_state=0;
                }
            }
           
            USART3_RX_CNT=0;
            USART3_RX_FLAG=0;
        }
              
        //定时与保持与微信小程序的同步--1秒一次
        delay_ms(10);
        time_cnt++;
        if(time_cnt==50)
        {
            time_cnt=0;
            
            //状态灯 --表示程序还活着
            LED2=!LED2;
            
            //读取光强度
            light=Read_BH1750_Data();
           
            //读取温湿度
            SHT3x_ReadData(&Humidity,&Temperature);
            humi=Humidity;
            temp=Temperature;
            
            //上传数据
             sprintf(mqtt_message,"{\"method\":\"report\",\"clientToken\":\"123\",\"params\":{\"temperature\":%f,\"humidity\":%f,\"motor\":%d,\"light\":%f}}",
            temp,humi,motor_state,light);
            MQTT_PublishData(POST_TOPIC,mqtt_message,0);
            //根据湿度自动灌溉
            if(humi<50.0)  //小于50自动灌溉
            {
                 motor_state=1; //电机状态更新
                 MOTOR_DEV=1;  //开电机
            }
        }
         
        //OLED显示屏
        if(page==0)
        {
            ShowTemperatureAndHumidity(temp,humi,light);
        }
        else if(page==1)
        {
            ESP8266_ShowPageTable();
        }
    }
}

使用特权

评论回复
40
自动化陈稳|  楼主 | 2021-5-31 22:03 | 只看该作者
6.1 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"
#include "oled.h"
#include "fontdata.h"
#include "bh1750.h"
#include "iic.h"
#include "sht3x.h"

/*
硬件连接方式:
ESP8266串口WIFI模块与STM32的串口3相连接。
PB10--RXD 模块接收脚
PB11--TXD 模块发送脚
GND---GND 地
VCC---VCC 电源(3.3V~5.0V)
OLED接线:
D0----SCK-----PB14
D1----MOSI----PB13
RES—复位(低电平有效)—PB12
DC---数据和命令控制管脚—PB1
CS---片选引脚-----PA7
微型直流电机:  PB8
紫光灯:        PB9
LED硬件连接: PB5 PE5
KEY硬件连接:PE3 PE4
*/

#define ESP8266_WIFI_AP_SSID  "CMCC-Cqvn"   //将要连接的路由器名称 --不要出现中文、空格等特殊字符
#define ESP8266_AP_PASSWORD "99pu58cb"     //将要连接的路由器密码


//腾讯物联网服务器的设备信息
#define MQTT_ClientID "6142CX41XESmartAgriculture"
#define MQTT_UserName "6142CX41XESmartAgriculture;12010126;HUA2G;1624271589"
#define MQTT_PassWord "a8aadebe9721f70e6f9e14fe56ff1d2b5cac9625fa1f96af2f0e0098597fe78b;hmacsha256"

//订阅与发布的主题
#define SET_TOPIC  "$thing/down/property/6142CX41XE/SmartAgriculture"  //订阅
#define POST_TOPIC "$thing/up/property/6142CX41XE/SmartAgriculture"  //发布


char mqtt_message[200];//上报数据缓存区
char OLED_ShowBuff[100];
u8 ESP8266_Stat=0;


/*
函数功能: 温湿度\光强度显示
*/
void ShowTemperatureAndHumidity(float temp,float humi,float light)
{
    sprintf(OLED_ShowBuff,"T: %.2f",temp);
        OLED_ShowString(40,16*0,16,OLED_ShowBuff);
    sprintf(OLED_ShowBuff,"H: %.2f%%",humi);
        OLED_ShowString(40,16*1,16,OLED_ShowBuff);
    sprintf(OLED_ShowBuff,"L: %.2f%%",light);
        OLED_ShowString(40,16*2,16,OLED_ShowBuff);
}

/*
函数功能: ESP8266显示页面
*/
void ESP8266_ShowPageTable(void)
{
    if(ESP8266_Stat)OLED_ShowString(0,16*0,16,"WIFI STAT:ERROR");
    else OLED_ShowString(0,16*0,16,"WIFI STAT:OK");

    //显示字符串
    sprintf((char*)OLED_ShowBuff,"%s",ESP8266_WIFI_AP_SSID);
    OLED_ShowString(0,16*1,16,OLED_ShowBuff);       
   
    sprintf((char*)OLED_ShowBuff,"%s",ESP8266_AP_PASSWORD);   
    OLED_ShowString(0,16*2,16,OLED_ShowBuff);   
}


int main()
{
   u32 time_cnt=0;
   u32 i;
   u8 key;
   u8 page=0;
   float temp=0;
   float humi=0;
   float light=0;
   u8 motor_state=0;
   float Humidity;
   float Temperature;
   
   delay_ms(1000);
   delay_ms(1000);
   
   LED_Init();
   KEY_Init();
   IIC_Init();
   
    //OLED初始化
   OLED_Init(0xc8,0xa1); //OLED显示屏初始化--正常显示;
     //清屏
   OLED_Clear(0);
   
   USART1_Init(115200);
   TIMER1_Init(72,20000); //超时时间20ms

   USART3_Init(115200);//串口-WIFI
   TIMER3_Init(72,20000); //超时时间20ms
   
   Init_SHT30();
   
   USART1_Printf("正在初始化WIFI请稍等.\n");
   
   if(ESP8266_Init())
   {
      ESP8266_Stat=1;
      USART1_Printf("ESP8266硬件检测错误.\n");  
   }
   else
   {
      //非加密端口
      USART1_Printf("WIFI:%d\n",ESP8266_STA_TCP_Client_Mode(ESP8266_WIFI_AP_SSID,ESP8266_AP_PASSWORD,"106.55.124.154",1883,1));
   }
   
    //2. MQTT协议初始化       
    MQTT_Init();
   
    //3. 连接腾讯云IOT服务器        
    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==1)
        {
            //清屏
            OLED_Clear(0);
            
            //翻页
            if(page>=1)
            {
                page=0;
            }
            else
            {
                 page++;
            }         
        
            LED1=!LED1;  //LEd状态灯
        }
        else if(key==2)
        {
            LED1=!LED1;  //LEd状态灯
            time_cnt=0;
            //电机状态改变
            MOTOR_DEV=!MOTOR_DEV;
            //电机状态
            motor_state=MOTOR_DEV;
            //补光灯
            LIGHT_DEV=!LIGHT_DEV;      
        }  
        
        //微信小程序开锁方式: 接收WIFI返回的数据
        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]);
            }
            
            //如果是下发了属性,判断是开锁还是关锁
            if(USART3_RX_CNT>5)
            {
                //使用字符串查找函数
                if(strstr((char*)&USART3_RX_BUFFER[5],"\"motor\":1"))
                {
                     LED1=0;  //亮灯
                     MOTOR_DEV=1; //开电机
                     motor_state=1;
                }
                else if(strstr((char*)&USART3_RX_BUFFER[5],"\"motor\":0"))
                {
                    LED1=1;  //灭灯
                    MOTOR_DEV=0; //关电机
                    motor_state=0;
                }
            }
           
            USART3_RX_CNT=0;
            USART3_RX_FLAG=0;
        }
              
        //定时与保持与微信小程序的同步--1秒一次
        delay_ms(10);
        time_cnt++;
        if(time_cnt==50)
        {
            time_cnt=0;
            
            //状态灯 --表示程序还活着
            LED2=!LED2;
            
            //读取光强度
            light=Read_BH1750_Data();
           
            //读取温湿度
            SHT3x_ReadData(&Humidity,&Temperature);
            humi=Humidity;
            temp=Temperature;
            
            //上传数据
             sprintf(mqtt_message,"{\"method\":\"report\",\"clientToken\":\"123\",\"params\":{\"temperature\":%f,\"humidity\":%f,\"motor\":%d,\"light\":%f}}",
            temp,humi,motor_state,light);
            MQTT_PublishData(POST_TOPIC,mqtt_message,0);
            //根据湿度自动灌溉
            if(humi<50.0)  //小于50自动灌溉
            {
                 motor_state=1; //电机状态更新
                 MOTOR_DEV=1;  //开电机
            }
        }
         
        //OLED显示屏
        if(page==0)
        {
            ShowTemperatureAndHumidity(temp,humi,light);
        }
        else if(page==1)
        {
            ESP8266_ShowPageTable();
        }
    }
}

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则