亿迅智能制造网
工业4.0先进制造技术信息网站!
首页 | 制造技术 | 制造设备 | 工业物联网 | 工业材料 | 设备保养维修 | 工业编程 |
home  MfgRobots >> 亿迅智能制造网 >  >> Manufacturing Technology >> 制造工艺

智能地下室通风系统:Arduino 驱动的湿度自动控制

组件与物料

组件 说明 数量
Arduino Nano R3 主控制器 1
IO 扩展板 集成 1-Wire 转 I2C、继电器驱动、OLED 驱动、湿度传感器驱动 1
IO 扩展板套装 含上述模块 1

应用与在线服务

工具 说明
Arduino IDE 开发环境

项目简介

功能特性

智能地下室通风系统:Arduino 驱动的湿度自动控制

构建通风系统所需物料

接线图

智能地下室通风系统:Arduino 驱动的湿度自动控制

OLED 显示效果

智能地下室通风系统:Arduino 驱动的湿度自动控制

为何选择 IO 扩展板?

系统构建步骤

  1. Arduino Nano 连接 IO 扩展板烧录代码(6Pin 排针为软串口调试口,正式安装可不接)
  2. 修改代码中 ONEWIRE_TO_I2C_ROM 地址匹配你的 1-Wire 转 I2C 模块
  3. 连接 110VAC 给双风扇供电
  4. 外壳钻 7/16″ 和 9/16″ 孔安装 PG7/PG9 防水接头(PG7 进 12V 电源,PG9 出传感器/风扇线)
  5. 选定排气口安装风扇朝外吹,确保对侧进气口开放,关闭相邻通风口形成区域气流
  6. 室外湿度传感器引线通过现有通道引入室内,远离建筑物障碍物,校准对比气象数据
  7. 室内传感器安装在中心或重点防潮区域
  8. 所有线缆汇聚到控制箱,整理固定
  9. 测试验证:断开 Arduino 直连电脑手动控制继电器/风扇,确认无误后装箱密封
智能地下室通风系统:Arduino 驱动的湿度自动控制
智能地下室通风系统:Arduino 驱动的湿度自动控制
智能地下室通风系统:Arduino 驱动的湿度自动控制
智能地下室通风系统:Arduino 驱动的湿度自动控制
智能地下室通风系统:Arduino 驱动的湿度自动控制
智能地下室通风系统:Arduino 驱动的湿度自动控制
智能地下室通风系统:Arduino 驱动的湿度自动控制
智能地下室通风系统:Arduino 驱动的湿度自动控制
智能地下室通风系统:Arduino 驱动的湿度自动控制
智能地下室通风系统:Arduino 驱动的湿度自动控制

更新日志

2019/03/20 更新

系统在爬行空间运行数月零死机,热水器漏水导致相对湿度峰值 >95% 后,成功降至 50% 以下。持续有效工作!

智能地下室通风系统:Arduino 驱动的湿度自动控制

更换为 SH1106 1.3″ OLED 显示屏(更大易读),仅需将代码 ST10 改为 ST13,得益于 IO 扩展板固件更新。

智能地下室通风系统:Arduino 驱动的湿度自动控制

2019/09/12 更新

发布 v1.1 修复冷启动 OLED 白屏问题,爬行空间通风持续稳定运行中!

完整代码

Basement/Crawlspace Ventilation System (C/C++)

/* IO Expander
 * Basement/Crawlspace Ventilation System v1.1
 */
#include <math.h>
#include <SoftwareSerial.h>
#include <avr/wdt.h>
#include "IOExpander.h"

#define FAHRENHEIT
#define ONEWIRE_TO_I2C_ROM "i4s71"
#define INIT_OLED "st13;si;sc;sd"
#define HUMIDITY_SENSOR_INSIDE "s6t1"
#define HUMIDITY_SENSOR_OUTSIDE "s8t1"
#define FAN_ON "r1o"
#define FAN_OFF "r1f"
#define ABSOLUTE_DELTA_FAN_ON 1    // 室内绝对湿度 - 室外 >= 1 g/m³ 开风扇
#define ABSOLUTE_DELTA_FAN_OFF 0.5 // 差值 <= 0.5 关风扇
#define OUTSIDE_RELATIVE_FAN_ON 88  // 室外相对湿度 <= 88% 开风扇
#define OUTSIDE_RELATIVE_FAN_OFF 90 // 室外相对湿度 >= 90% 关风扇
#define MINIMUM_TEMPERATURE 15      // 室外温度 <= 15°C 间歇运行
#define FAN_ON_TIME (20*60*1000L)   // 20 分钟
#define FAN_OFF_TIME (20*60*1000L)  // 20 分钟

//#define SERIAL_DEBUG
#define SERIAL_TIMEOUT 5000

#ifdef SERIAL_DEBUG
SoftwareSerial swSerial(8,7);
#endif

struct HS {
  float temp;
  float relative;
  float absolute;
  bool error;
};

int led = 13;
bool init_oled = true;
long ontime, offtime;

#ifdef FAHRENHEIT
#define C2F(temp) CelsiusToFahrenheit(temp)
float CelsiusToFahrenheit(float celsius) {
  return ((celsius*9)/5)+32;
}
#else
#define C2F(temp) (temp)
#endif

void SerialPrint(const char* str, float decimal, char error) {
  Serial.print(str);
  if (error) Serial.print(F("NA"));
  else Serial.print(decimal, 1);
}

float DewPoint(float temp, float humidity) {
  float t = (17.625 * temp) / (243.04 + temp);
  float l = log(humidity/100);
  float b = l + t;
  return (243.04*b)/(17.625-b); // August-Roche-Magnus 近似
}

