环境参数智能监测站设计(软件篇)

2023-10-09 17:10

本文主要是介绍环境参数智能监测站设计(软件篇),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

环境参数智能监测站设计(软件篇)

系统总体设计

本系统具有对环境的温度、湿度、光照、空气质量、土壤水分、雨情的检测和控制等功能。系统运用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.

这篇关于环境参数智能监测站设计(软件篇)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/174322

相关文章

Qt 设置软件版本信息的实现

《Qt设置软件版本信息的实现》本文介绍了Qt项目中设置版本信息的三种常用方法,包括.pro文件和version.rc配置、CMakeLists.txt与version.h.in结合,具有一定的参考... 目录在运行程序期间设置版本信息可以参考VS在 QT 中设置软件版本信息的几种方法方法一:通过 .pro

MyBatis设计SQL返回布尔值(Boolean)的常见方法

《MyBatis设计SQL返回布尔值(Boolean)的常见方法》这篇文章主要为大家详细介绍了MyBatis设计SQL返回布尔值(Boolean)的几种常见方法,文中的示例代码讲解详细,感兴趣的小伙伴... 目录方案一:使用COUNT查询存在性(推荐)方案二:条件表达式直接返回布尔方案三:存在性检查(EXI

安装centos8设置基础软件仓库时出错的解决方案

《安装centos8设置基础软件仓库时出错的解决方案》:本文主要介绍安装centos8设置基础软件仓库时出错的解决方案,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐... 目录安装Centos8设置基础软件仓库时出错版本 8版本 8.2.200android4版本 javas

如何确定哪些软件是Mac系统自带的? Mac系统内置应用查看技巧

《如何确定哪些软件是Mac系统自带的?Mac系统内置应用查看技巧》如何确定哪些软件是Mac系统自带的?mac系统中有很多自带的应用,想要看看哪些是系统自带,该怎么查看呢?下面我们就来看看Mac系统内... 在MAC电脑上,可以使用以下方法来确定哪些软件是系统自带的:1.应用程序文件夹打开应用程序文件夹

基于Python实现智能天气提醒助手

《基于Python实现智能天气提醒助手》这篇文章主要来和大家分享一个实用的Python天气提醒助手开发方案,这个工具可以方便地集成到青龙面板或其他调度框架中使用,有需要的小伙伴可以参考一下... 目录项目概述核心功能技术实现1. 天气API集成2. AI建议生成3. 消息推送环境配置使用方法完整代码项目特点

JavaScript实战:智能密码生成器开发指南

本文通过JavaScript实战开发智能密码生成器,详解如何运用crypto.getRandomValues实现加密级随机密码生成,包含多字符组合、安全强度可视化、易混淆字符排除等企业级功能。学习密码强度检测算法与信息熵计算原理,获取可直接嵌入项目的完整代码,提升Web应用的安全开发能力 目录

利用Python实现Excel文件智能合并工具

《利用Python实现Excel文件智能合并工具》有时候,我们需要将多个Excel文件按照特定顺序合并成一个文件,这样可以更方便地进行后续的数据处理和分析,下面我们看看如何使用Python实现Exce... 目录运行结果为什么需要这个工具技术实现工具的核心功能代码解析使用示例工具优化与扩展有时候,我们需要将

基于Python打造一个智能单词管理神器

《基于Python打造一个智能单词管理神器》这篇文章主要为大家详细介绍了如何使用Python打造一个智能单词管理神器,从查询到导出的一站式解决,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1. 项目概述:为什么需要这个工具2. 环境搭建与快速入门2.1 环境要求2.2 首次运行配置3. 核心功能使用指

Python实现word文档内容智能提取以及合成

《Python实现word文档内容智能提取以及合成》这篇文章主要为大家详细介绍了如何使用Python实现从10个左右的docx文档中抽取内容,再调整语言风格后生成新的文档,感兴趣的小伙伴可以了解一下... 目录核心思路技术路径实现步骤阶段一:准备工作阶段二:内容提取 (python 脚本)阶段三:语言风格调

使用Python实现表格字段智能去重

《使用Python实现表格字段智能去重》在数据分析和处理过程中,数据清洗是一个至关重要的步骤,其中字段去重是一个常见且关键的任务,下面我们看看如何使用Python进行表格字段智能去重吧... 目录一、引言二、数据重复问题的常见场景与影响三、python在数据清洗中的优势四、基于Python的表格字段智能去重