Умный контроллер вентиляторов AV-шкафа на Arduino Nano, DHT11 и реле
Компоненты и материалы
| Arduino Nano R3 | ×1 |
| Датчик температуры и влажности DHT11 (4 пина) | ×1 |
| Релейный модуль 5 В | ×1 |
О проекте
Мой AV-ресивер сильно грелся, поэтому перед летом решил добавить вентиляцию шкафа. Сначала искал 5-12 В источник на корпусе ресивера, включающийся только при его работе, но нашёл только внутри. Также хотел, чтобы вентиляторы работали ещё некоторое время после выключения, но подбор конденсаторов усложнял задачу.

Готовые термостатические вентиляторы на Amazon стоили >$30, а у меня уже были все детали: вентилятор, термодатчик, реле.


Написал скетч для Arduino Nano ($2), подключил DHT11 и реле — заработало отлично.

Нашёл старые ПК-вентиляторы (80 мм и 120 мм), крутящиеся от 5 В и потребляющие <200 мА, запитал от старого USB-зарядки. Добавил статусные светодиоды и пьезо-зумер для сигнализации перегрева. Всё поместилось в компактный корпус.



Светодиоды: верхний левый — питание (зелёный); нижний левый — темп. норма (зелёный); средний — вентиляторы включены (оранжевый); правый — перегрев (красный).

При включении контроллер проходит POST: проверяет вентиляторы, светодиоды, зумер.

Алгоритм работы
- Контроллер усредняет температуру за 30 секунд.
- Если > 95 °F (35 °C) — вентилятор включается на 5 минут.
- Если > 120 °F (49 °C) — звучит алärm, вентиляторы продолжают работать. Алärm повторяется каждые 30 сек до снижения температуры.
На практике вентиляторы включаются через ~2 мин после включения ресивера и работают всё время его работы. После выключения медиа-центра вентиляторы крутятся ещё минимум 5 мин. Алärm пока не срабатывал.
Улучшение: заменить Nano на ATtiny85, реле на MOSFET — меньше размеры и ШИМ-управление скоростью вентиляторов.
Исходный код (C/C++)
// Temperature controller for A/V Cabinet
// Fan controlled by 10A relay connected to 12v (PC) or 5v (USB) Fan
// Piezo alarm for overheating alert
int FANTEMP = 95; // Включение вентилятора (95°F ≈ 35°C)
int ALARMTEMP = 120; // Перегрев (120°F ≈ 49°C)
int FANLED = 2; // LED вентилятора
int TEMPOK = 3; // LED норма температуры
int ALARMLED = 4; // LED тревоги
int ALARMPIN = 7; // Пьезо-зумер
#define DHTPIN 8 // DHT датчик
int FANPIN = 9; // Реле вентилятора
#include "DHT.h"
#define DHTTYPE DHT11
DHT dht(DHTPIN, DHTTYPE);
const int numReadings = 10;
float avetemp = 0, temp = 0, checkdelay = 0;
void setup() {
Serial.begin(9600);
Serial.println("Temp Monitor Started");
dht.begin();
pinMode(FANPIN, OUTPUT);
pinMode(ALARMPIN, OUTPUT);
pinMode(ALARMLED, OUTPUT);
pinMode(FANLED, OUTPUT);
pinMode(TEMPOK, OUTPUT);
digitalWrite(FANPIN, HIGH); // Реле активное LOW
digitalWrite(FANLED, HIGH);
digitalWrite(ALARMLED, HIGH);
digitalWrite(TEMPOK, HIGH);
for (int x = 0; x < 5; x++) { tone(ALARMPIN, 220 * x, 75); delay(100); } // Тест зумера
Serial.print("Fan Test Started (5 Seconds) ");
for (int x = 0; x < 5; x++) { Serial.print("."); delay(1000); }
Serial.println("Done");
digitalWrite(FANPIN, LOW); digitalWrite(FANLED, LOW);
digitalWrite(ALARMLED, LOW); digitalWrite(TEMPOK, LOW);
noTone(ALARMPIN);
}
void loop() {
delay(2000);
temp = 0;
Serial.print("Realtime Temp: \t");
for (int x = 0; x < numReadings; x++) {
float f = dht.readTemperature(true); // Фаренгейты
Serial.print(f); Serial.print("\t");
temp += f;
delay(3000);
}
Serial.println();
avetemp = temp / numReadings;
Serial.print("Average Temp is "); Serial.println(avetemp);
if (isnan(temp)) { Serial.println("Failed to read from DHT sensor!"); return; }
// Аларм
if (avetemp > ALARMTEMP) {
digitalWrite(ALARMLED, HIGH);
Serial.print("Temperature is over "); Serial.print(ALARMTEMP); Serial.println(", Alarm is on");
for (int x = 0; x < 3; x++) {
tone(ALARMPIN, 660, 1000); delay(500);
tone(ALARMPIN, 440, 1000); delay(500);
}
noTone(ALARMPIN);
checkdelay = 30000; // 30 сек до следующей проверки
} else {
digitalWrite(ALARMLED, LOW);
Serial.print("Temperature is under "); Serial.print(ALARMTEMP); Serial.println(", Alarm is off");
checkdelay = 300000; // 5 мин
}
// Вентилятор
if (avetemp > FANTEMP) {
digitalWrite(FANPIN, HIGH); digitalWrite(FANLED, HIGH); digitalWrite(TEMPOK, LOW);
Serial.print("Temperature is over "); Serial.print(FANTEMP);
Serial.print(", Fan is on (for "); Serial.print(checkdelay / 1000 / 60); Serial.println(" minutes)");
delay(checkdelay);
} else {
digitalWrite(FANPIN, LOW); digitalWrite(FANLED, LOW); digitalWrite(TEMPOK, HIGH);
Serial.print("Temperature is under "); Serial.print(FANTEMP); Serial.println(", Fan is off");
}
Serial.println(); Serial.println();
}
Схема

Производственный процесс
- PWM контроллер мощности: сборка драйвера лампы с пульсирующей шириной модуляции
- Картотечный шкаф: дизайн, производство и современное применение
- Температурно-управляемый вентилятор: DIY релейная система охлаждения мебели для медиа
- Устранение вибрации вентилятора: практическое решение балансировки на месте
- Веб-управляемая DMX-система освещения: Arduino Mega как мастер-контроллер
- Автоматизированный игровой помощник: устройство для автонажатия кнопок на геймпаде
- DIY USB-геймпад на Arduino: собственный высокопроизводительный контроллер
- Unopad: Бесшовный Arduino MIDI-контроллер для Ableton Live
- Контроллер вакуумно-люминесцентного дисплея (VFD) на Arduino — DIY набор
- Arduino Home Controller с Alexa: умный дом голосовым управлением