当前位置:网站首页>基于机智云平台的温湿度和光照强度获取
基于机智云平台的温湿度和光照强度获取
2022-07-25 09:22:00 【F l e】
本次设计采用esp8266烧写机智云固件。esp8266与stm32进行通信,则stm32可以通过esp8266与机智云服务器进行数据交互,而机智云服务器可以和机智云app进行数据交互,所以stm32通过esp8266可以与机智云app进行数据交互。stm32作为MCU与传感器进行数据交互,得到传感器采集的数值,所以完成的是传感器和app的数据交互。由于本次实验增加了对光照强度的采集,所以又增加了一个三色RGB灯外设。通过机智云app可以调节RGB灯的光强,以此来模拟光照强度的变化。整个设计的传感器数据流向如下图所示:
另外,对于用机智云app调节RGB灯的光强的数据流向如下图:
一、传感器的测试
本次设计利用STM32CubeMX进行开发,代码设计过程分模块进行,分别编写测试用例验证各模块的功能,包括oled模块、按键模块、dht11模块、光敏电阻模块、rgb模块。
1、oled模块
①接线:
| Stm32 | oled |
|---|---|
| 3.3V | VCC |
| GND | GND |
| PB13 | D0 |
| PB15 | D1 |
| PB4 | RES |
| PB3 | DC |
| GND | CS |
②代码编写:
本次设计中oled采用硬件SPI2驱动,STM32CubeMX的设计如下图:


