本网页已闲置超过3分钟,按键盘任意键或点击空白处,即可回到网页

基于Arduino的气候室系统
发布时间:2021-05-04
分享到:
基于Arduino的气候室系统
发布时间:2021-05-04
分享到:

该系统的设计和建造是为了在不同湿度条件下进行重量分析实验。

硬件组件:

  • 单片机
  • 旋转编码器
  • 发光二极管  64*128
  • 温度传感器  DHT22
  • 超声波喷雾器、造雾器
  • 冷却器
  • 加热床
  • 5mm发光二极管  绿、红色
  • 试验板
  • 通孔电阻器  150Ω
  • 电阻  100Ω
  • 开关  场效应晶体管
  • 热敏电阻  100kΩ
  • AC/DC电源  12 V
  • AC/DC变压器  12-24V  1A

系统描述、结构:

主体结构是一个二手水族箱,尺寸为49厘米×34厘米×25厘米,水族箱底部对应于腔室的后壁,气候室腔室的底部、后壁分别由3毫米的金属板代替(由于金属具有较高的热扩散率,当冷却或加热被激活时,金属板会加速室内冷热的分配);水族箱底部的玻璃被改造成了一扇门,可以打开和关闭水族箱。

气候室位于一个10厘米高的金属框架上,以便将带有湿度敏感电子设备的设备放置在系统外部。为了到达腔室的内部,在底板的结构中集成了金属管。

电子元件:三个放置在底部作为湿度源的超声波雾化器、两个在后壁中的珀耳帖元件、安装在用于调节温度的两个加热床。

为了使空气在整个腔室中循环,两个风扇被放置在前平面的顶部。

(包括控制气候条件的组件示意图)

系统电路、连接:

所有的电子设备都装在机器的顶部。

Arduino微控制器的控制信号(5V)驱动小型MOSFETs,然后将信号(12V)转发给大功率MOSFETs,同时直接触发风扇。在后一种情况下,来自微控制器的信号使用脉宽调制来调节风扇的每分钟转数(750-3000转/分)。大功率场效应晶体管由电源适配器供电,用于切换后续设备,如珀耳帖元件、加热床和雾化器。

在喷雾器的电路中,两个变压器连接在电源和大功率场效应晶体管之间,以将电压从12V (30A)降低到24V (1A)。

热敏电阻、显示器、编码器和T/RH传感器直接由微控制器的电源供电,微控制器本身由电源适配器供电。

(电路图)

程序设计:

首先,使用旋转编码器确定30-100%湿度之间的理想相对湿度水平。随着每次顺时针旋转,数值变为+5,逆时针旋转-5,按下确认显示屏上显示的数值为所需数值(我们可以仅在室内开启喷雾器来增加湿度,使其不低于周围环境的数值)。

然后将设定值与室内由DHT22测量的实际相对湿度水平进行比较。如果测得的水平较低,喷雾器就会打开以湿润空气。风扇持续运转以确保空气循环,让水滴分布在整个室内。当达到期望的湿度水平时,继续读取实际湿度水平,而喷雾器保持关闭。

程序流程图:

使用Arduino Uno R3来处理气候控制。

湿度代码(用于处理喷雾器的切换,以将稳定的湿度条件保持在所需的水平):

// 加载库
#include "DHT.h"
#include "U8glib.h"
U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_NONE | U8G_I2C_OPT_DEV_0);

//设置温度/湿度传感器的引脚并指定类型,给出输出字符串
#define DHTPIN 2
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);
char str [10];

//硬件引脚
const int Fog = 3; //喷雾器
const int Fan = 6; //空气循环用CPU风扇
const int OK = 7;  //旋转编码器推送
const int CCW = 8; //逆时针旋转编码器
const int CW = 9;  //顺时针旋转编码器

//变量
int ack = 0;
int RH_set = 35; /设置起始值
int SET = 0;
int Direction = 0;
boolean T_condition = true;
boolean RH_condition = true;
long previousMillis = 0;
long interval = 2000;

