Управление кулерами на основе ардуино

Стоит у меня домашний сервер, и вот проблема: или шумит жутко, или перегревается и виснет. Немного подумав решил что соорудив управление куллерами с этой проблемой хоть не окончательно, но справлюсь.

Контроллер решил использовать в корпксе TQFP32 (ATMEGA168-20AU). Куллеры у меня немного различаются — один имеер 2 вывода (только питание), на втором есть 3й контакт — скорость вращения. Скорость вращения регулировать решил через ШИМ. Отображать решил в процентах. На управление решил сделать два режима:
1)Управляется автоматически, в зависимости от температуры. При 45С скорость 70%. При 50С скорость 78%. Третий показатель температуры задается переменным резистером, и включает вращение на 100%. При этом режиме отображается: текущая температура, заданная температура и скорость куллеров в процентах.
2)Ручное управление. Два потенциометра регулируют скорость вращения каждый своего куллера. При этом режиме отображается: Скорость вращения кулера с датчиком в оборотах в минуту (rpm), скорость вращения в процентах, текущая температура.

Выбор режима управления определяется переключателем, встроенным в один из переменных резистеров. Второй резистер в автоматическом режиме управляет выбором критической температуры. В ручном режиме каждый резистер управляет своим кулером.

Детали использовал:
HL1 = Светодиод по вкусу
HL2 = Светодиод по вкусу
IC1 = DS18B20
IC2 = ATMEGA168-20AU
LCD = WH1602M-YGH-CTK
M1 = Кулер 12v
M2 = Кулер 12В с датчиком
R1 = 1k
R2 = 10k
R3 = 4.7k
R4 = 50KПеременный с выключателем
R5 = 50KПеременный
R6 = 100
R7 = 100
R8 = 10k
R9 = 10k
S1 = Выключатель в резисторе
VD1 = диод любой smd
VD2 = диод любой smd
VD3 = диод любой smd
VD4 = диод любой smd
VT1 = КТ315б
VT2 = КТ315б
X = 16MHz
Схема spl7:


Плата lay


Скетч:

//Эта библиотека входит в комплект АРДУИНО ИДЕ
#include <LiquidCrystal.h> //библиотека ЛСД экранчика
//Эту библиотеку брал тут: http://robocraft.ru/files/library/OneWire.zip
#include <OneWire.h> //Библиотека работы с 1-ware
//А эту тут: dallas.milesburton.com/index.php?title=Dallas_Temperature_Control_Library#Latest
#include <DallasTemperature.h>//Библиотека работы с термодатсиками 1-ware
#define pwmpinA 10 //Выход ШИМ 1
#define pwmpinB 11 //Выход ШИМ 2
#define HallSensor 2  // pin для датчика оборотов вентилятора (прерывание)
#define ONE_WIRE_BUS 1 //Датчик температуры на аналоговом входе 5
//переключатель встроен в переменный резистор, как только повернул ручку - включился управляемый в ручную режим
#define SWBTN 0 //Переключатель режима работы (Авто/Управляемый) 
OneWire oneWire(ONE_WIRE_BUS);//скажем библиотеке где у нас градусник
DallasTemperature sensors(&oneWire);//скажем библиотеке где у нас градусник
LiquidCrystal lcd(5,6,7,8,9,12); //пины подключения ЛСД
int potB=5; //потенциометр изменения оборотов 2
int potA=0; //потенциометр изменения оборотов 1
int NbTopsFan, Calc, fadeValue, fadeValueA, procfade, procfadeA, CtempA,CtempB;  //целочисленные переменные для расчетов
typedef struct{ // Вводим новый тип переменных для вентиляторов 
  char fantype;
  unsigned int fandiv;
}fanspec;
//Массив переменных нового типа
fanspec fanspace[3]={{0,1},{1,2},{2,8}};
//Переменная, отвечающая за выбор типа датчика вентилятора (1 – униполярный датчик Холла, 2 –биполярный датчик Холла)
char fan = 1;  
//Эта функция у нас будет вызываться при каждом прерывании
void rpm(){NbTopsFan++;}

