本文主要是介绍环境参数智能监测站设计(软件篇),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
环境参数智能监测站设计(软件篇)
系统总体设计
本系统具有对环境的温度、湿度、光照、空气质量、土壤水分、雨情的检测和控制等功能。系统运用STM32F103C8T6作为最小系统的中央处理器。整个系统主要从硬件电路设计和软件程序设计两部分来实现。可以将环境监控系统的硬件分为几大模块进行设计,分别为:信号采集模块、主控制模块、人机互动模块。本系统设计用DS18B20、DHT11、光敏二极管、MQ-135对温度、湿度、光照、环境质量等参数进行采集。再把采集的数据输送到STM32F103C8T6中进行处理。处理后的信息输送到OLED上进行显示。STM32F103C8T6根据键盘输入的设置参数值进行对比和判断是否有参数超过设置的范围,如有参数超标就发出声响进行警报,把环境参数通过NRF24L01模块发送到终端上。
检测节点结构框图:
总程序流程图
本系统采用单片机作为主控制部分,主程序是一个无限循环的程序,通过keil开发环境下载到单片机中工作。系统开始工作时,主程序运行,先对系统的硬件进行初始化,然后判断是否有键盘摁下,运用键盘进行环境参数的设置,然后通过传感器采集环境中的温度、湿度、光照、有害气体的参数。在OLED上显示采集到的环境参数。在与我们所设置的环境参数进行比较看是否有参数超标。
总程序流程图:
DS18B20程序流程图
温度监控的子程序也是一个循环的程序。当单片机接上电之后,单片机向DS18B20传感器发出指令,DS18b20传感器采集环境中温度参数,把温度值传输到液晶显示屏上显示出来。同时在STM32中将采集的温度参数的实际值与我们设置的参数范围进行比较。如果实际的参数值在设置的范围内,则返回重新采集。如果不在范围之内就发出警报并把数值通过蓝牙传输到终端上,同时开启相应的设备控制温度,并返回重新采集数据。
DS18B20流程图:
DHT11程序流程图
湿度监控也是一个循环的子程序。当STM32通上电之后,STM32向DHT11发出采集指令,它就采集养殖舍内的湿度参数值,把该参数值传送到OLED上显示出来。同时在STM32中将采集的湿度参数的实际值与我们设置的参数范围进行比较。如果实际的参数值在设置的范围内,则返回重新采集。如果不在范围之内就发出警报并把数值通过蓝牙传输到终端上,同时开启相应的设备控制湿度,并返回重新采集数据。
DHT11流程图:
MQ-135程序流程图
有害气体监控的子程序也是一个循环的程序。当单片机接上电之后,单片机向MQ-135传感器发出指令,MQ-135传感器采集环境中有害气体浓度,把有害气体浓度值传输到液晶显示屏上显示出来。同时有害气体浓度值在单片机中与我们设定的参数浓度值进行对比是否在设定的浓度范围之内。如果在设定的范围之内,则返回重新采集数据。如果不在范围之内发出警报把数值通过NRF传输到终端上,提醒管理人员进行人工处理降低有害气体浓度,并返回重新采集数据。
MQ-135流程图:
光照强度程序流程图
当STM32通上电之后,STM32向光照传感器发出工作指令,其通过光敏电阻采集养殖舍内的光照参数,并把该参数值传送到OLED上显示出来。同时实际的光照与系统内设定的光照范围进行比较,看实际值在哪个范围内,系统会对不同的范围开启不同的灯光数值,并返回重新采集数值。
光照流程图:
NRF 程序流程图
监测终端上电,首先NRF检测配对,检测环境检测节点是否工作正常,随后进行环境参数采集,分析处理。
土壤水分程序流程图
土壤水分传感器,AD采集传感器采集的电压信号,公式计算可得土壤水分百分比,随即传输给监测终端,并在OLED显示信息。
雨情程序流程图
雨滴传感器采集雨情信息,同其他传感器类似,单片机AD采集电压信号,并通过NRF传输给监测终端,公式计算之后得雨情信息。
核心代码
检测节点主程序
#include "stm32f10x.h"
#include "bsp_led.h"
#include "bsp_GeneralTim.h"
#include "bsp_adc.h"
#include "OLED_I2C.h"
#include "delay.h"
#include "bsp_key.h"
#include "beep.h"
#include "nrf24l01.h"
#include "sys.h"
#include "bsp_usart.h"
#include "bsp_dht11.h"
#include "ds18b20.h"
#define uint unsigned int
#define uchar unsigned char
///
void num_char(uint x);
uchar adc1_num[ ]="12345";
uint ADC_ConvertedValueLocal[NOFCHANEL];
extern __IO uint16_t ADC_ConvertedValue[NOFCHANEL];
char *reverse(char *s)
{char temp;char *p = s; //p指向s的头部char *q = s; //q指向s的尾部while(*q)++q;q--;//交换移动指针,直到p和q交叉while(q > p){temp = *p;*p++ = *q;*q-- = temp;}return s;
}
// //检测到的传感器ID存数组
extern unsigned char DS18B20_ID[8][8];
extern unsigned char DS18B20_SensorNum;
int main(void)
{ char *string = my_itoa(12700);uchar TEMP[]="TEMP:";/*温度 ℃*/uchar HUM[]="HUM:"; /*湿度 %Rh*/uchar CDQ[]="CDQ:"; /*光强 lux*/uchar SHUM[]="SHUM:";/*土壤水分 %*/uchar PSI[]="PSI:";/*空气质量 ppm*/uchar RCD[]="RCD:";/*雨情 mm*/u8 rx_buf[40];u16 TEMP1=0,HUM1=0,CDQ1=0,SHUM1=0,PSI1=0,RCD1=0;int adc_A5_i,adc_A7_i,adc_A1_U,adc_B0_U;int duty_set=10,fre_set=100;int set_point=5000;float Temp;u8 num=0,i;SystemInit();NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);LED_GPIO_Config();//BEEP_Init();ADCx_Init();SPI2_Init();NRF24L01_Init();/* 高级定时器初始化 */GENERAL_TIM_Init(duty_set , fre_set);DelayInit();I2C_Configuration();OLED_Init();OLED_CLS();Key_GPIO_Config();pid_text_init();OLED_Fill(0xFF);//全屏点亮DelayMs(1000);OLED_Fill(0x00);//全屏灭DHT11_Data_TypeDef DHT11_Data;/* 配置Systick 为1us中断一次 */USART_Config();//初始化串口2/*初始化DT11的引脚*/DHT11_Init ();/*初始化DS18b20的引脚*/u8 DS18B20_Init();while(NRF24L01_Check()) //检测NRF24L01是否存在{GPIO_SetBits(GPIOC,GPIO_Pin_13); OLED_ShowStr(0,1,(unsigned char*)"NRF Error",1);OLED_ShowStr(0,2,(unsigned char*)"Please chect NRF",1);}NRF24L01_TX_Mode();while (DS18B20_Init()) //检测DS18B20是否存在{OLED_ShowStr(0,1,(unsigned char*)"Ds18B20 Error",1);}while(1){LED1_TOGGLE;num=DS18B20_Search_Rom(1);for(i=0;i<num;i++){TEMP1=DS18B20_Get_Temp1(i);}if( DHT11_Read_TempAndHumidity ( & DHT11_Data ) == SUCCESS){HUM1=DHT11_Data.humi_int;}if(NRF24L01_TxPacket(rx_buf)==TX_OK){GPIO_ResetBits(GPIOC,GPIO_Pin_13);}else{GPIO_SetBits(GPIOC,GPIO_Pin_13);DelayMs(100);GPIO_ResetBits(GPIOC,GPIO_Pin_13);DelayMs(100); }rx_buf[0]=TEMP1>>8;//温度rx_buf[1]=TEMP1;rx_buf[2]=HUM1>>8;//湿度rx_buf[3]=HUM1;rx_buf[4]=adc_B0_U>>8;//光照强度rx_buf[5]=adc_B0_U;rx_buf[6]=adc_A5_i>>8;//土壤水分rx_buf[7]=adc_A5_i;rx_buf[8]=adc_A7_i>>8;//空气质量rx_buf[9]=adc_A7_i;rx_buf[10]=adc_A1_U>>8;//雨情rx_buf[11]=adc_A1_U;adc_A5_i = ADC_ConvertedValue[0]*33000/4096;adc_A7_i = ADC_ConvertedValue[1]*33000/4096;adc_A1_U = ADC_ConvertedValue[2]*33000/4096;adc_B0_U = ADC_ConvertedValue[3]*33000/4096;///温度显示// string = my_itoa(TEMP1);OLED_ShowStr(0,0,TEMP,1);OLED_ShowStr(40,0,string,1);
///湿度显示//string = my_itoa(HUM1);OLED_ShowStr(0,1,HUM,1);OLED_ShowStr(40,1,string,1);///光强显示//// adc_A5_i=adc_A5_i*30.3/50; string = my_itoa(adc_B0_U); OLED_ShowStr(0,2,CDQ,1);OLED_ShowStr(40,2,string,1);
///土壤水分显示//
// adc_A7_i= adc_A7_i*30.3/50;string = my_itoa(adc_A5_i);//32991:最干燥 (32991-采集值)/32991=水分 %OLED_ShowStr(0,3,SHUM,1);OLED_ShowStr(40,3,string,1);///空气质量显示// 10--1000ppmstring = my_itoa(adc_A7_i); // OLED_ShowStr(0,4,PSI,1);OLED_ShowStr(40,4,string,1);///雨情显示// string = my_itoa(adc_A1_U);//32991:雨情最小即未下雨 (32991-采集值)/32991=雨情 %OLED_ShowStr(0,5,RCD,1);OLED_ShowStr(40,5,string,1);OLED_ShowStr(25,6,"First node",2);LED2_TOGGLE;}}
监测终端主程序
#include "sys.h"
#include "sysitck.h"
#include "led.h"
#include "nrf24l01.h"
#include "adc.h"
#include "OLED_I2C.h"
#include "beep.h"
#include "bsp_adc.h"
#include "bsp_GeneralTim.h"
#include "key.h"
#define uint unsigned int
#define uchar unsigned char
void num_char(uint x);
uchar adc1_num[ ]="12345";
uint ADC_ConvertedValueLocal[NOFCHANEL];
extern __IO uint16_t ADC_ConvertedValue[NOFCHANEL];
char *reverse(char *s)
{char temp;char *p = s; //p指向s的头部char *q = s; //q指向s的尾部while(*q)++q;q--;//交换移动指针,直到p和q交叉while(q > p){temp = *p;*p++ = *q;*q-- = temp;}return s;
}
// //检测到的传感器ID存数
int main(void)
{ char *string = my_itoa(12700);uchar TEMP[]="TEMP:";/*温度 ℃*/uchar HUM[]="HUM:"; /*湿度 %Rh*/uchar CDQ[]="CDQ:"; /*光强 lux*/uchar SHUM[]="SHUM:";/*土壤水分 %*/uchar PSI[]="PSI:";/*空气质量 ppm*/uchar RCD[]="RCD:";/*雨情 mm*/int adc_A5_i,adc_A7_i,adc_B0_U,adc_B1_U;int duty_set=10,fre_set=100;int m=0;//节点数int i=0;int T=0;u8 rx_buf[40];u16 TEMP1=0,HUM1=0,CDQ1=0,SHUM1=0,PSI1=0,RCD1=0;//u16 TEMP2=0,HUM2=0,CDQ2=0,SHUM2=0,PSI2=0,RCD2=0;//SystemInit();NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);LED_GPIO_Config();Key_GPIO_Config();NRF24L01_Init();adc_init();I2C_Configuration();OLED_Init();OLED_Fill(0xFF);delay_ms(1000);OLED_Fill(0x00);while(NRF24L01_Check()) //检测NRF24L01是否存在{GPIO_SetBits(GPIOC,GPIO_Pin_13); OLED_ShowStr(0,1,(unsigned char*)"NRF Error",1);OLED_ShowStr(0,2,(unsigned char*)"Please chect NRF",1);}while(1){ // key_scan();digitalToggle(LED3_GPIO_PORT,LED3_GPIO_PIN);delay_ms(10);digitalToggle(LED2_GPIO_PORT,LED2_GPIO_PIN);第一节点环境信息接收///TEMP1=rx_buf[0]<<8|rx_buf[1];//温度HUM1=rx_buf[2]<<8|rx_buf[3];//湿度CDQ1=rx_buf[4]<<8|rx_buf[5];//光照强度SHUM1=rx_buf[6]<<8|rx_buf[7];//土壤水分PSI1=rx_buf[8]<<8|rx_buf[9];//空气质量RCD1=rx_buf[10]<<8|rx_buf[11];//雨情第二节点环境信息接收///TEMP2=rx_buf[0]<<8|rx_buf[1];//温度HUM2=rx_buf[2]<<8|rx_buf[3];//湿度CDQ2=rx_buf[4]<<8|rx_buf[5];//光照强度SHUM2=rx_buf[6]<<8|rx_buf[7];//土壤水分PSI2=rx_buf[8]<<8|rx_buf[9];//空气质量RCD2=rx_buf[10]<<8|rx_buf[11];//雨情if(TEMP1>30|TEMP2>30){BEEP_Init();Sound(50);}if(HUM1>70|HUM2>70){BEEP_Init();Sound(50);}if(m==0){for(i=0;i<6;i++){OLED_ShowCN(18+i*16,0,i);//个人信息}for(i=0;i<4;i++){OLED_ShowCN1(26+i*16,2,i);//}for(i=0;i<3;i++){OLED_ShowCN2(36+i*16,4,i);//}OLED_ShowStr(24,6,"1605260141",2);}//第一个节点环境信息if(m==1) { NRF24L01_RX_Mode();///温度显示// string = my_itoa(TEMP1);OLED_ShowStr(0,0,TEMP,1);OLED_ShowStr(40,0,string,1);OLED_ShowCN3(90, 0, 0);///湿度显示// string = my_itoa(HUM1);OLED_ShowStr(0,1,HUM,1);OLED_ShowStr(40,1,string,1);OLED_ShowStr(90,1,"%Rh",1);///光照强度显示// string = my_itoa(CDQ1);OLED_ShowStr(0,2,CDQ,1);OLED_ShowStr(40,2,string,1);OLED_ShowStr(90,2,"lux",1);///土壤水分显示//string = my_itoa((32991-SHUM1)/32991.0*100);//32991:最干燥(32991-采集值)/32991=水分 %值显示OLED_ShowStr(0,3,SHUM,1);OLED_ShowStr(40,3,string,1);OLED_ShowStr(90,3,"%",1);///空气质量显示// string = my_itoa(990/32991.0*PSI1); //32991:最大采集电压 10-1000ppm 990/32991*采集电压值= ppmOLED_ShowStr(0,4,PSI,1);OLED_ShowStr(40,4,string,1);OLED_ShowStr(90,4,"ppm",1);///雨情显示//string = my_itoa((32991-RCD1)/32991.0*100);//32991:未下雨 (32991-采集值)/32991=雨情 %值显示OLED_ShowStr(0,5,RCD,1);OLED_ShowStr(40,5,string,1);OLED_ShowStr(90,5,"mm",1);OLED_ShowStr(25,6,"First node",2);}//第二个节点环境信息if(m==2) { NRF24L01_RX_Mode1();///温度显示// string = my_itoa(TEMP2);OLED_ShowStr(0,0,TEMP,1);OLED_ShowStr(40,0,string,1);OLED_ShowCN3(90, 0, 0);///湿度显示// string = my_itoa(HUM2);OLED_ShowStr(0,1,HUM,1);OLED_ShowStr(40,1,string,1);OLED_ShowStr(90,1,"%Rh",1);///光照强度显示// string = my_itoa((CDQ2));OLED_ShowStr(0,2,CDQ,1);OLED_ShowStr(40,2,string,1);OLED_ShowStr(90,2,"lux",1);///土壤水分显示//string = my_itoa((32991-SHUM2)/32991.0*100);OLED_ShowStr(0,3,SHUM,1);OLED_ShowStr(40,3,string,1);OLED_ShowStr(90,3,"%",1);///空气质量显示// string = my_itoa(990/32991.0*PSI2);OLED_ShowStr(0,4,PSI,1);OLED_ShowStr(40,4,string,1);OLED_ShowStr(90,4,"ppm",1);///雨情显示//string = my_itoa((32991-RCD2)/32991.0*100);OLED_ShowStr(0,5,RCD,1);OLED_ShowStr(40,5,string,1);OLED_ShowStr(90,5,"mm",1);OLED_ShowStr(25,6,"Second node",2);}if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_6)==0){delay_ms(20);if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_6)==0)m++;if(m>2)m=1;OLED_Fill(0x00);while(!GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_6));}if(NRF24L01_RxPacket(rx_buf)==0) {GPIO_ResetBits(GPIOC,GPIO_Pin_13);}}}
由于程序篇幅较长,这里不一一展示,后续会将完整代码上传此博客。
最后,大家对程序有什么疑问或建议均可留言,感谢大家支持!!!
环境参数智能监测站设计(硬件篇) 链接: link.
环境参数智能监测站设计(说明书篇)链接: link.
这篇关于环境参数智能监测站设计(软件篇)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!