本文的开发项目由开发者发布在csdn博客(f l e)分享,该设计采用esp8266烧写机智云固件。并且esp8266与stm32进行通信,则stm32可以通过esp8266与机智云服务器进行数据交互,而机智云服务器可以和机智云app进行数据交互。为此,实现stm32通过esp8266可以与机智云app进行数据交互。
stm32作为mcu与传感器进行数据交互,得到传感器采集的数值,所以完成的是传感器和app的数据交互。由于本次实验增加了对光照强度的采集,所以又增加了一个三色rgb灯外设。通过机智云app可以调节rgb灯的光强,以此来模拟光照强度的变化。整个设计的传感器数据流向如下图所示:
另外,对于用机智云app调节rgb灯的光强的数据流向如下图:
01传感器的测试
本次设计利用stm32cubemx进行开发,代码设计过程分模块进行,分别编写测试用例验证各模块的功能,包括oled模块、按键模块、dht11模块、光敏电阻模块、rgb模块。1、oled模块① 接线:
②代码编写:
本次设计中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可以用于检测按键状态。对应的引脚为:
②代码编写:
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模块
①接线:
②代码编写:
由于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、光敏电阻模块
①接线:
②代码编写:
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模块
①接线:
②代码编写:
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灯被点亮。
02通过esp8266实现数据上传和数据回传
在进行数据上传与数据回传之前,首先进行用于打印数据的串口1的设置和用于stm32与esp8266通信的串口2。串口1:
串口1设置pa9和pa10分别作为tx和rx,波特率为115200,不使能中断。
串口2:
串口2设置pa2和pa3分别作为tx和rx,波特率为9600,使能中断。
1、数据上传:温湿度数据、关照强度数据
①主要代码
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收到的,两者一致,说明数据交互是正确的。2、数据回传: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 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上为同样的数值,说明数据交互正确。
03总 结
①通过这次设计接触了stm32cubemx这个软件,相比与之前的标准库,stm32cubemx生成的hal库不仅封装度更高,而且更有利于开发者进行快速开发,而且在本次实验中机智云生成的代码也是基于hal库的,这说明以后对于stm32来说,会越来越趋向于hal开发。②官网永远是对解决问题的最好地方,机智云的官方文档给了我极大帮助。
③esp8266的烧录对于供电要求十分苛刻,导致多次烧录都失败了,所以在制pcb的时候加上了esp8266的烧录接口,以及gpio的接地开关,还有复位电路。pcb扩展板图如下:
④stmrct6板的供电十分差,由于刚开始只是接了st-link进行供电,导致dht11和oled一起使用时dht11的vcc口只有2.6v,进而使得dht11通信一直不成功,这也说明了一切先从电源管理开始,确保供电没问题再查找软件问题。
如何选择LED电子显示屏型号
谷景电感技术助力无人机行业升级换代
再谈“软件定义汽车”,剖析SOAFEE的成绩、打法和目标
深圳福凯半导体荣获DEKRA德凯颁发CB CTF Stage 1认可实验室证书
如何用HFSS-API来设计指数渐变传输线?
基于机智云物联网平台的温湿度和光照强度获取
苹果不忘iPhone6等老机型
新款华硕飞行堡垒笔记本曝光,将首发AMD的移动标压处理器
消防物联网的特征有哪些?
区块链技术在智慧养老领域的现状及前景
IPv6仅仅是比ipv4增加了地址长度吗
LED屏幕与OLED屏幕之间的区别不仅仅只是相差一个字母
SMT贴片加工厂验收电路板时都会检查哪些内容
同轴电缆的概念及工作原理
中山力士乐叶片泵发生故障的原因都有哪些
新型光纤让3D电影不戴眼镜成为可能
荣耀V20背面设计曝光采用了全新的魅眼全视屏屏占比相比以往更高
PLC输入模块与主令电器电器类设备的连接
基于ADC的PDN 部署和布局布线
华为“GPU Turbo”大杀技加持,AI、速度双领先开启全新速度时代!