void rpmcalk()//подсчитываем обороты кулера
{
 NbTopsFan = 0; // Обнуляем переменную, содержащую обороты
 delay (1000); //Ждем 1 секунду
 Calc = ((NbTopsFan * 60)/fanspace[fan].fandiv);   //Рассчитываем величину оборотов за 60 секунд, поделенную на множитель вентилятора
}

void lcdprn()//отображаем информацию на экран
{
lcd.clear();//очистка экрана
lcd.setCursor(0, 0);//курсор на координаты
lcd.print("RPM:");//пишем текст
lcd.print(Calc);//пишем скорость кулера из переменной
lcd.setCursor(8, 0);//курсор на координаты
lcd.print("Spd1:");//пишем текст
lcd.print(procfade);//пишим проценты скорости кулера1
lcd.setCursor(0, 1);//курсор на координаты
lcd.print("Spd2:");//пишем текст
lcd.print(procfadeA);//пишим проценты скорости кулера2
lcd.setCursor(8, 1);//курсор на координаты
lcd.print("Temp:");//пишем текст
lcd.print(CtempA);//пишим температуру
lcd.print("C");//пишем текст
}

void lcdprnA()//отображаем информацию на экран в режиме автоконтроля
{
lcd.clear();//очистка экрана
lcd.setCursor(0, 1);//курсор на координаты
lcd.print("AUTO");//пишем текст значащий что выбран автоконтроль температуры
lcd.setCursor(9, 1);//курсор на координаты
lcd.print("Spd:");//пишем текст
lcd.print(procfade);//пишим проценты скорости кулеров
lcd.setCursor(0, 0);//курсор на координаты
lcd.print("Tmp:");//пишем текст
lcd.print(CtempA);//пишим текущюю температуру
lcd.print("C");//пишем текст
lcd.setCursor(8, 0);//курсор на координаты
lcd.print("CrT:");//пишем текст
lcd.print(CtempB);//пишим температуру КРИТИЧЕСКОГО реагирования
lcd.print("C");//пишем текст
}


void PotReadALL()//читаем и считаем потенциометры
{
  fadeValue=analogRead(potA);//читаем первый потенциометр
  fadeValueA=analogRead(potB);//читаем второй потенциометр
  fadeValue=fadeValue/4;//уменьшаем показания первого потенциометра до приемлимых для ШИМ вывода
  if (fadeValue<=128){fadeValue=128;}//Ограничиваем минимум оборотов до 50%
  procfade=(fadeValue/2.54);//пересчитываем показания первого потенциометра в проценты
  fadeValueA=fadeValueA/4;//уменьшаем показания второго потенциометра до приемлимых для ШИМ вывода
  procfadeA=(fadeValueA/2.54);//пересчитываем показания второго потенциометра в проценты
}

void TempTOvalue()//Читаем температуру с градусника
{
  sensors.requestTemperatures();//Опрашиваем градусники
  //градусник может быть не один, протокол 1-ware позволяет подключать
  //много устройств паралельно, но на моем дисплее место хватило токо на
  //один показатель температуры
  CtempA=sensors.getTempCByIndex(0);//присваиваем температуру переменной
}

//ручная регулировка скорости вращения
void manualcontrol(){

  PotReadALL();//читаем и считаем потенциометры
  rpmcalk();//считаем скорость кулера
  TempTOvalue();
  lcdprn();//Выводим информацию на дисплей
  analogWrite(pwmpinA, fadeValue);//задаем скорость вращения кулера 1         
  analogWrite(pwmpinB, fadeValueA);//задаем скорость вращения кулера 2         
  
}