利用STM32CubeMX生成的SPI主要代码如上所示。在生成的SPI代码上进一步编写oled.c和oled.h文件。
oled.c封装了以下的函数:
测试函数:
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_SPI2_Init();
OLED_Init();
OLED_ShowString(0, 0, "wait for set esp8266,press key1 to set esp8266 with AIRLINK_MODE");
}
③测试用例实验结果:
由上图可知,oled模块的显示函数能够正确显示。
2、按键模块
①接线:
KEY_R0接地,KEY_L0和KEY_L1可以用于检测按键状态。
对应的引脚为:
| KEY_R0 | PC11(利用单片机输出低电平) |
|---|---|
| KEY_L0 | PC10 |
| KEY_L1 | PB5 |
②代码编写:
STM32CubeMX设计如下:
PC11设置为输出模式,PC10和PB5设置为输入模式。
Key.c封装了以下函数:
void key_init(void)
{
HAL_GPIO_WritePin(KEY_COM_GND_GPIO_Port, KEY_COM_GND_Pin, GPIO_PIN_RESET);
}
void Test_key(void)
{
if(HAL_GPIO_ReadPin(KEY1_GPIO_Port, KEY1_Pin)==GPIO_PIN_SET)
{
OLED_ShowString(0,0,"key1_up");
}
else
{
OLED_ShowString(0,0,"key1_down");
}
if(HAL_GPIO_ReadPin(KEY2_GPIO_Port, KEY2_Pin)==GPIO_PIN_SET)
{
OLED_ShowString(0,10,"key2_up");
}
else
{
OLED_ShowString(0,10,"key2_down");
}
OLED_Refresh_Gram();
}
测试用例:
int main(void)
{
MX_GPIO_Init();
key_init();
while(1)
{
Test_key();
}
}
③测试用例实验结果:
由图中可以看出,按键一被按下时显示key1_down和key2_up,与理论相符。
3、dht11模块
①接线:
| Stm32 | Dht11 |
|---|---|
| 3.3V | VCC |
| GND | GND |
| PB0 | DAT |
②代码编写:
由于dht11的数据引脚有时需要作为输入,有时需要作为输出,所以不在STM32CubeMX设置。
Dht11.c主要封装了以下函数:
这里的us延时并没有使用定时器来产生,而是用系统时钟来实现:
void delay_us(uint32_t us)
{
uint32_t delay = (HAL_RCC_GetHCLKFreq() / 4000000 * us);
while (delay--)
{
;
}
}
测试用例:
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_SPI2_Init();
OLED_Init();
while(1)
{
Test_dht11();
}
void Test_dht11(void)
{
char txt[16];
while(1)
{
DHT11_Read_Data(&humidity_integer,&humidity_decimal,&temperature_integer,&temperature_decimal);
sprintf(txt, "temp:%d.%d", temperature_integer,temperature_decimal);
OLED_ShowString(0,0,txt);
sprintf(txt, "humi:%d.%d", humidity_integer,humidity_decimal);
OLED_ShowString(0,10,txt);
OLED_Refresh_Gram();
}
}
③测试用例实验结果:
由上图可以看出,温度为23.3℃,湿度为53.0%,湿度的小数为0,与理论相符。
4、光敏电阻模块
①接线:
| Stm32 | 5506 |
|---|---|
| 3.3V | VCC |
| GND | GND |
| PA0 | AO |
②代码编写:
STM32CubeMX设置ADC1的IN0如下:
Stm32Rct6的ADC是12位的,这里没有更改的选项,则ADC读取的最大值是2^12=4096。
这里采样时间Sampling Time选择1.5个周期。ADC采样时间 = (采样周期+12.5周期)* 1/ADC时钟频率,这里ADC采样时间=(1.5+12.5)*1/12 = 1.167us。
light_check5506.c主要封装以下函数:
void light_check5506_init(void)
{
HAL_ADCEx_Calibration_Start(&hadc1);
HAL_Delay(200);
}
uint32_t light_check5506_getinitvalue(void)
{
HAL_ADC_Start(&hadc1);
HAL_ADC_PollForConversion(&hadc1,50);//ÏÞʱ50ms
return HAL_ADC_GetValue(&hadc1);
}
uint32_t light_check5506_get0to100value(void)
{
//°µ-->ÁÁ£º0~100
uint32_t value;
value=light_check5506_getinitvalue();
value=4096-value;//ÔʼÊý¾ÝÊÇÔ½°µÊý¾ÝÔ½´ó
value=(value*100/4096);//»¯Îª0~100µÄÊý,±ØÐëÏȳËÒÔ100ÔÙ³ý£¬ÒòΪȫ²¿ÊÇÕûÊý
return value;
}
void Test_5506(void)
{
uint32_t value;
char txt[16];
while(1)
{
value=light_check5506_get0to100value();
sprintf(txt, "light(0-100):%d", value);
OLED_ShowString(0,0,txt);
OLED_Refresh_Gram();
}
}
测试用例:
main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_SPI2_Init();
MX_ADC1_Init();
OLED_Init();
light_check5506_init();
while(1)`
{
Test_5506();
}
}
③测试用例实验结果:
将ADC读取的值归一化到0~100后光照强度的数值为18。
5、rgb模块
①接线:
| Stm32 | rgb |
|---|---|
| GND | GND |
| PC6 | R |
| PC7 | G |
| PC8 | B |
②代码编写:
STM32CubeMX设置TIM8的三个通道如下:
计数周期Counter Period设置为255,这是为了便于查找RGB颜色表进行颜色设置,占空比Pulse设置为50%
Rgb.c封装了以下函数:
void rgb_init(void)
{
HAL_TIM_PWM_Start(&htim8,TIM_CHANNEL_1);
HAL_TIM_PWM_Start(&htim8,TIM_CHANNEL_2);
HAL_TIM_PWM_Start(&htim8,TIM_CHANNEL_3);
}
void Test_rgb(void)
{
rgb_setpwm(10.0,100.0,200.0);
}
void rgb_setpwm(uint8_t pwm_r,uint8_t pwm_g,uint8_t pwm_b)
{
__HAL_TIM_SET_COMPARE(&htim8, TIM_CHANNEL_1,pwm_r);
__HAL_TIM_SET_COMPARE(&htim8, TIM_CHANNEL_2,pwm_g);
__HAL_TIM_SET_COMPARE(&htim8, TIM_CHANNEL_3,pwm_b);
}
测试用例:
main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_SPI2_Init();
MX_TIM8_Init();
rgb_init();
OLED_Init();
while(1)`
{
Test_rgb();
}
}
③测试用例实验结果:
由上图可知RGB灯被点亮。
二、通过esp8266实现数据上传和数据回传
在进行数据上传与数据回传之前,首先进行用于打印数据的串口1的设置和用于stm32与esp8266通信的串口2。
串口1:

