🎀 文章作者:二土电子
🐸 期待大家一起学习交流!
一、功能简介
我们要实现的功能有以下几个
- 获取周围环境温湿度信息
- OLED显示温湿度
- 利用ESP-01S连接Wifi并连接OneNET平台
- 上报温湿度信息
二、OneNET固件烧写
在连接OneNET之前,我们先给我们的ESP-01S烧写固件,烧写工具和连接OneNET的固件,可以关注文末公众号私信获取。这里介绍一下烧写方法。
烧录固件我们需要用到USB-TTL,接线按照下表即可
表中并未说明3V3如何接线,是因为ESP-01S的3V3引脚不要接到USB-TTL的3V3,否则即使固件下载成功也无法正常使用!一定要注意!可以用一个单片机的3.3V引脚来供电,注意共地!
接好线后,打开固件烧录软件,按照下图配置,点击“START”等待完成即可。
烧录完成后,将ESP-01S的IO0引脚连接到高电平,重新上电,打开串口助手,发送“AT+CIPSTATUS”,末尾加换行回车。如果收到返回消息,说明烧写成功。
如果没有收到返回消息,可以先将之前的固件擦除,再重新烧录一次,如何擦除固件,可以关注文末公众号查看,会提供擦除固件所需的.bin文件。
三、配置OneNET平台
这里贴一下链接OneNET多协议接入。进入链接后,新建产品,添加设备即可,值得注意的是,新建产品时要选择正确的联网方式
新建完产品后添加设备即可
至此,我们的OneNET配置完成。点击进入产品详情和设备详情,可以看到产品ID、设备ID以及自己自定义的鉴权信息。这些在后面会用到。
四、连接OneNET测试
可以先将ESP-01S连接到USB-TTL上,此时我们先用AT指令来测试一下能否上云。在测试时,会用到下面几条AT指令
- AT+CIPSTATUS
查询Wifi连接状态,0表示未连接,1表示正在接入。 - AT+CWJAP=ID,Password
连接到指定Wifi - AT+IOTCFG=设备ID,产品ID,鉴权信息
连接OneNET - AT+IOTSEND=0,temper,温度值
上报温度数据
如果连接成功,可以在OneNET平台看到设备上线,而且收到设备上报的信息。
五、程序设计
对于DHT11和OLED,这里只给出了部分程序,详细程序和原理,可至博主STM32外设系列查看。完整工程文件可关注文末公众号获取。
5.1 DHT11获取温湿度
/*
*==============================================================================
*函数名称:Med_Dht11_ReceOneByte
*函数功能:接收一帧数据
*输入参数:无
*返回值:一字节接收数据
*备 注:无
*==============================================================================
*/
u8 Med_Dht11_ReceOneByte (void)
{
u8 tempVar = 0; // 临时循环变量
u8 receData = 0; // 接收数据
for (tempVar = 0;tempVar < 8;tempVar ++)
{
receData <<= 1; // 左移
while (DHT11_SDA_DATA); // 等待高电平过去
while (!DHT11_SDA_DATA); // 等待54us的低电平过去
delay_us(40); // 延时30us之后判断是0还是1
// 如果30us之后依旧为高电平
if (DHT11_SDA_DATA)
{
receData |= 1; // 接收数据为1
}
else
{
receData |= 0; // 接收数据为0
}
}
return receData;
}
/*
*==============================================================================
*函数名称:Med_Dht11_GetData
*函数功能:获取温湿度数据
*输入参数:*temp:存储温度数据变量地址;*humi:存储湿度数据变量地址
*返回值:0:读取成功;1:读取失败
*备 注:无
*==============================================================================
*/
u8 Med_Dht11_GetData (u8 *temp, u8 *humi)
{
u8 buf[5];
u8 i;
Drv_Dht11_Reset(); // 复位DHT11
if(Drv_Dht11_ConnectCheck() == 0)
{
for(i = 0; i < 5; i++) //读取40位数据
{
buf[i] = Med_Dht11_ReceOneByte();
}
if((buf[0] + buf[1] + buf[2] + buf[3]) == buf[4])
{
*humi = buf[0];
*temp = buf[2];
}
}
else
{
return 1;
}
return 0;
}
5.2 OLED显示字符串
/*
*==============================================================================
*函数名称:Med_Oled_ShowString
*函数功能:显示一串字符串
*输入参数:x:横坐标;y:纵坐标;chr:要显示的字符串;Char_Size:大小(8/16)
*返回值:无
*备 注:无
*==============================================================================
*/
void Med_Oled_ShowString(u8 x,u8 y,u8 *chr,u8 Char_Size)
{
while (*chr!='\0')
{
Med_Oled_ShowChar(x,y,*chr,Char_Size);
x+=8;
if(x>120)
{
x=0;
y+=2;
}
chr++;
}
}
5.3 连接OneNET
u8 gString[500]; // 存储串口发送内容
/*
*==============================================================================
*函数名称:App_Esp8266_Init
*函数功能:ESP8266初始化
*输入参数:无
*返回值:无
*备 注:检测ESP8266连接状态,并连接指定WIFI
*==============================================================================
*/
void App_Esp8266_Init (void)
{
// 连接指定WIFI
Med_Oled_ShowString(0,2,"Connect Wifi...",8); //在OLED上显示字符串
sprintf((char*)gString,"AT+CWJAP=%s,%s\r\n",WIFINAME,WIFIPASSWORD);
while (!Med_Esp8266_SendCmd(gString));
Med_Oled_ShowString(0,4,"Success!",8); //在OLED上显示字符串
delay_ms(1000);
delay_ms(1000);
}
/*
*==============================================================================
*函数名称:App_Esp8266_Connect_Onenet
*函数功能:连接OneNET
*输入参数:无
*返回值:无
*备 注:无
*==============================================================================
*/
void App_Esp8266_Connect_Onenet (void)
{
// 连接OneNET
Med_Oled_Clear(); // 清屏
Med_Oled_ShowString(2,7,"ertu 2023.10.26",8); // 在OLED上显示字符串
Med_Oled_ShowString(0,2,"Connect OneNET..",8); //在OLED上显示字符串
sprintf((char*)gString,"AT+IOTCFG=%s,%s,%s\r\n",DEVICEID,PRODUCTID,AUTH_INFOR);
while (!Med_Esp8266_SendCmd(gString));
Med_Oled_ShowString(0,4,"Success!",8); //在OLED上显示字符串
delay_ms(1000);
delay_ms(1000);
}
5.4 main函数
int main(void)
{
u8 temper = 0; // 存储温度
u8 humidity = 0; // 存储湿度
u8 string[10]; // 显示字符串
u8 dataStr[20]; // 上报数据使用的字符串
u8 dataSendFreCtrl = 0; // 数据上报频率控制
Med_Mcu_Iint(); // 系统初始化
App_Esp8266_Connect_Onenet(); // 连接OneNET
Med_Oled_Clear(); // 清屏
Med_Oled_ShowString(2,7,"ertu 2023.10.26",8); // 在OLED上显示字符串
Med_Oled_ShowCHinese16x16(10,1,"温度:"); // 显示一组汉字
Med_Oled_ShowCHinese16x16(10,4,"湿度:"); // 显示一组汉字
while(1)
{
Med_Dht11_GetData(&temper,&humidity); // 获取温湿度数据
// DHT11湿度测量范围在20%~90%,低于20%时,输出湿度为0
// 为了显示低于20%的情况,这里用英文提示,防止误认为湿度测量异常
// 针对超出90%的情况也作出了限制
if (humidity < 20 || humidity > 90)
{
Med_Oled_ShowString(60,4,"Out ",8); //在OLED上显示字符串
}
// printf("温度:%d 湿度:%d\r\n",temper,humidity);
// 显示温湿度
sprintf((char*)string,"%d",temper);
Med_Oled_ShowString(60,1,string,16);
if (humidity >= 20 && humidity <= 90)
{
sprintf((char*)string,"%d",humidity);
Med_Oled_ShowString(60,4,string,16);
Med_Oled_ShowString(76,4," %",16);
}
delay_ms(1000);
dataSendFreCtrl = dataSendFreCtrl + 1;
if (dataSendFreCtrl >= 5)
{
dataSendFreCtrl = 0;
// 上报数据
sprintf((char*)dataStr,"AT+IOTSEND=0,temper,%d\r\n",temper);
USART_Send(UART1,dataStr);
delay_ms(200);
sprintf((char*)dataStr,"AT+IOTSEND=0,humidity,%d\r\n",humidity);
USART_Send(UART1,dataStr);
}
}
}