void autocontrol()//Автоконтроль температуры
{
  PotReadALL();//читаки потенциомерты(с них получим установку критической температуры)
  CtempB=fadeValueA/3; //переводим результат потенциометра в температуру от 0 до 85
  TempTOvalue();//меряем температуру
  fadeValue=0;//сбрасываем показатель скорости
  if (CtempA>=45){fadeValue=180;}//сверяем скорость с критами
  if (CtempA>=50){fadeValue=200;}//сверяем скорость с критами
  if (CtempA>=CtempB){fadeValue=254;}//сверяем скорость с заданой температурой, если задана 
  //температура ниже предыдущих сверок скорость ВСЕГДА на максимуме.
  procfade=(fadeValue/2.54);//пересчитываем показания первого потенциометра в проценты
  lcdprnA();//Выводим информацию на дисплей
  analogWrite(pwmpinA, fadeValue);//задаем скорость вращения кулера 1         
  analogWrite(pwmpinB, fadeValue);//задаем скорость вращения кулера 2         
}

void setup()  { 
  pinMode(HallSensor, INPUT);  // Настраиваем pin на получение прерываний
  pinMode(SWBTN,INPUT); //пин на переключатель -на вход
  attachInterrupt(0, rpm, RISING);  //Привязываем прерывание по номеру 0 к нашей функции, причем высчитываться
 // она будет каждый раз при смене сигнала
  sensors.begin();//включаем сенсор температуры
  lcd.begin(16, 2);//Выставляем параметры экрана
  lcd.home();//очищаем экран и переводим курсор в начало
} 

void loop()  { 
 if (digitalRead(SWBTN)==HIGH){manualcontrol();}  //если переключатель включен - ручное управление вентиляторами
 else {autocontrol();}//иначе - автоконтроль
}

//При разработке этого устройствы использовал следующие статьи:
//http://mk90.blogspot.com/2010/08/arduino.html
//http://robocraft.ru/blog/arduino/136.html

Здесь лежит архив со схемами, скетчем и библиотеками.

Комментарии (22)

RSS свернуть / развернуть
+
0
Хаха-я тоже такое соорудил по статье из мк90. Только я делал шилдом к дуине, но потом забил на это и в итоге две платы и пучек проводов-выглядит не ахти, но в корпусе не видно :)
Со временем тоже хочу переделать на одну плату-но не хватает знаний. как это делается? запрограммировал атмегу-выдернул, запаял?
+еще ко всему у вас теряется возможность перепрошить атмегу, хотя выпаять перепрошить :)
А почему контроль нескольких кулеров не сделали? или вы не сайленсфрик?
а так вам жииирный плюс-за подробное описание, ибо когда приделывал экранчик не нашел внятного мануала на некоторые функции. правда мне уже не к чему-но новички ваш труд оценят
avatar

Alek

  • 7 марта 2011, 17:55
+
0
про несколько кулеров-я про цпу/гпу и два корпусных например :) так то у вас два
avatar

Alek

  • 7 марта 2011, 17:58
+
0
Два, 1 — 3 пиновый, на проц, 2й — 2 хпиновый на харды. Мне и два кулера слишком мешают спать.
Возможность перепрошивки не теряется, и выпаивать не обязательно, для прошивки выведены пины sck miso mosi reset, через них шил изначально, т.к. микроконтроллер ради экономии размера использовал в корпусе TQFP32, это как на ардуино нано.
avatar

mogalkov

  • 7 марта 2011, 18:11
+
0
Чисто для упрощения жизни можно было как раз ардуино нано и использовать тем более что есть наш Российский отличный вариант OR-Duino Nano продают:
Калининград
Петербург
Москва
avatar

skystorm

  • 9 марта 2011, 11:23
+
0
ATmega168-20AU 89.50руб
Дуины нано дешевле 600руб не видел.
Да и по размерам с дуиной все равно больше получится.
Имхо дуина хороша и удобна для прототипирования. Собрал все на макетке, посмотрел, проверил, 10 раз подумал нужно ли это устройство приводить в жизнь или просто поигратся собирал. Если решил что нужно -разводим плату, травим и паяем.
avatar

mogalkov

  • 9 марта 2011, 17:16
+
0
Эти от 400 руб.
По поводу прототипирования согласен на 100%!
Мне плату разводить, травить… на единичный девайс влом!
Я возьму макетку и там распаяю :)))
avatar

skystorm

  • 10 марта 2011, 14:58