void setup()
{
  pinMode(Fog, OUTPUT);
  pinMode(Fan, OUTPUT);
  pinMode(OK, OUTPUT);
  pinMode(CCW, OUTPUT);
  pinMode(CW, OUTPUT);

  digitalWrite(Fog, LOW);
  digitalWrite(OK, HIGH);
  digitalWrite(CCW, HIGH);
  digitalWrite(CW, HIGH);

  Serial.begin(9600);
  dht.begin();
  
  // 在OLED显示屏上显示起始页;延迟1.5s
  u8g.firstPage();
  do
  {
    u8g.setFont(u8g_font_helvB14);
    u8g.drawStr(10, 20, "Climate");
    u8g.drawStr(10, 40, "Chamber");
  } while (u8g.nextPage());

  delay(1500);
}

void loop()
{
  if (SET == 0)
  {
    float T = dht.readTemperature();
    float RH = dht.readHumidity();
    
    // 在OLED显示屏上显示设置菜单
    u8g.firstPage();
    do
    {
      u8g.setFont(u8g_font_helvB08);
      u8g.drawStr(10, 20, "Set Humidity:");
      u8g.setPrintPos(20, 40);
      u8g.print(RH_set);
      u8g.drawStr(40, 40, "%");
    } while (u8g.nextPage());
    delay(100);
    
    
    while (RH_condition)
    {
      // 当顺时针编码为+5时,将上限设置为100
      if (digitalRead(CW) == LOW)
      {
        RH_set = RH_set + 5;
        if (RH_set > 100)
        {
          RH_set = 100;
        }
        
        // 在OLED显示屏上显示数值变化
        u8g.firstPage();
        do
        {
          u8g.setFont(u8g_font_helvB08);
          u8g.drawStr(10, 20, "Set Humidity:");
          u8g.setPrintPos(20, 40);
          u8g.print(RH_set);
          u8g.drawStr(40, 40, "%");
        } while (u8g.nextPage());
        delay(100);
      }
      
      // 当逆时针旋转编码器为-5时,将下限设置为30
      if (digitalRead(CCW) == LOW)
      {
        RH_set = RH_set - 5;
        if (RH_set < 30)
        {
          RH_set = 30;
        }
        
        // 在OLED显示屏上显示数值变化
        u8g.firstPage();
        do
        {
          u8g.setFont(u8g_font_helvB08);
          u8g.drawStr(10, 20, "Set Humidity:");
          u8g.setPrintPos(20, 40);
          u8g.print(RH_set);
          u8g.drawStr(40, 40, "%");
        } while (u8g.nextPage());
        delay(200);
      }
      if (digitalRead(OK) == LOW)
      {
        delay(100);
        RH_condition = false;
      }
    }
    
    // 确认设置为不重复此过程
    SET = 1;
  }
  
  //每2秒钟通过DHT22连续读取实际情况:
  //如果当前时间和上次读取DHT22的时间之间的差异大于您希望读取它的时间间隔->读取DHT22
  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis > interval)
  { 
    // 保存您上次阅读DHT22的时间
    previousMillis = currentMillis;
    
    float RH = dht.readHumidity();
    float T = dht.readTemperature();
    
    // 在OLED显示屏上显示DHT22读数
    u8g.firstPage();
    do
    {
      float T = dht.readTemperature();
      float RH = dht.readHumidity();
      u8g.setFont(u8g_font_helvB08);
      u8g.drawStr( 2, 20, "Temperature:");
      u8g.setPrintPos(80, 20);
      u8g.print(T);
      u8g.drawStr( 110, 20, "*C");
      u8g.drawStr( 3, 50, "Humidity:");
      u8g.setPrintPos(80, 50);
      u8g.print(RH);
      u8g.drawStr( 112, 50, "%");
    } while (u8g.nextPage());
    
    //湿度控制:
    //如果湿度等于或高于设定值->喷雾器会关闭
    if (RH  >= RH_set)
    {
      delay(3000);
      if (RH >= RH_set)
      {
        digitalWrite(Fog, LOW);
        analogWrite(Fan, 180);
      }
    }
    
    //如果湿度低于设定值->喷雾器打开2秒;
    if (RH < RH_set)
    {
      delay(3000);
      if (RH < RH_set)
      {
        digitalWrite(Fog, HIGH);
        analogWrite(Fan, 180);
        delay(2000);
        digitalWrite(Fog, LOW);
      }
    }
  }
}

加入微信技术交流群

技术交流,职业进阶

关注与非网服务号

获取电子工程师福利

加入电路城 QQ 交流群

与技术大牛交朋友

讨论