串口1设置PA9和PA10分别作为TX和RX,波特率为115200,不使能中断。
串口2:


串口2设置PA2和PA3分别作为TX和RX,波特率为9600,使能中断。
(一)数据上传------温湿度数据、关照强度数据
①主要代码
void userHandle(void)
{
DHT11_Read_Data( & humidity_integer, & humidity_decimal, & temperature_integer, & temperature_decimal);
currentDataPoint.valuehumidity = humidity_integer;
currentDataPoint.valueLight_intensity = light_check5506_get0to100value();
currentDataPoint.valueDHT11 = temperature_integer + 0.1 * temperature_decimal;
}
在userHandle(void)中添加温湿度数据的采集以及光照强度的读取。userHandle()是main函数中while循环的内容。
由左图可以看出,userHandle对于用户来说是最顶层的,数据在userHandle中采集,依次经过gizCheckReport判断是否上报当前状态的数据、gizDataPoints2ReportData完成用户区数据到上报型数据的转换、gizReportData将转换后的上报数据通过串口发送给 WiFi 模块。
②设计结果:
首先确保esp8266和手机都已经连接到同一个网络,这里用电脑作为这个网络。
由上图可知手机和esp8266已经连接上了电脑。机智云app连接上esp8266后得到上传来的数据:

Oled上的数据是stm32收集的,右边图的数据是app通过esp8266收到的,两者一致,说明数据交互是正确的。
(二)数据回传------RGB三数值
①主要代码
int8_t gizwitsEventProcess(eventInfo_t * info, uint8_t * gizdata, uint32_t len)
{
uint8_t i = 0;
dataPoint_t * dataPointPtr = (dataPoint_t *)gizdata;
moduleStatusInfo_t * wifiData = (moduleStatusInfo_t *)gizdata;
protocolTime_t * ptime = (protocolTime_t *) gizdata;
# if MODULE_TYPE
gprsInfo_t * gprsInfoData = (gprsInfo_t *)gizdata;
# else
moduleInfo_t * ptModuleInfo = (moduleInfo_t *) gizdata;
# endif
if ((NULL == info) || (NULL == gizdata))
{
return -1;
}
for (i=0; i < info->num; i++)
{
switch(info->event[i])
{
case EVENT_LED_R:
currentDataPoint.valueLED_R = dataPointPtr->valueLED_R;
GIZWITS_LOG("Evt:EVENT_LED_R %d\n", currentDataPoint.valueLED_R);
rgb_setpwm(currentDataPoint.valueLED_R, currentDataPoint.valueLED_G, currentDataPoint.valueLED_B);
break;
case EVENT_LED_G:
currentDataPoint.valueLED_G = dataPointPtr->valueLED_G;
GIZWITS_LOG("Evt:EVENT_LED_G %d\n", currentDataPoint.valueLED_G);
rgb_setpwm(currentDataPoint.valueLED_R, currentDataPoint.valueLED_G, currentDataPoint.valueLED_B);
break;
case EVENT_LED_B:
currentDataPoint.valueLED_B = dataPointPtr->valueLED_B;
GIZWITS_LOG("Evt:EVENT_LED_B %d\n", currentDataPoint.valueLED_B);
rgb_setpwm(currentDataPoint.valueLED_R, currentDataPoint.valueLED_G, currentDataPoint.valueLED_B);
break;
}
}
}
在gizwitsEventProcess中的EVENT_LED_R、EVENT_LED_G、EVENT_LED_B分别添加对对RGB三个PWM的赋值,赋值之后使其立即生效。
protocolIssuedProcess被 gizwitsHandle 调用,接收来自云端或 app端下发的相关协议数据。ACTION_CONTROL_DEVICE进行“控制型协议”的相关处理,gizDataPoint2Event根据协议生成“控制型事件”,并进行相应数据类型的转化转换,gizwitsEventProcess是位于数据回传过程中的最底层,根据已生成的“控制型事件”进行相应处理。
②设计结果:
首先确保esp8266和手机都已经连接到同一个网络,这里用电脑作为这个网络。
由上图可知手机和esp8266已经连接上了电脑。机智云app设置RGB三个PWM数值,得到oled上的数据为:

