系统实现的是运用一块STM32F103C8T6作为发射端节点,上面搭载NRF2401(2.4G)并连上温湿度模块,外加一块STM32F103C8T6作为接收端节点,上面搭上气体传感器,0.96寸OLED显示屏,NRF2401(2.4G)作为接收端,通过ESP8266WiFi模块上传阿里云,并在阿里云上面的IOT Studio 显示自己的数据,当然我也自己写了自己的js界面,显示在自己本地上面的浏览器上。整体功能显示基本完成,NRF2401(2.4模块)上已经实现,过程还是挺充实
也可以在自己上面阿里云上面通过物理模型实现数据的可视化web界面设置。
简易的实现自己的一系列功能时,可能你以为就实现了?其实还有自己实现的可以自己web端实现的功能,自己运用的node.js架构后台,然后运用阿里云上面的AMQP服务端订阅功能实现对数据的下发和显示
温湿度DHT117+无线通信模块作为远节点的温湿度结点(发射端)主函数代码实现:
通过传感器采集模块,在监测的周遭环境上由模值转化为数据,通过OUT管脚输出数据,同时交一个无线传输模块作为一个远节点,
(1)main.c
#include "stm32f10x.h"
#include "usart.h"
#include "delay.h"
#include "DTH117.h"
#include "sys.h"
#include "SPI_NRF.h"
#include
#include
#include
u8 status; //用于判断接收/发送状态
u8 txbuf[2]; //发送缓冲
u8 rxbuf[4];//接收缓冲
int i=0;
/*
*读取温湿度传感器DHT11的值,并用串口打印出来
*/
void clock_init(void);
u8 temp = 0,humi = 0;
int main(void)
{
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
SPI_NRF_Init();
delay_init();
DHT11_Init();
clock_init();
usart_init(115200); //初始化串口
printf("\r\n 这是一个 NRF24L01 无线传输实验 \r\n");
printf("\r\n 这是无线传输 主机端 的反馈信息\r\n");
printf("\r\n 正在检测NRF与MCU是否正常连接。。。\r\n");
/*检测NRF模块与MCU的连接*/
status = NRF_Check();
/*判断连接状态*/
if(status == SUCCESS)
printf("\r\n NRF与MCU连接成功!\r\n");
else
printf("\r\n NRF与MCU连接失败,请重新检查接线。\r\n");
while(1)
{
DHT11_Read_Data(&temp,&humi);
printf("\r\n 主机端 进入自应答发送模式\r\n");
NRF_TX_Mode();
txbuf[0]=temp;
txbuf[1]=humi;
status = NRF_Tx_Dat(txbuf);//这里只设置为发给进入接收模式的无线模块
/*
以下注释的代码是对无线通信模块相互收发一体模式,我在这里没有对接收端下发指令给接收端,所以
这部分我注释了,就是没有实现将这里模块实现最大程度上面的收发一体,仅仅是将一个作为发射端,一个
作为接收端
*/
// switch(status)
// {
// case MAX_RT:
// printf("\r\n 主机端 没接收到应答信号,发送次数超过限定值,发送失败。 \r\n");
// break;
//
// case ERROR:
// printf("\r\n 未知原因导致发送失败。 \r\n");
// break;
//
// case TX_DS:
// printf("\r\n 主机端 接收到 从机端 的应答信号,发送成功! \r\n");
// break;
// }
// printf("\r\n 主机端 进入接收模式。 \r\n");
// NRF_RX_Mode();
// status = NRF_Rx_Dat(rxbuf);
//
switch(status)
{
// case RX_DR:
// for(i=0;i<300;i++)
// {
// printf("\r\n 主机端 接收到 从机端 发送的数据为:%d \r\n",rxbuf[i]);
// txbuf[i] =rxbuf[i];
//
// }
// break;
case ERROR:
printf("\r\n 主机端 接收出错。 \r\n");
break;
}
}
}
// }
/**************************************************************************
函数名:void clock_init(void)
参数说明:无
返回值:无
函数作用:开启高速外部时钟,
ADCCLK设置为12MHZ, SYSCLK设置为72Mhz,PCLK1设置为36MHZ,PKLC2设置为72mhz
***************************************************************************/
void clock_init(void)
{
RCC->CR = 0x1010000;
RCC->CFGR = 0x1DC402;
}
(2).无线通信模块(管脚定义)SPI_NRF.c
/************************************************************
* 文件名 :SPI_NRF.c
* 描述 :SPI_NRF24L01+无线模块应用函数库
* 实验平台: STM32开发板
* 硬件连接:-----------------------------|
* | |
* | PA1 : NRF- CSN |
| PA5-SPI1-SCK : NRF -SCK |
| PA6-SPI1-MISO : NRF -MISO|
| PA7-SPI1-MOSI : NRF -MOSI|
| PA3 : NRF-IRQ |
| PA2 : NRF-CE |
* | |
* -----------------------------
* 管脚没有特别的要求需要这样的定义
**********************************************************************************/
#include "SPI_NRF.h"
#include "usart.h"
#include "delay.h"
u8 RX_BUF[RX_PLOAD_WIDTH]; //接收数据缓存
u8 TX_BUF[TX_PLOAD_WIDTH]; //发射数据缓存
u8 TX_ADDRESS[TX_ADR_WIDTH] = {0x34,0x43,0x10,0x10,0x01}; // 定义一个静态发送地址
u8 RX_ADDRESS[RX_ADR_WIDTH] = {0x34,0x43,0x10,0x10,0x01};
/*
* 函数名:SPI_NRF_Init
* 描述 :SPI的 I/O配置用
*/
void SPI_NRF_Init(void)
{
SPI_InitTypeDef SPI_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
/*使能GPIOB,GPIOD,复用功能时钟*/
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOE|RCC_APB2Periph_AFIO, ENABLE);
/*使能SPI1时钟*/
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);
/*配置 SPI_NRF_SPI的 SCK,MISO,MOSI引脚,GPIOA^5,GPIOA^6,GPIOA^7 */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用功能
GPIO_Init(GPIOA, &GPIO_InitStructure);
/*配置SPI_NRF_SPI的CE引脚,GPIOA^2和SPI_NRF_SPI的 CSN 引脚: NSS GPIOA^1*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2|GPIO_Pin_1;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/*配置SPI_NRF_SPI的IRQ引脚,GPIOA^3*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU ; //上拉输入
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* 这是自定义的宏,用于拉高csn引脚,NRF进入空闲状态 */
NRF_CSN_HIGH();
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; //双线全双工
SPI_InitStructure.SPI_Mode = SPI_Mode_Master; //主模式
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; //数据大小8位
SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low; //时钟极性,空闲时为低
SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge; //第1个边沿有效,上升沿为采样时刻
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; //NSS信号由软件产生
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_8; //8分频,9MHz
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; //高位在前
SPI_InitStructure.SPI_CRCPolynomial = 7;
SPI_Init(SPI1, &SPI_InitStructure);
/* Enable SPI1 */
SPI_Cmd(SPI1, ENABLE);
}
接收端接收的数据就是来自发射端上面的数据,通时自己在接收端上还实现了对MQ-3气体传感器的处理,同时自己在考虑这个数据的直观性还是用了一个OLED显示屏实现数据的客观处理。
(1)气体传感器ADC.c
#include "adc.h"
#include "delay.h"
#include "stm32f10x_adc.h"
//
//本程序只供学习使用,未经作者许可,不得用于其它任何用途
//All rights reserved
//
//初始化ADC
//这里我们仅以规则通道为例
//我们默认将开启通道0~3
void Adc_Init(void)
{
ADC_InitTypeDef ADC_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA |RCC_APB2Periph_ADC1, ENABLE ); //使能ADC1通道时钟
RCC_ADCCLKConfig(RCC_PCLK2_Div6); //设置ADC分频因子6 72M/6=12,ADC最大时间不能超过14M
//PA1 作为模拟通道输入引脚
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; //模拟输入引脚
GPIO_Init(GPIOA, &GPIO_InitStructure);
ADC_DeInit(ADC1); //复位ADC1,将外设 ADC1 的全部寄存器重设为缺省值
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; //ADC工作模式:ADC1和ADC2工作在独立模式
ADC_InitStructure.ADC_ScanConvMode = DISABLE; //模数转换工作在单通道模式
ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; //模数转换工作在单次转换模式
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; //转换由软件而不是外部触发启动
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //ADC数据右对齐
ADC_InitStructure.ADC_NbrOfChannel = 1; //顺序进行规则转换的ADC通道的数目
ADC_Init(ADC1, &ADC_InitStructure); //根据ADC_InitStruct中指定的参数初始化外设ADCx的寄存器
ADC_Cmd(ADC1, ENABLE); //使能指定的ADC1
ADC_ResetCalibration(ADC1); //使能复位校准
while(ADC_GetResetCalibrationStatus(ADC1)); //等待复位校准结束
ADC_StartCalibration(ADC1); //开启AD校准
while(ADC_GetCalibrationStatus(ADC1)); //等待校准结束
ADC_SoftwareStartConvCmd(ADC1, ENABLE); //使能指定的ADC1的软件转换启动功能
}
//获得ADC值
//ch:通道值 0~3
u16 Get_Adc(u8 ch)
{
//设置指定ADC的规则组通道,一个序列,采样时间
ADC_RegularChannelConfig(ADC1, ch, 1, ADC_SampleTime_239Cycles5 ); //ADC1,ADC通道,采样时间为239.5周期
ADC_SoftwareStartConvCmd(ADC1, ENABLE); //使能指定的ADC1的软件转换启动功能
while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC ));//等待转换结束
return ADC_GetConversionValue(ADC1); //返回最近一次ADC1规则组的转换结果
}
u16 Get_Adc_Average(u8 ch,u8 times)
{
u32 temp_val=0;
u8 t;
for(t=0;t<times;t++)
{
temp_val+=Get_Adc(ch);
Delay_Ms(5);
}
return temp_val/times;
}
(2).main.c
/*-----------------------------------------------------*/
/* 超纬电子STM32系列开发板 */
/*-----------------------------------------------------*/
/* 程序结构 */
/*-----------------------------------------------------*/
/*USER :包含程序的main函数,是整个程序的入口 */
/*HARDWARE :包含开发板各种功能外设的驱动程序 */
/*CORE :包含STM32的核心程序,官方提供,我们不修改 */
/*STLIB :官方提供的库文件,我们不修改 */
/*-----------------------------------------------------*/
/* */
/* 程序main函数,入口函数源文件 */
/* */
/*-----------------------------------------------------*/
#include "stm32f10x.h" //包含需要的头文件
#include "main.h" //包含需要的头文件
#include "delay.h" //包含需要的头文件
#include "usart1.h" //包含需要的头文件
#include "usart2.h" //包含需要的头文件
#include "timer1.h" //包含需要的头文件
#include "timer2.h" //包含需要的头文件
#include "timer3.h" //包含需要的头文件
#include "timer4.h" //包含需要的头文件
#include "wifi.h" //包含需要的头文件
#include "led.h" //包含需要的头文件
#include "mqtt.h" //包含需要的头文件
#include "key.h" //包含需要的头文件
#include "dht11.h" //包含需要的头文件
#include "oled.h"
#include "sys.h"
#include "adc.h"
#include "SPI_NRF.h"
int main(void)
{
Delay_Init(); //延时功能初始化
Usart1_Init(9600); //串口1功能初始化,波特率9600
Usart2_Init(115200); //串口2功能初始化,波特率115200
TIM4_Init(300,7200); //TIM4初始化,定时时间 300*7200*1000/72000000 = 30ms
LED_Init(); //LED初始化
OLED_Init();
Adc_Init();
SPI_NRF_Init();
WiFi_ResetIO_Init(); //初始化WiFi的复位IO
MQTT_Buff_Init(); //初始化接收,发送,命令数据的 缓冲区 以及各状态参数
AliIoT_Parameter_Init(); //初始化连接阿里云IoT平台MQTT服务器的参数
OLED_Clear();
OLED_Display_On();
OLED_ShowCHinese(40,0,0);
OLED_ShowCHinese(60,0,1);
OLED_ShowCHinese(80,0,2);
OLED_ShowCHinese(100,0,3);
//显示各个参数的中文
OLED_ShowCHinese(0,2,4);
OLED_ShowCHinese(18,2,5);
OLED_ShowString(35,2, ":",16);//显示温度中文
OLED_ShowCHinese(0,4,6);
OLED_ShowCHinese(18,4,7);
OLED_ShowString(35,4, ":",16);//显示温度中文
while(1) //主循环
{
/*--------------------------------------------------------------------*/
/* Connect_flag=1同服务器建立了连接,我们可以发布数据和接收推送了 */
/*--------------------------------------------------------------------*/
if(Connect_flag==1){
/*-------------------------------------------------------------*/
/* 处理发送缓冲区数据 */
/*-------------------------------------------------------------*/
if(MQTT_TxDataOutPtr != MQTT_TxDataInPtr){ //if成立的话,说明发送缓冲区有数据了
//3种情况可进入if
//第1种:0x10 连接报文
//第2种:0x82 订阅报文,且ConnectPack_flag置位,表示连接报文成功
//第3种:SubcribePack_flag置位,说明连接和订阅均成功,其他报文可发
if((MQTT_TxDataOutPtr[2]==0x10)||((MQTT_TxDataOutPtr[2]==0x82)&&(ConnectPack_flag==1))||(SubcribePack_flag==1)){
u1_printf("发送数据:0x%x\r\n",MQTT_TxDataOutPtr[2]); //串口提示信息
MQTT_TxData(MQTT_TxDataOutPtr); //发送数据
MQTT_TxDataOutPtr += BUFF_UNIT; //指针下移
if(MQTT_TxDataOutPtr==MQTT_TxDataEndPtr) //如果指针到缓冲区尾部了
MQTT_TxDataOutPtr = MQTT_TxDataBuf[0]; //指针归位到缓冲区开头
}
}//处理发送缓冲区数据的else if分支结尾
/*-------------------------------------------------------------*/
/* 处理接收缓冲区数据 */
/*-------------------------------------------------------------*/
if(MQTT_RxDataOutPtr != MQTT_RxDataInPtr){ //if成立的话,说明接收缓冲区有数据了
u1_printf("接收到数据:");
/*-----------------------------------------------------*/
/* 处理CONNACK报文 */
/*-----------------------------------------------------*/
//if判断,如果第一个字节是0x20,表示收到的是CONNACK报文
//接着我们要判断第4个字节,看看CONNECT报文是否成功
if(MQTT_RxDataOutPtr[2]==0x20){
switch(MQTT_RxDataOutPtr[5]){
case 0x00 : u1_printf("CONNECT报文成功\r\n"); //串口输出信息
ConnectPack_flag = 1; //CONNECT报文成功,订阅报文可发
break; //跳出分支case 0x00
case 0x01 : u1_printf("连接已拒绝,不支持的协议版本,准备重启\r\n"); //串口输出信息
Connect_flag = 0; //Connect_flag置零,重启连接
break; //跳出分支case 0x01
case 0x02 : u1_printf("连接已拒绝,不合格的客户端标识符,准备重启\r\n"); //串口输出信息
Connect_flag = 0; //Connect_flag置零,重启连接
break; //跳出分支case 0x02
case 0x03 : u1_printf("连接已拒绝,服务端不可用,准备重启\r\n"); //串口输出信息
Connect_flag = 0; //Connect_flag置零,重启连接
break; //跳出分支case 0x03
case 0x04 : u1_printf("连接已拒绝,无效的用户名或密码,准备重启\r\n"); //串口输出信息
Connect_flag = 0; //Connect_flag置零,重启连接
break; //跳出分支case 0x04
case 0x05 : u1_printf("连接已拒绝,未授权,准备重启\r\n"); //串口输出信息
Connect_flag = 0; //Connect_flag置零,重启连接
break; //跳出分支case 0x05
default : u1_printf("连接已拒绝,未知状态,准备重启\r\n"); //串口输出信息
Connect_flag = 0; //Connect_flag置零,重启连接
break; //跳出分支case default
}
}
//if判断,第一个字节是0x90,表示收到的是SUBACK报文
//接着我们要判断订阅回复,看看是不是成功
else if(MQTT_RxDataOutPtr[2]==0x90){
switch(MQTT_RxDataOutPtr[6]){
case 0x00 :
case 0x01 : u1_printf("订阅成功\r\n"); //串口输出信息
SubcribePack_flag = 1; //SubcribePack_flag置1,表示订阅报文成功,其他报文可发送
Ping_flag = 0; //Ping_flag清零
TIM3_ENABLE_30S(); //启动30s的PING定时器
TIM2_ENABLE_30S(); //启动30s的上传数据的定时器
TempHumi_State(); //先发一次数据
break; //跳出分支
default : u1_printf("订阅失败,准备重启\r\n"); //串口输出信息
Connect_flag = 0; //Connect_flag置零,重启连接
break; //跳出分支
}
}
//if判断,第一个字节是0xD0,表示收到的是PINGRESP报文
else if(MQTT_RxDataOutPtr[2]==0xD0){
u1_printf("PING报文回复\r\n"); //串口输出信息
if(Ping_flag==1){ //如果Ping_flag=1,表示第一次发送
Ping_flag = 0; //要清除Ping_flag标志
}else if(Ping_flag>1){ //如果Ping_flag>1,表示是多次发送了,而且是2s间隔的快速发送
Ping_flag = 0; //要清除Ping_flag标志
TIM3_ENABLE_30S(); //PING定时器重回30s的时间
}
}
//if判断,如果第一个字节是0x30,表示收到的是服务器发来的推送数据
//我们要提取控制命令
else if((MQTT_RxDataOutPtr[2]==0x30)){
u1_printf("服务器等级0推送\r\n"); //串口输出信息
MQTT_DealPushdata_Qs0(MQTT_RxDataOutPtr); //处理等级0推送数据
}
MQTT_RxDataOutPtr += BUFF_UNIT; //指针下移
if(MQTT_RxDataOutPtr==MQTT_RxDataEndPtr) //如果指针到缓冲区尾部了
MQTT_RxDataOutPtr = MQTT_RxDataBuf[0]; //指针归位到缓冲区开头
}//处理接收缓冲区数据的else if分支结尾
/*-------------------------------------------------------------*/
/* 处理命令缓冲区数据 */
/*-------------------------------------------------------------*/
if(MQTT_CMDOutPtr != MQTT_CMDInPtr){ //if成立的话,说明命令缓冲区有数据了
u1_printf("命令:%s\r\n",&MQTT_CMDOutPtr[2]); //串口输出信息
MQTT_CMDOutPtr += BUFF_UNIT; //指针下移
if(MQTT_CMDOutPtr==MQTT_CMDEndPtr) //如果指针到缓冲区尾部了
MQTT_CMDOutPtr = MQTT_CMDBuf[0]; //指针归位到缓冲区开头
}//处理命令缓冲区数据的else if分支结尾
}//Connect_flag=1的if分支的结尾
/*--------------------------------------------------------------------*/
/* Connect_flag=0同服务器断开了连接,我们要重启连接服务器 */
/*--------------------------------------------------------------------*/
else{
u1_printf("需要连接服务器\r\n"); //串口输出信息
TIM_Cmd(TIM4,DISABLE); //关闭TIM4
TIM_Cmd(TIM3,DISABLE); //关闭TIM3
WiFi_RxCounter=0; //WiFi接收数据量变量清零
memset(WiFi_RX_BUF,0,WiFi_RXBUFF_SIZE); //清空WiFi接收缓冲区
if(WiFi_Connect_IoTServer()==0){ //如果WiFi连接云服务器函数返回0,表示正确,进入if
u1_printf("建立TCP连接成功\r\n"); //串口输出信息
Connect_flag = 1; //Connect_flag置1,表示连接成功
WiFi_RxCounter=0; //WiFi接收数据量变量清零
memset(WiFi_RX_BUF,0,WiFi_RXBUFF_SIZE); //清空WiFi接收缓冲区
MQTT_Buff_ReInit(); //重新初始化发送缓冲区
}
}
}
}
/*-------------------------------------------------*/
/*函数名:采集温湿度,并发布给服务器 */
/*参 数:无 */
/*返回值:无 */
/*-------------------------------------------------*/
void TempHumi_State(void)
{
int humidity; //定义一个变量,保存湿度值
int temperature; //定义一个变量,保存温度值
int ch4;
u16 TVOC_AD;
int avalue;
char temp[256];
u8 status; //用于判断接收/发送状态
u8 txbuf[4]; //发送缓冲
u8 rxbuf[4];//接收缓冲
u8 i;
SPI_NRF_Init();
u1_printf("\r\n 正在检测NRF与MCU是否正常连接。。。\r\n");
status = NRF_Check();
/*等待接收数据*/
if(status == SUCCESS)
u1_printf("\r\n NRF与MCU连接成功!\r\n");
else
u1_printf("\r\n 正在检测NRF与MCU是否正常连接。。。\r\n");
u1_printf("\r\n 从机端 进入接收模式\r\n");
NRF_RX_Mode(); //这边的是在收
status = NRF_Rx_Dat(rxbuf);
/*判断接收状态*/
if(status == RX_DR)
{
u1_printf("\r\n 从机端 接收到 主机端 发送的数据 \r\n");
for(i=0;i<2;i++)
{
if(i%2==0)
{
u1_printf("\r\n 温度的数据为:%d \r\n",rxbuf[i]);
OLED_ShowNum(45,2,rxbuf[i],3,16);//显示温度的码值
temperature=rxbuf[i]; //定义一个变量,保存温度值
txbuf[i] =1;
}
else
{
u1_printf("\r\n 湿度的数据为:%d \r\n",rxbuf[i]);
OLED_ShowNum(45,4,rxbuf[i],3,16);//显示湿度的码值
humidity=rxbuf[i]; //定义一个变量,保存湿度值
txbuf[i] =1;
}
TVOC_AD=Get_Adc_Average(ADC_Channel_0,4);
OLED_ShowNum(0,6,TVOC_AD,4,16);//显示ADC的值
avalue=(float)TVOC_AD*2*(3.3/4095);//测量值是在没有气体的环境下测得,同时测得的模值在进行这样的运算下是一个小数,又应为是avalue是一个int类型,所以值为0
ch4=avalue;
u1_printf("%.3dV--这个是烟雾数据",ch4);
OLED_ShowNum(60,6,avalue,4,16);
}
}
// DHT11_Read_Data(&temperature,&humidity); //读取温湿度值
u1_printf("温度:%d 湿度:%d 甲醛:%d\r\n",temperature,humidity,ch4); //串口输出信息
sprintf(temp,"{\"method\":\"thing.event.property.post\",\"id\":\"203302322\",\"params\":{\"CurrentHumidity\":%d,\"Temperature\":%d,\"ch4\":%d},\"version\":\"1.0.0\"}",humidity,temperature,ch4); //构建回复湿度温度数据
MQTT_PublishQs0(P_TOPIC_NAME,temp,strlen(temp)); //添加数据,发布给服务器
}
1.如果对整体的代码还不是非常熟悉的可以看看超纬电子STM32系列课程。
2.wifi模块在用之前就需要烧录设置为station模式
3.wifi的频段设置为2.4G
5.代码运用的二个串口,串口1用来串口输出,串口二用来上传数据到服务器
6.需要改动的地方时
7.如果使用的是这个代码,阿里云上面的产品设计需要设置的连接方式是蜂窝模式。
这里是代码下载地点
这个是我其他博客里面的资料