大棚环境监测系统"/>
基于arduino的农业大棚环境监测系统
基于arduino的农业大棚环境监测系统
注:本文系湛江市第十七中学星火创客团队及岭南师范学院物联网俱乐部原创部分参赛项目,转载请保留声明。
一、硬件准备
器材 | 数量 |
---|---|
arduino主板 | 一块 |
LCD1602 | 一块 |
IIC模块 | 一个 |
DHT11温湿度传感器(22or21也行) | 一个 |
光照强度传感器 | 一个 |
4×4按键 | 一块 |
有源蜂鸣器 | 一个 |
面包板(可有可无,有是最好的,接线方便) | 一块 |
杜邦线 | 若干 |
二、软件准备
开发环境 | 版本 |
---|---|
arduino IDE | 1.8.13(自己看着办) |
windows | 10(自己看着办) |
1、arduino IDE下载:
三、项目部分
注:本项目按照本人习惯来进行,谢谢谅解!
1、DHT11温湿度传感器测试
(1)接线
arduino引脚 | DHT11温湿度传感器引脚 |
---|---|
2 | data |
3.3v | vcc |
GND | GND |
(2)相关代码
#include "DHT.h"//自己看哪个数字引脚顺眼就定义那个
#define DHTPIN 2 // Digital pin connected to the DHT sensor
// Uncomment whatever type you're using!//自己用的什么类型自己选择,看着办。
#define DHTTYPE DHT11 // DHT 11
//#define DHTTYPE DHT22 // DHT 22 (AM2302), AM2321
//#define DHTTYPE DHT21 // DHT 21 (AM2301)DHT dht(DHTPIN, DHTTYPE);void setup() {Serial.begin(9600);Serial.println(F("DHTxx test!"));dht.begin();
}void loop() {// Wait a few seconds between measurements.delay(2000);// Reading temperature or humidity takes about 250 milliseconds!// Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)float h = dht.readHumidity();// Read temperature as Celsius (the default)float t = dht.readTemperature();// Read temperature as Fahrenheit (isFahrenheit = true)float f = dht.readTemperature(true);// Check if any reads failed and exit early (to try again).if (isnan(h) || isnan(t) || isnan(f)) {Serial.println(F("Failed to read from DHT sensor!"));return;}// Compute heat index in Fahrenheit (the default)float hif = dhtputeHeatIndex(f, h);// Compute heat index in Celsius (isFahreheit = false)float hic = dhtputeHeatIndex(t, h, false);Serial.print(F("Humidity: "));Serial.print(h);Serial.print(F("% Temperature: "));Serial.print(t);Serial.print(F("°C "));Serial.print(f);Serial.print(F("°F Heat index: "));Serial.print(hic);Serial.print(F("°C "));Serial.print(hif);Serial.println(F("°F"));
}
(3)效果图
2、光照强度传感器测试
(1)接线
arduino引脚 | 光照强度传感器引脚 |
---|---|
A0 | s |
3.3v | + |
GND | - |
(2)相关代码
//自己看哪个模拟输出引脚顺眼就定义那个
#define Sunshine A0 //定义AO 引脚 为 IO-A0
//#define DO 7 //定义DO 引脚 为 IO-7,如果接线为7,代码就定义为7void setup() {pinMode(Sunshine, INPUT);//定义A0为输入模式,将AO所测得的数据输入到计算机中
// pinMode(DO, INPUT);//定义DO为输入模式,将DO所测得的数据输入到计算机中Serial.begin(9600);/*使用串口与计算机通信,需要先使用Serial.begin() 初始化Arduino的串口通信功能*/
}void loop() {sunshine_detection();
}
//Sunshine值越高,光照强度值越小,Sunshine值越低,光照强度值越大void sunshine_detection(void){//串口返回测量数据Serial.print("Sunshine=");/*串口初始化完成后,我们便可以使用Serial.print() 或Serial.println() 向计算机发送信息了。*/Serial.println(analogRead(Sunshine));/*读取AO的数值。它可以将外部输入的模拟信号转换为芯片运算时可以识别的数字信号,从而实现读入模拟值的功能。模拟输入功能需要使用analogRead() 函数。*/
// Serial.print("|DO=");
// Serial.println(digitalRead(DO));/*读取DO的数值。返回值为获取到的信号状态,1为高电平,0为低电平。*/delay(2000);
}
(3)效果图
3、LCD1602和按键测试
(1)接线
arduino引脚 | LCD1602(这里已经接了一个IIC模块) |
---|---|
GND | GND |
5V | VCC |
A5 (orSCL) | SCL |
A4(orSDA) | SDA |
arduino引脚 | 4×4键盘 |
---|---|
3 | R1 |
4 | R2 |
5 | R3 |
6 | R4 |
7 | C1 |
9 | C2 |
10 | C3 |
11 | C4 |
(2)相关代码
#include <stdio.h>
#include <string.h>
#include<Keypad.h>
//LingShun lab
#include <Wire.h>
#include <LiquidCrystal_I2C.h> //引用I2C库//设置LCD1602设备地址,这里的地址是0x3F,一般是0x20,或者0x27,具体看模块手册
LiquidCrystal_I2C lcd(0x27, 16, 2);
/**********4*4矩阵按键**********/
#define KEY_ROWS 4 //4*4矩阵按键的列数
#define KEY_COLS 4 //4*4矩阵按键的行數
char keymap[KEY_ROWS][KEY_COLS] = { //设置按键模组{'1', '2', '3', 'A'},{'4', '5', '6', 'B'},{'7', '8', '9', 'C'},{'.', '0', '#', 'D'}
};
byte rowPins[KEY_ROWS] = {3, 4, 5, 6}; //0-3行 横向
byte colPins[KEY_COLS] = {7, 9, 10, 11}; //0-3列 列向
//创建一个KeyPad对象
Keypad keypad = Keypad(makeKeymap(keymap), rowPins, colPins, KEY_ROWS, KEY_COLS);String inputCode = ""; //暂存用户的按键字符串
bool acceptKey = true; //代表是否接受用户按键输入的字符,预设为“接受”void setup() {// put your setup code here, to run once:Serial.begin(9600); //初始化串口lcd.init(); // 初始化LCDlcd.backlight(); //}void loop() {// put your main code here, to run repeatedly:key_1();
}
void key_1(void) {char key = keypad.getKey(); //检测按键按下的值if (acceptKey && key != NO_KEY) { //如果当前接受按键信号,且按键值不为空if (key == 'A') {Serial.println(inputCode);lcd.clear();lcd.setCursor(0, 0); //设置显示指针lcd.print("change S"); //输出字符到LCD1602上lcd.setCursor(0, 1);lcd.print("sun:");inputCode = "";} else if (key == '#') { //这一个if的功能就是当按下“#”键时,就会少一个字符,相当于清除功能,但不是一次性全部清空。inputCode = inputCode.substring( 0 , inputCode.length() - 1 );lcd.clear();lcd.setCursor(0, 0); //设置显示指针lcd.print("change S"); //输出字符到LCD1602上lcd.setCursor(0, 1);lcd.print("sun:");lcd.print(inputCode);} else { //显示出输入的每一个字符inputCode += key;lcd.print(key);}}
}
(3)效果图
4、项目总体设计
(1)接线(其他的模块接线请参考上面的单独测试)
arduino引脚 | 有源蜂鸣器引脚(在这没有做单独的测试) |
---|---|
GND | GND |
3.3V | VCC |
I/O | 8(我这里定义的pin8) |
(2)相关代码
#include <stdio.h>
#include <string.h>
#include "DHT.h"
#include<Keypad.h>
//LingShun lab
#include <Wire.h>
#include <LiquidCrystal_I2C.h> //引用I2C库//dht_11说明
#define DHTPIN 2 // Digital pin connected to the DHT sensor
float Temp_Value, Humi_Value; //定义两个变量分别存储温度与湿度值// Uncomment whatever type you're using!
#define DHTTYPE DHT11 // DHT 11
//#define DHTTYPE DHT22 // DHT 22 (AM2302), AM2321
//#define DHTTYPE DHT21 // DHT 21 (AM2301)DHT dht(DHTPIN, DHTTYPE);//设置LCD1602设备地址,这里的地址是0x3F,一般是0x20,或者0x27,具体看模块手册
LiquidCrystal_I2C lcd(0x27, 16, 2);#define Home 0 //主界面,显示温度、湿度和光照强度
#define User_T 1 //对温度的监控阈值修改界面
#define User_H 2 //对湿度的监控阈值修改界面
#define User_S 3 //对光照强度的监控阈值修改界面
unsigned int Page = Home; //默认主界面
float Temp_Vchange = 27 ; //初始化的温度的监控阈值
float Humi_Vchange = 50 ; //初始化的湿度的监控阈值
float Sun_Vchange = 400 ; //初始化的光照强度的监控阈值/**********4*4矩阵按键**********/
#define KEY_ROWS 4 //4*4矩阵按键的列数
#define KEY_COLS 4 //4*4矩阵按键的行數
char keymap[KEY_ROWS][KEY_COLS] = { //设置按键模组{'1', '2', '3', 'A'},{'4', '5', '6', 'B'},{'7', '8', '9', 'C'},{'.', '0', '#', 'D'}
};
byte rowPins[KEY_ROWS] = {3, 4, 5, 6}; //0-3行 横向
byte colPins[KEY_COLS] = {7, 9, 10, 11}; //0-3列 列向
//创建一个KeyPad对象
Keypad keypad = Keypad(makeKeymap(keymap), rowPins, colPins, KEY_ROWS, KEY_COLS);String inputCode = ""; //暂存用户的按键字符串
bool acceptKey = true; //代表是否接受用户按键输入的字符,预设为“接受”//光照传感器说明
#define Sunshine A0 //定义AO 引脚 为 IO-A0
float sunshine;//
long last_time = 0;
//#define DO 7 //定义DO 引脚 为 IO-7,如果接线为7,代码就定义为7,用来检测元件工作正常//蜂鸣器定义
#define pinBuzzer 8 //管脚D8连接到蜂鸣器元件的基极//LCD1602显示模块
void lcd_1602(void) {long now = millis();if (now - last_time > 2000) { //每隔两秒就读取一次相关的数据并显示在LCD上last_time = now;dht_11();sunshine_detection();}if (Temp_Value > Temp_Vchange || Humi_Value < Humi_Vchange || sunshine > Sun_Vchange) { //当超过相关阈值就会发出警报,即蜂鸣器回发出声音digitalWrite(pinBuzzer, LOW);//输出LOW电平,发声}else {digitalWrite(pinBuzzer, HIGH);//输出HIGH电平,停止发声}lcd.setCursor(0, 0); //设置显示指针lcd.print("H:"); //输出湿度到LCD1602上lcd.print(Humi_Value);lcd.print(" ");lcd.print("T:"); //输出温度到LCD1602上lcd.print(Temp_Value);lcd.setCursor(0, 1);lcd.print("sun:"); //输出光照强度到LCD1602上lcd.print(sunshine);// delay(1000);
}void setup() {// put your setup code here, to run once:Serial.begin(9600); //初始化串口//dht11dht.begin();//光照传感器pinMode(Sunshine, INPUT);//定义A0为输入模式,将AO所测得的数据输入到计算机中// pinMode(DO, INPUT);//定义DO为输入模式,将DO所测得的数据输入到计算机中//Close the pinBuzzerpinMode(pinBuzzer, OUTPUT); //设置pinBuzzer脚为输出状态digitalWrite(pinBuzzer, HIGH);//lcd1602lcd.init(); // 初始化LCDlcd.backlight(); //设置LCD背景等亮}void loop() {// put your main code here, to run repeatedly:// lcd_1602();char key = keypad.getKey(); //检测按键按下的值switch (Page) {case Home:lcd_1602();if (acceptKey && key != NO_KEY) { //如果当前接受按键信号,且按键值不为空if (key == 'A') { //如果按下了"A"Page = User_T; //页面值设置为User_T,跳转到修改温度监控阈值的界面,再按下"D"键时就会显示修改的界面。lcd.clear();Temp_change();} else if (key == 'B') { //如果按下了"B"Page = User_H; //页面值设置为User_H,跳转到修改湿度监控阈值的界面,再按下"D"键时就会显示修改的界面。lcd.clear();Humi_change();} else if (key == 'C') { //如果按下了"C"Page = User_S; //页面值设置为User_S,跳转到修改光照强度监控阈值的界面,再按下"D"键时就会显示修改的界面。lcd.clear();Sun_change();}}break;case User_T:if (acceptKey && key != NO_KEY) { //如果当前接受按键信号,且按键值不为空if (key == 'D') { //按下"D"键时就会显示修改温度的界面Serial.println(inputCode);Temp_Vchange = inputCode.toFloat();Serial.println(Temp_Vchange);lcd.clear();Temp_change();inputCode = "";} else if (key == '#') { //这一个if的功能就是当按下“#”键时,就会少一个字符,相当于清除功能,但不是一次性全部清空。inputCode = inputCode.substring( 0 , inputCode.length() - 1 );lcd.clear();Temp_change();lcd.print(inputCode);} else if (key == 'A') { //按下"A"时就会返回主界面lcd.clear();inputCode = "";Page = Home;}else { //显示出输入的每一个字符inputCode += key;lcd.print(key);}}break;case User_H:if (acceptKey && key != NO_KEY) { //如果当前接受按键信号,且按键值不为空if (key == 'D') { //按下"D"键时就会显示修改湿度的界面Serial.println(inputCode);Humi_Vchange = inputCode.toFloat();Serial.println(Humi_Vchange);lcd.clear();Humi_change();inputCode = "";} else if (key == '#') { //这一个if的功能就是当按下“#”键时,就会少一个字符,相当于清除功能,但不是一次性全部清空。inputCode = inputCode.substring( 0 , inputCode.length() - 1 );lcd.clear();Humi_change();lcd.print(inputCode);} else if (key == 'B') { //按下"B"时就会返回主界面lcd.clear();inputCode = "";Page = Home;}else { //显示出输入的每一个字符inputCode += key;lcd.print(key);}}break;case User_S:if (acceptKey && key != NO_KEY) { //如果当前接受按键信号,且按键值不为空if (key == 'D') { //按下"D"键时就会显示修改光照强度的界面Serial.println(inputCode);Sun_Vchange = inputCode.toFloat();Serial.println(Sun_Vchange);lcd.clear();Sun_change();inputCode = "";} else if (key == '#') { //这一个if的功能就是当按下“#”键时,就会少一个字符,相当于清除功能,但不是一次性全部清空。inputCode = inputCode.substring( 0 , inputCode.length() - 1 );lcd.clear();Sun_change();lcd.print(inputCode);} else if (key == 'C') { //按下"C"时就会返回主界面lcd.clear();inputCode = "";Page = Home;}else { //显示出输入的每一个字符inputCode += key;lcd.print(key);}}break;}}//温湿度模块
void dht_11(void) {// Wait a few seconds between measurements.// Reading temperature or humidity takes about 250 milliseconds!// Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)Humi_Value = dht.readHumidity();// Read temperature as Celsius (the default)Temp_Value = dht.readTemperature();// Read temperature as Fahrenheit (isFahrenheit = true)// float f = dht.readTemperature(true);// Check if any reads failed and exit early (to try again).if (isnan(Humi_Value) || isnan(Temp_Value)) {Serial.println(F("Failed to read from DHT sensor!"));return;}// // Compute heat index in Fahrenheit (the default)// float hif = dhtputeHeatIndex(f, h);// // Compute heat index in Celsius (isFahreheit = false)// float hic = dhtputeHeatIndex(t, h, false);Serial.print(F("Humidity: "));Serial.print(Humi_Value);Serial.print(F("% Temperature: "));Serial.print(Temp_Value);Serial.println(F("°C "));// Serial.println(f);// Serial.print(F("°F Heat index: "));// Serial.print(hic);// Serial.print(F("°C "));// Serial.print(hif);// Serial.println(F("°F"));
}//光照强度模块
void sunshine_detection(void) {//串口返回测量数据sunshine = analogRead(Sunshine);Serial.print("Sunshine=");/*串口初始化完成后,我们便可以使用Serial.print() 或Serial.println() 向计算机发送信息了。*/Serial.println(sunshine);/*读取AO的数值。它可以将外部输入的模拟信号转换为芯片运算时可以识别的数字信号,从而实现读入模拟值的功能。模拟输入功能需要使用analogRead() 函数。*/// Serial.print("|DO=");// Serial.println(digitalRead(DO));/*读取DO的数值。返回值为获取到的信号状态,1为高电平,0为低电平。输出0证明元件工作正常,输出1证明元件工作失常*/// delay(2000);
}void Humi_change(void) {lcd.setCursor(0, 0); //设置显示指针lcd.print("change Hum_Value"); //输出字符到LCD1602上lcd.setCursor(0, 1); //设置显示指针lcd.print("H:"); //输出字符到LCD1602上
}void Temp_change(void) {lcd.setCursor(0, 0); //设置显示指针lcd.print("change Tem_Value"); //输出字符到LCD1602上lcd.setCursor(0, 1); //设置显示指针lcd.print("Temp_Value:"); //输出字符到LCD1602上
}void Sun_change(void) {lcd.setCursor(0, 0); //设置显示指针lcd.print("change Sun_Value"); //输出字符到LCD1602上lcd.setCursor(0, 1); //设置显示指针lcd.print("Sun_Value:"); //输出字符到LCD1602上
}
(3)效果讲解
a、温度监控阈值修改界面
b、湿度监控阈值修改界面
c、光照强度监控阈值修改界面
d、主界面显示参数界面
e、B站讲解视频:以后再补
四、总结
这一次的项目主要是学习一下各类传感器等原件的使用,最后通过自己的逻辑思维整合成一个比较有意义的小项目,希望对大家学习有所帮助,欢迎各位大佬批评指正或有什么建议可以在评论留言,谢谢!
更多推荐
基于arduino的农业大棚环境监测系统
发布评论