Уважаемые читатели!
Эта статья написана не мной, посему - прошу любить и жаловать: сегодня Vergellan поделится с вами опытом создания умного регулятора вращения вентиляторов, с участием термодатчика, LCD-дисплея и, конечно же, Arduino.
Несколько месяцев назад я прочел ряд статей об Arduino и весьма заинтересовался данным девайсом, а вскоре решил приобрести. Надо отметить, что я далек от микроэлектроники, поэтому плата расположила к себе прежде всего относительной простотой в освоении. Набаловавшись с LED-ами и «Hello world»-ами, захотелось сделать что-нибудь практичное, заодно более детально ознакомиться с возможностями Arduino. Памятуя об аномально жарком лете 2010 года, возникла идея собрать регулятор оборотов кулера в зависимости от температуры с выводом всех сопутствующих характеристик на LCD. Надеюсь, что кому-нибудь данная схема или ее вариации смогут пригодиться, поэтому решил выложить свои наброски.
Для данной схемы нам понадобится:
- Собственно сама плата Arduino или аналог;
- Макетная плата для сборки компонентов схемы;
- Дисплей WH1601A-NGG-CT с подстроечным резистором на 20 кОм или аналогичный;
- Резисторы – 220 Ом, 10 кОм, 4.7 кОм;
- Биполярный транзистор SS8050D или аналогичный ему;
- Цифровой температурный датчик DS18B20;
- Диод 1N4148 или аналог;
- Вентилятор осевой трехпроводной (на 12В), например - компьютерный;
- Разъем гнезда питания 2,1/5,5 мм.
Компьютерный кулер имеет три провода, два из которых - красный (+12V) и черный (GND) используются для питания, а третий (желтый) связан с таходатчиком, построенном на элементе Холла. К сожалению, 5V с платы нам явно недостаточно, но 6 цифровых выходов Arduino могут работать в режиме ШИМ (они отмечены на самой плате белыми квадратиками, либо буквами PWM), поэтому мы можем регулировать подачу сигнала с платы на реле, которое будет отвечать за изменение напряжения, подаваемого на вентилятор.
Получать информацию об оборотах мы будем с третьего провода от таходатчика, воспользовавшись модифицированным способом, основанным на реализации прерываний, которые у большинства Arduino могут приходить на цифровые pin 2 (прерывание 0) и 3 (прерывание 1). Кстати, у Arduino Mega наличествует еще 4 дополнительных пина с возможностью получения прерываний.
Теперь необходимо расположить цифровой датчик температуры, данные которого мы будем использовать для регулирования напряжения, подаваемого на цифровой выход с ШИМ, а следовательно для «открытия» канала напряжения вентилятора. Для датчиков фирмы Dallas существует собственная библиотека Arduino – DallasTemperature, которую впоследствии мы и будем подключать в скетче. Библиотеку необходимо распаковать в каталог arduino-0018/libraries/.
Осталось последнее – подключить LCD, где у нас будет отображаться вся текущая информация о температуре и скорости вентилятора. Поскольку я использовал для сборки экран WH1601A, могут иметь место известные проблемы с отображением строк. Для их устранения мы воспользуемся библиотекой LiquidCrystalRus, которую необходимо также распаковать в каталог arduino-0018/libraries/.
//Подключаем библиотеку для термодатчика #include <dallastemperature.h> //Подключаем библиотеку для LCD #include <LiquidCrystalRus.h> #define PowerPin 9 // pin для контроля питания вентилятора #define HallSensor 2 // pin для датчика оборотов вентилятора (прерывание) #define TempPin 7 // pin для датчика температуры LiquidCrystalRus lcd(12, 11, 10, 6, 5, 4, 3); //Подключение LCD DallasTemperature tempSensor; int NbTopsFan, Calc, fadeValue; //целочисленные переменные для расчетов float temper; //вещественная переменная для хранения температуры typedef struct{ // Вводим новый тип переменных для вентиляторов char fantype; unsigned int fandiv; }fanspec; //Массив переменных нового типа fanspec fanspace[3]={{0,1},{1,2},{2,8}}; //Переменная, отвечающая за выбор типа датчика вентилятора (1 – униполярный датчик Холла, 2 –биполярный датчик Холла) char fan = 2; //Эта функция у нас будет вызываться при каждом прерывании void rpm () { NbTopsFan++; } // Функция расчета подаваемого напряжения на цифровой pin с ШИМ void temp () { fadeValue = min(int(temper*7),255); // Умножаем температуру на коэффициент, // берем от произведения целое число } // Т.к. максимальное значение ШИМ составляет 255, то подавать больше не имеет смысла – берем минимум из двух void setup() { tempSensor.begin(TempPin); //Запускаем температурный датчик lcd.begin(16, 2); //Задаем характеристики LCD lcd.setDRAMModel(LCD_DRAM_WH1601); //И тип дисплея pinMode(HallSensor, INPUT); // Настраиваем pin на получение прерываний attachInterrupt(0, rpm, RISING); //Привязываем прерывание по номеру 0 к нашей функции, причем высчитываться она будет каждый раз при смене сигнала } void loop () { temper = tempSensor.getTemperature(); // Получаем температуру temp(); // Высчитываем подаваемое напряжение на ШИМ analogWrite(PowerPin, fadeValue); // Подаем его NbTopsFan = 0; // Обнуляем переменную, содержащую обороты delay (1000); //Ждем 1 секунду Calc = ((NbTopsFan * 60)/fanspace[fan].fandiv); //Рассчитываем величину оборотов за 60 секунд, поделенную на множитель вентилятора lcd.print (Calc, DEC); //Выводим рассчитанную величину в десятичном виде lcd.print (" rpm - "); lcd.print(temper); //Выводим температуру lcd.home(); }
У меня финальная схемка выглядит так (часть компонентов перенес с макетки на дополнительную плату, т.к. планирую сделать уже готовый регулятор в нормальном корпусе):
В завершение хотел бы выразить огромную благодарность Илье Данилову (idanilov) за «привитый» интерес к Arduino и за помощь в освоении данной платформы.
UPD: Последняя версия LiquidCrystalRus доступна на github.
UPD: Последняя версия LiquidCrystalRus доступна на github.