实用指南:基于单片机的花卉温室湿度与光照监测系统设计【附代码】
算法与建模 | 专注PLC、单片机毕业设计
✨ 擅长数据搜集与处理、建模仿真、程序设计、仿真代码、论文写作与指导,毕业论文、期刊论文经验交流。
✅ 专业定制毕业设计
✅ 具体问题能够私信或查看文章底部二维码
(1)
在核心控制单元的选型与系统架构设计方面,本系统旨在实现对花卉温室环境的精准监控,故而控制器的选择至关重要。设计初期不直接锁定某一款特定型号的单片机,而是需要从处理能力、功耗、I/O口资源以及成本等多个维度进行综合考量。常见的备选方案包括经典的51系列单片机、AVR系列以及性能更强的STM32系列。51系列单片机虽然成本低廉、资料丰富,但其运算速度相对较慢,且片内资源对于复杂的温室多点监测可能略显捉襟见肘;相比之下,STM32系列基于ARM Cortex-M内核,拥有丰富的外设接口和强大的数据处理能力,适合未来功能的扩展,例如增加无线传输模块或上位机通信。然而,考虑到本环境关键针对湿度与光照的基础监测与简单的继电器控制,且对实时性要求并非工业级苛刻,为了平衡系统复杂度与开发周期,最终的设计方案往往倾向于选择一款性价比较高、具有足够ADC(模数转换)通道或通用IO口的8位或32位微控制器。系统架构上,单片机作为主控核心,通过外围电路连接传感器模块、显示模块、报警模块以及执行机构驱动电路。电源部分必须设计稳定的5V与3.3V供电,以适应不同器件的电压需求,确保系统在温室高湿环境下能稳定长时间运行,避免因电源波动导致的复位或测量误差。
(2)
关于环境感知层的设计,重点在于湿度传感器与光照传感器的选型与电路搭建。针对湿度监测,市面上有电阻式、电容式以及集成数字式传感器。电阻式传感器受温度影响大,线性度较差;电容式响应快但电路复杂。考虑到温室环境的特殊性,设计中通常对比模拟电压输出型传感器与数字总线型传感器。模拟传感器要求单片机内部具备ADC或外接模数转换芯片,信号传输过程中易受干扰;而集成数字传感器(如DHT系列或SHT系列)内部集成了信号调理与标定,能直接借助单线或I2C总线输出数字温湿度值,具有更高的抗干扰能力和测量精度。在选型论证中,会优先考虑具备防水防尘能力的封装形式,以应对温室的水汽。对于光照监测,传统的光敏电阻虽然价格低廉,但其输出阻值随光强变化呈非线性,且一致性较差,需复杂的校准算法。设计中往往会对比光敏二极管与专用的数字环境光传感器。数字光传感器(如BH系列)能够直接输出勒克斯(Lux)单位的光照强度值,光谱响应特性接近人眼,且量程范围广,能够区分阴天、傍晚与正午的强光,更适合花卉生长对光照精度的要求。电路设计上,需加入滤波电容以滤除电源噪声,确保传感器内容的稳定性。
(3)
执行机构与人机交互界面的设计是系统实现自动化管理的关键。当监测到的湿度低于设定阈值或光照强度不足时,系统需要自动触发相应的补水或补光设备。这部分的电路设计核心在于弱电控制强电的隔离与驱动。单片机的IO口驱动能力有限,无法直接驱动大功率的水泵或植物生长灯,因此必须依据三极管驱动继电器或使用光耦隔离加可控硅的方案。设计中会详细论述继电器的选型,包括线圈电压、触点容量等,并加入续流二极管保护电路以防止感应电动势击穿驱动管。软件逻辑上,通过按键设定花卉生长所需的湿度上下限与光照阈值,这些参数应存储在单片机的EEPROM或外部存储芯片中,防止掉电丢失。显示部分,为了在光照强烈的温室中依然清晰可读,通常对比LCD液晶显示屏与高亮度的LED数码管或OLED屏幕。OLED屏幕虽然功耗低、视角广,但LCD1602或12864在显示多行字符(如同时呈现湿度、光照、设定值)方面更具优势。报警电路则采用有源蜂鸣器配合LED指示灯,当环境参数严重超标时发出声光报警,提醒管理人员介入。
#include
#include
// Define Types
typedef unsigned char u8;
typedef unsigned int u16;
// Hardware Definitions
sbit SENSOR_A = P1^0; // Example: Human Body Sensor or Gas Sensor DO
sbit SENSOR_B = P1^1; // Example: Light Sensor DO
sbit RELAY_1 = P2^0; // Actuator 1: Fan / Motor / Light
sbit RELAY_2 = P2^1; // Actuator 2: Valve / Alarm / Curtain Open
sbit BUZZER = P2^3; // Alarm Buzzer
sbit ADC_CS = P3^5; // ADC Chip Select (if using external ADC)
sbit ADC_CLK = P3^6;
sbit ADC_DAT = P3^7;
// Global Variables
u8 threshold_val = 120;
u8 current_val = 0;
u8 mode_flag = 0; // 0: Auto, 1: Manual
// Delay Function
void delay_ms(u16 ms) {
u16 i, j;
for(i = ms; i > 0; i--)
for(j = 110; j > 0; j--);
}
// Simulated ADC Read Function (Generic for SPI type ADC like ADC0832)
u8 adc_read(void) {
u8 i, dat = 0;
ADC_CS = 0;
ADC_CLK = 0;
// Start bit and config bits would go here
ADC_CLK = 1; ADC_CLK = 0; // Pulse
ADC_CLK = 1; ADC_CLK = 0;
for(i = 0; i < 8; i++) {
dat <<= 1;
ADC_CLK = 1;
if(ADC_DAT) dat |= 0x01;
ADC_CLK = 0;
}
ADC_CS = 1;
return dat;
}
// Logic Control Function
void system_logic() {
// Read sensors
current_val = adc_read();
// Check Sensors (Digital Input)
if(SENSOR_A == 1) {
// Example: Human detected or Gas Leak detected
delay_ms(50); // Debounce
if(SENSOR_A == 1) {
BUZZER = 0; // Turn on Alarm (Active Low)
RELAY_1 = 0; // Activate Fan/Light
}
} else {
BUZZER = 1; // Turn off Alarm
// Hysteresis logic for analog value
if(current_val < threshold_val - 10) {
RELAY_1 = 1; // Turn off Actuator
}
}
// Example: Light Dependent Logic or Curtain Logic
if(mode_flag == 0) { // Auto Mode
if(current_val > threshold_val) {
RELAY_2 = 0; // Action A (e.g., Close Curtain)
} else {
RELAY_2 = 1; // Action B (e.g., Open Curtain)
}
}
}
// Timer Initialization for PWM or Timing
void timer0_init() {
TMOD |= 0x01;
TH0 = 0xFC; // 1ms
TL0 = 0x18;
ET0 = 1;
TR0 = 1;
EA = 1;
}
// Main Routine
void main() {
// Initialization
RELAY_1 = 1;
RELAY_2 = 1;
BUZZER = 1;
timer0_init();
while(1) {
system_logic();
delay_ms(100);
}
}
// Interrupt Service Routine (e.g., for Timing or PWM generation)
void timer0_isr() interrupt 1 {
static u16 count = 0;
TH0 = 0xFC;
TL0 = 0x18;
count++;
if(count > 1000) { // 1 second interval
count = 0;
// Periodic tasks can be placed here
}
}

如有难题,可以直接沟通
浙公网安备 33010602011771号