+
0
Ну, не знаю, как-то паячными макетками никогда не пользовался, и всегда считал их бесполезными. К тому же не уверен что есть макетки под smd компоненты (тотже TQFP32 например). Да и сомневаюсь на счет целесообразности делать платы ЛУТом массово (имхо для домашних условий удобнее и проще лазерного утюга ничего нет).
avatar

mogalkov

  • 10 марта 2011, 22:55
+
0
Здравствуйте! Мне очень понравился ваш проект, только вот не могу открыть «Плата lay» ((( Можете обновить или скинуть рабочий файл
avatar

uzdyiv

  • 8 ноября 2011, 14:39
+
0
Что значит не можешь открыть? Он не открываться должен а скачиваться. Попробуй правой кнопкой — сохранить как.
avatar

mogalkov

  • 8 ноября 2011, 20:59
+
0
Только что проверил:
Sprint-Layout 5.0 и ЭТИМ открывается.
avatar

mogalkov

  • 8 ноября 2011, 21:12
+
0
Сп)
avatar

uzdyiv

  • 15 ноября 2011, 13:27
+
0
Слышен писк от винтилятора на частоте шим ~500гц. Писк лечится электролитом о 50мкф минусом на землю, а плюсом на минус кулера.
avatar

natural

  • 2 декабря 2011, 22:43
+
0
Через какую программу забрасывали скетч и как???
avatar

uzdyiv

  • 3 декабря 2011, 00:57
+
0
Я не использовал эту схему и скетч. У меня всё проще, я использовал freeduino nano, подключил датчик температуры и вентилятор, без LCD и переменников. Использовал пример Oneware, который есть в ардуине, и который читает температуру с датчиков. Дальше используя несложную формулу для конвертации температуры в скорость делаете вызов analogWrite(pwmpinA, fadeValue);
Всё просто ) Сейчас собираюсь повесить гирлянду датчиков чтобы мерить температуру внутри корпуса, снаружи, на улице и в квартире. А сам сервер будет в нише на балконе :)
Еще бы клёво подключить датчик влажности, счетчик гейгера, тока они шибко дорогие.
А LCD не нужен, сервер пусть публикует информацию с датчиков на web-страничку, которую можно увидеть с другого компутера, со смартфона, или с телика )
avatar

natural

  • 3 декабря 2011, 14:58
+
0
Ну если я заброшу всё это в микроконтроллер оно будет нормально работать?
avatar

uzdyiv

  • 4 декабря 2011, 17:45
+
0
а можно видео вернуть
avatar

uzdyiv

  • 4 декабря 2011, 17:50
+
0
Здравствуйте) я новичок, будте добры проясните ситуацию!
Транзистор VT2 в роли ключа размыкает/замыкает землю, но на эту же землю замыкается провод Data кулера М2 при каждом обороте. В момент когда «ключ-транзистор» разомкнут, а а провод data замкнулся на землю, оборот считываться не будет, т.е. проподает! или я не прав? проясните ситуацию?
avatar

EvgeniyK

  • 5 декабря 2011, 08:29
+
0
Заливал прошивку через AVRdude, примерно как заливать описывал тут и тут. Сама прошивка создается при компиляции, путь к ней можно узнать если зажать шифт при нажатии кнопки компиляции (в ардиуно версии 0.22).

Писк слышен из-за того что куллеры могут работать в роли динамиков (принцип устройства один, магнит + обмотка) убрать можно и конденцатером большой емкости или RC фильтром, я его к схеме не пририсовывал так как писк зависит от самого вентилятора, насколько свободно он сидит. Те на которых используется у меня свистят не слышно.

Видео верну скорее всего не раньше чем после НГ.
avatar

mogalkov

  • 8 декабря 2011, 08:29
+
0
А с вами можно как то связаться по скайпу или ещё чему то??
avatar

uzdyiv

  • 13 января 2012, 21:05
+
0
Когда видео будет, очень нужно (
avatar

uzdyiv

  • 30 января 2012, 21:37
+
0
Верните видео(
avatar

uzdyiv

  • 19 февраля 2012, 21:08
+
0
Видео совсем никак не просмотреть?
avatar

OrCanum

  • 8 апреля 2014, 16:32

Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.