K32W061开发板是一款面向智能照明、智能门锁、温控器、智能家居领域及无线传感网的开发板,它以超低功耗高性能的 Arm®Cortex®-M4 无线微控制器为内核,含有640KB片上 Flash、152KB SRAM 、128KB ROM,且含有 2.4GHz BLE5 和 IEEE 802.15.4 收发器。该开发板体型小巧,为便于扩展使用它配有Arduino 接口的转接板。
最初的设想是在该开发板的基础上设计一个可以无线通讯来传递数据的家居环境状态检测器,因初期在开发环境的构建上消耗了大量的时间,使得后续的开发时间相对紧张,为此只能调整设计的目标来实现一个基于模拟信号采集的状态检测器,其具体的功能为:
以OLED屏为显示器件,由于其采样I2C接口来工作,故十分节省I/O引脚。另外,为了配合A/D的数据采集,选取RTC来辅助进行采样时间点的标记。在需要时,利用RTC还可独立的以电子时钟来使用。
在以A/D来采集数据时,可配以相应的传感器来获取环境的状态信息。此外,可以串行通讯的方式将采集的数据存储到相应的文本文件中。
当初是将数字式传感器也纳入其中的,如以DHT22来检测温湿度、以BH1750检测光照强度、以BMP085来检测大气压等,无奈时间紧只好看时间紧可能的补上。
该检测器的整体构成如图1所示,其处理流程如图2所示。
图1整体构成
图2处理流程
界面形式:
记录格式:
程序设计:
详细内容参见以下介绍:
1. 开箱及开发环境构建
2.I/O口使用及OLED屏显示驱动
3.片内功能的使用
测试效果:
图3 主界面
图4 电子时钟
图5电位器模拟测试
图6火焰传感器检测
图7土壤湿度传感器
图6实际检测
经改进采用0.96'的双色屏替代了原0.91'的单色屏,新的显示效果如图7至图10所示。
图7 新界面
图8 RTC电子时钟与A/D采集
图9 光强检测
图10气压检测
0.96'显示屏的初始化函数为:
- void OLED_Init(void)
- {
- Write_IIC_Command(0xae);
- Write_IIC_Command(0x02);
- Write_IIC_Command(0x10);
- Write_IIC_Command(0x40);
- Write_IIC_Command(0x81);
- Write_IIC_Command(0xff);
- Write_IIC_Command(0xa1);
- Write_IIC_Command(0xc8);
- Write_IIC_Command(0xa6);
- Write_IIC_Command(0xa8);
- Write_IIC_Command(0x3f);
- Write_IIC_Command(0xd3);
- Write_IIC_Command(0x00);
- Write_IIC_Command(0xd5);
- Write_IIC_Command(0x80);
- Write_IIC_Command(0xd9);
- Write_IIC_Command(0xf1);
- Write_IIC_Command(0xda);
- Write_IIC_Command(0x12);
- Write_IIC_Command(0xdb);
- Write_IIC_Command(0x40);
- Write_IIC_Command(0x20);
- Write_IIC_Command(0x02);
- Write_IIC_Command(0x8d);
- Write_IIC_Command(0x14);
- Write_IIC_Command(0xa4);
- Write_IIC_Command(0xa6);
- Write_IIC_Command(0xaf);
- Write_IIC_Command(0xaf);
- OLED_Clear();
- }
读取光强的函数为:
- void Get_Sunlight_Value()
- {
- int dis_data=0;
- float temp;
- char i=0;
- unsigned int sd;
- Single_Write_BH1750(0x01);
- Single_Write_BH1750(0x10);
- SysTick_DelayTicks(180U);
- Multiple_Read_BH1750();
- for(i=0;i<3;i++) dis_data=BUF[0];
- dis_data=(dis_data <<8)+BUF[1];
- temp=(float)dis_data/1.2;
- sd=temp;
- OLED_ShowString(0,2,"Sunlight= lx",16);
- OLED_ShowNum(72,2,sd,5,16);
- }
读取温度的函数为:
- long bmp085ReadTemp(void)
- {
- BMP085_Start();
- BMP085_Send_Byte(BMP085_SlaveAddress);
- while(BMP085_Wait_Ack()){}
- BMP085_Send_Byte(0xF4);
- while(BMP085_Wait_Ack()){}
- BMP085_Send_Byte(0x2E);
- while(BMP085_Wait_Ack()){}
- BMP085_Stop();
- SysTick_DelayTicks(10U);
- return (long) Multiple_read(0xF6);
- }
读取气压的函数为:
- long bmp085ReadPressure(void)
- {
- long pressure = 0;
- BMP085_Start();
- BMP085_Send_Byte(BMP085_SlaveAddress);
- while(BMP085_Wait_Ack()){}
- BMP085_Send_Byte(0xF4);
- while(BMP085_Wait_Ack()){}
- BMP085_Send_Byte(0x34);
- while(BMP085_Wait_Ack()){}
- BMP085_Stop();
- SysTick_DelayTicks(10U);
- pressure = Multiple_read(0xF6);
- pressure &= 0x0000FFFF;
- return pressure;
- }
相应的关键处理程序如下:
- while (1)
- {
- if(GPIO_PinRead(GPIO, 0, 5)==0)
- {
- OLED_Clear();
- m=(m+1)%2;
- if(m==0)
- {
- OLED_ShowNum(10,0,date.year,2,16);
- OLED_ShowNum(34,0,date.month,2,16);
- OLED_ShowNum(58,0,date.day,2,16);
- OLED_ShowChar(26,0,'-',16);
- OLED_ShowChar(50,0,'-',16);
- }
- while(GPIO_PinRead(GPIO, 0, 5)==0);
- }
- RTC_GetDatetime(RTC, &date);
- if(t!=date.second)
- {
- if(d!=date.day)
- {
- OLED_ShowNum(10,0,date.year,2,16);
- OLED_ShowNum(34,0,date.month,2,16);
- OLED_ShowNum(58,0,date.day,2,16);
- }
- if(m==0)
- {
- OLED_ShowChar(26,0,'-',16);
- OLED_ShowChar(50,0,'-',16);
- OLED_ShowChar(26,2,':',16);
- OLED_ShowChar(50,2,':',16);
- OLED_ShowNum(10,2,date.hour,2,16);
- OLED_ShowNum(34,2,date.minute,2,16);
- OLED_ShowNum(58,2,date.second,2,16);
- PRINTF("%d:%d:%d- ", date.hour,date.minute,date.second);
- ADC_DoSoftwareTriggerConvSeqA(DEMO_ADC_BASE);
- while (!ADC_GetChannelConversionResult(DEMO_ADC_BASE, DEMO_ADC_SAMPLE_CHANNEL_NUMBER, &adcResultInfoStruct))
- {
- }
- PRINTF("ADC: %d\r\n", adcResultInfoStruct.result);
- OLED_ShowString(10,4,"CH1= ",16);//ch1
- OLED_ShowNum(60,4,adcResultInfoStruct.result,4,16);
- OLED_ShowString(10,6,"CH2= ",16);//ch2
- }
- if(m==1)
- {
- OLED_ShowString(10,0,"BMP085: ",16);
- OLED_ShowString(10,2,"BH1750: ",16);
- OLED_ShowString(10,4,"temp: ",16);
- OLED_ShowString(10,6,"humi: ",16);
- Get_Sunlight_Value();
- bmp085Convert();
- OLED_ShowNum(66,0,pressure/100,5,16);
- DHT11_Read_Data(&temperature1,&humidity1);
- OLED_ShowNum(66,4,temperature1,2,16);
- OLED_ShowNum(66,6,humidity1,2,16);
- }
- t=date.second;
- }
- }
此外,在上位机接收串口发送数据的情况下还可以如下的界面来显示检测数据。
图11 界面设计
图12 初始状态
图13 接受数据后
视频:
环境状态检测器的实现.mp4
改进方向:
后续的改进方向是增添新的数字式传感器检测及无线传输数据功能。