由上图可知,右图为app设置的三个PWM数值,左图再oled上为同样的数值,说明数据交互正确。
三、总结与体会
①通过这次设计接触了STM32CubeMX这个软件,相比与之前的标准库,STM32CubeMX生成的Hal库不仅封装度更高,而且更有利于开发者进行快速开发,而且在本次实验中机智云生成的代码也是基于Hal库的,这说明以后对于stm32来说,会越来越趋向于Hal开发。
②官网永远是对解决问题的最好地方,机智云的官方文档给了我极大帮助。
③esp8266的烧录对于供电要求十分苛刻,导致多次烧录都失败了,所以我在制pcb的时候加上了esp8266的烧录接口,以及GPIO的接地开关,还有复位电路。
④stmRct6板的供电十分差,由于我刚开始只是接了ST-LINK进行供电,导致dht11和oled一起使用时dht11的VCC口只有2.6V,进而使得dht11通信一直不成功,这也说明了一切先从电源管理开始,确保供电没问题再查找软件问题。
附录
1、PCB扩展板
PCB工程链接:
链接:https://pan.baidu.com/s/1mASqMcT1FdAu_I2DBkxMeg
提取码:xydq
2、代码
链接:https://pan.baidu.com/s/1fQRfchWXtGXmWRjT9O1fTw
提取码:jaam
边栏推荐
- How to deploy the jar package to the server? Note: whether the startup command has nohup or not has a lot to do with it
- Data preprocessing
- Numpy - Construction of array
- How to configure SSH after changing the computer
- 语音聊天app源码-钠斯网络源码出品
- 如何将其他PHP版本添加到MAMP
- cf #785(div2) C. Palindrome Basis
- 深入解读C语言随机数函数和如何实现随机数
- Job 7.15 shell script
- Indexes, views and transactions of MySQL
猜你喜欢

Install MySQL in Ubuntu and create new users

作业7.21 约瑟夫环问题与进制转换

Why use json.stringify() and json.parse()

对象数据如何转化成数组

Student management system (summary)

单例模式(Singleton)

Swagger2 shows that there is a problem with the get interface, which can be solved with annotations

基于人脸识别的树莓派门禁系统

【cf】Round 128 C. Binary String

OC--包装类和处理对象
随机推荐
[code source] daily question simple fields and
[HCTF 2018]admin
对象数据如何转化成数组
laravel 调用第三方 发送邮件 (php)
自定义 view 实现兑奖券背景[初级]
OC--初识
Redis string structure command
关于学生管理系统(注册,登录,学生端)
【代码源】 每日一题 素数之欢(bfs)
【代码源】每日一题 算的我头都大啦
Prim 最小生成树(图解)
[GYCTF2020]Node Game
cf #785(div2) C. Palindrome Basis
How to configure SSH after changing the computer
OC -- Foundation -- dictionary
The shortest path problem Bellman Ford (single source shortest path) (illustration)
[code source] daily question - queue
基于人脸识别的树莓派门禁系统
Basic network knowledge
Singleton mode