#define MOLAR_MASS_OF_WATER 18.01534
#define UNIVERSAL_GAS_CONSTANT 8.21447215

float AbsoluteHumidity(float temp, float relative) {
  // Buck (1981) 公式,精度约 0.1°C (-30~35°C)
  return (6.1121 * pow(2.718281828, (17.67 * temp) / (temp + 243.5)) * relative * MOLAR_MASS_OF_WATER) / ((273.15 + temp) * UNIVERSAL_GAS_CONSTANT);
}

void ReadHumiditySensor(HS* hs) {
  SerialCmd("sr");
  if (SerialReadFloat(&hs->temp) && SerialReadFloat(&hs->relative)) {
    hs->absolute = AbsoluteHumidity(hs->temp, hs->relative);
    hs->error = false;
  } else hs->error = true;
  SerialReadUntilDone();
}

void setup() {
  Serial.begin(115200);
#ifdef SERIAL_DEBUG
  swSerial.begin(115200);
#endif
  pinMode(led, OUTPUT);
  wdt_enable(WDTO_8S); // 8秒看门狗
  offtime = millis() - FAN_OFF_TIME;
}

void loop() {
  HS inside, outside;
  static bool fan = false;
  static bool cycle = false;
  static long last_time = -(60L * 1000L);

  Serial.println();
  if (SerialReadUntilDone()) {
    // 传感器每分钟读一次,防自热
    if (millis() - last_time > 60L * 1000L) {
      if (SerialCmdDone(HUMIDITY_SENSOR_INSIDE)) ReadHumiditySensor(&inside);
      if (SerialCmdDone(HUMIDITY_SENSOR_OUTSIDE)) ReadHumiditySensor(&outside);

      if (inside.error || outside.error) fan = false;
      else {
        if (fan) { // 运行中判断停止条件
          if (outside.relative >= OUTSIDE_RELATIVE_FAN_OFF || inside.absolute - outside.absolute <= ABSOLUTE_DELTA_FAN_OFF)
            cycle = fan = false;
          else {
            if (cycle && outside.temp <= MINIMUM_TEMPERATURE && millis() - ontime > FAN_ON_TIME) fan = false;
          }
          if (!fan) offtime = millis();
        } else { // 停止中判断启动条件
          if (outside.relative <= OUTSIDE_RELATIVE_FAN_ON && inside.absolute - outside.absolute >= ABSOLUTE_DELTA_FAN_ON)
            cycle = fan = true;
          if (cycle && outside.temp <= MINIMUM_TEMPERATURE)
            fan = (millis() - offtime > FAN_OFF_TIME) ? true : false;
          if (fan) ontime = millis();
        }
      }

      if (fan) SerialCmdDone(FAN_ON); else SerialCmdDone(FAN_OFF);

      if (SerialCmdNoError(ONEWIRE_TO_I2C_ROM)) {
        if (init_oled) { SerialCmdDone(INIT_OLED); init_oled = false; }
        // OLED 显示格式化指令
        SerialCmdDone("st13;sc;sf0;sa1;sd70,0,\"INSIDE\";sd127,0,\"OUTSIDE\";sf1;sa0;sd0,12,248,\""
#ifdef FAHRENHEIT
          "F"
#else
          "C"
#endif
          "\";sd0,30,\"%\";sf0;sd0,50,\"g/m\";sd20,46,\"3\";");
        SerialPrint("sf1;sa1;sd70,12,\"", C2F(inside.temp), inside.error);
        SerialPrint("\";sd70,30,\"", inside.relative, inside.error);
        SerialPrint("\";sd70,48,\"", inside.absolute, inside.error);
        SerialPrint("\";sd127,12,\"", C2F(outside.temp), outside.error);
        SerialPrint("\";sd127,30,\"", outside.relative, outside.error);
        SerialPrint("\";sd127,48,\"", outside.absolute, outside.error);
        Serial.print("\";");
        Serial.print("sf0;sa0;sd0,0,\"");
        if (fan) Serial.print("FAN"); else Serial.print("v1.1");
        Serial.println("\";sd");
        SerialReadUntilDone();
      } else init_oled = true;

      last_time = millis();
    }
    delay(1000);
  } else {
    // 通信故障闪烁 LED
    digitalWrite(led, HIGH); delay(500);
    digitalWrite(led, LOW); delay(500);
    init_oled = true;
  }
  wdt_reset(); // 喂狗
}

原理图

智能地下室通风系统:Arduino 驱动的湿度自动控制

制造工艺

  1. 基于 Arduino 与 Python 的可靠 RFID 考勤系统
  2. 基于 Arduino Uno 的人体检测救援机器人:传感器集成分步指南
  3. DIY 蓝牙控制 Arduino 间谍小车
  4. FlickMote:基于手势的智能家居红外遥控器
  5. DIY Arduino TV-B-Gone:万能关机遥控器
  6. 自制大尺寸LED主时钟带闹钟功能 — 12米外清晰可见
  7. SERENA:基于 Arduino Mega 2560 与 TFT 触摸屏的多级密码报警系统
  8. Arduino 自动浇水系统:定时 + 土壤湿度双模式,轻松养护盆栽
  9. 实时森林火灾监测系统:短信报警方案
  10. 基于 Arduino 与 Google Sheets 的实时 RFID 考勤系统
  11. 基于Arduino、Windows IoT与Azure云的高级跌倒检测系统
  12. 通风系统全解析:自然通风与机械通风、HVAC及高级监控应用