Мой термостат для котла BAXI
- Войдите на сайт для отправки комментариев
Всем привет, хочу представить свой небольшой проект термостата для котла отопления.
Пару лет назад я заменил старую систему отопления на более современную. И все меня устраивало, но постоянная регулировка температуры вручную немного напрягала, осенью (да и зимой) в моих краях большие перепады температуры. То жарко, то холодно в доме. Ночью хотелось прохладней, а днем наоборот по-теплей. Видел в продаже термостаты для котла: - дешевый с пружинкой, бррр, не мой вариант, хоть и не профи, но с детства очень дружу с компьютерами и паяльником, - дорогие электронные, опять не мой вариант :) я-же только начал осваивать ардуинки и уже собрал несложный контроллер для аквариума, надо пробывать !
Пока ждал необходимые компоненты из Китая начал шерстить интернет по теме терморегулирования. Перечитал кучу статей и форумов: термопроводность стен, разница температур, ПИД, кучу споров и т.д. Для себя решил: площадь у меня - небольшая, пид - много тонкостей да и мощность котла как автоматом регулировать я не знал. Поэтому пусть будет просто термостат.
Первое собранное устройство выглядит так:

Это головное устройство, оно находится возле котла и дает команду на вкл./выкл. )
С ним впаре работает:
Дистанционный датчик температуры, он переодически отправляет "голове" температуру в некой комнате.
Отработала эта связка пару месяцев и такую же захотел установить родственник. Собрал и ему. Его вариант выглядит так:
Датчик
Далее уже конкретно к железу :)
Умеет следующее:
поддерживает в доме дневную и ночную температуру;
два датчика температуры (дистанционный и местный, расположенный недалеко от котла);
основной датчик дистанционный, при его отключении или поломке автоматически переходит на работу с местным датчиком;
настройка температур, время срабатывания, гистерезиса, коррекция часов и еще некоторые сервисные настройки;
сохранение и вывод некоторых ошибок работы устройства и их сброс;
дистанционный датчик отправляет температуру на основное устройство с некоторыми интервалами и выводит ее на 7сегментник, меняет яркость дисплея в зависимости от освещения;
Для сборки этой системы потребовались:
2 arduino pro mini, часовой модуль ds3231, релейный модуль, 2 датчика 18b20, модули приемника и передатчика 433мГц, lcd 16x2 i2c, 7сегментный индикатор, блоки питания 12в и 5в, ну и еще мелочевка: max7219, кнопки, светодиоды... всего сразу не вспомню, прошло 2 года, а все схемы в голове ;) Если кого заинтересует вспомню подробней.
Устройство отработало 2 года, я уже начал забывать какая кнопка за что отвечает :) а если устройство включил и забыл, мне кажется, оно работает неплохо. Есть конечно же и мелкие косяки, недочеты. Их легко исправить при сборке нового устройства, свое править мне пока лень.... но вдруг )
Скетч выложу чуть позже. Он очень нубоватый (я только начинал учиться), там куча комментариев, поэтому новичкам будет легко разобраться, а старожилы немного развлекуться :)
Добрый день
Так как пишу что-то подобное, есть пару вопросов:
1. Как Вы организовали резервное питание устройств (если оно есть вообще);
2. Как реализовали временные интервалы? Например день, ночь, лето, зима и т.д.
3. Почему не использовали Nrf24l01+? Вроде оно лучше, чем 433МГц.
На счет ПИД регулятора, думаю для небольших помещений, шкурка вычинки не стоит. Лично я думаю начать от разницы температуры дома и на улицы, а там видно будет
1. Выкиньте ваш датчик на улицу, желательно на северную сторону.
2. Регулируйте температуру подачи в зависимости от наружной как на этом графике
Используя map() , понятно что в меню надо делать регулировку точек
http://www.heizungsforum.de/forum/index.php/Attachment/2502-Unbenannt1-PNG/
Полная документация http://www.gazeskatli.lv/documents/Junkers_TA211E_Rus.pdf
3. А все остальные таймеры-день-ночь это только дополнения к правильному регулированию
А называется всё это погодозависимый регулятор
Спасибо.
Но я немного про другое спрашивал) Зависимости от темп дома и улицы, сделаю в последнюю очередь, сейчас вопрос про интервалы.
Потому что у меня их будет порядка 4 в день.
И Вам доброго дня.
1. Резервного питания нет. Если вы имеете ввиду только сам термостат, какой смысл ? котел-то обесточен... А резервное питание котла - это уже другая история...
2. Интервалы день - ночь. Например: днем желаемая т.25-поддерживаем, бумс 23:00, ночь желаемая т.23 -держим, 6:00 день - т.25 греем-держим ну и тд. Приятно встать в 7 утра, а дома тепло )
3. Во-первых: для меня это был 2й на что-то похожий проект и про Nrf24l01+ я слышал только краем уха, да и сейчас еще толком с ними не разобрался :) Во-вторых: дом у меня небольшой, дальности и этих хватает.Да и передавать-то там особо нечего, раз в минуту температуру отправить. Ну и в-третьих: у меня на крыше дома стоят несколько wifi антенн+дома роутер+соседские роутеры, какофония в диапазоне wifi жесть. Не хотелось туда особо лезть.
Про ПИД много читал-думал, много заморочек там... ну его, не стоит )
По разнице температур.... оно наверное правильней, но там тоже есть подводные камни
Сегодня приеду домой, выложу скетчи
.....Зависимости от темп дома и улицы, сделаю в последнюю очередь, сейчас вопрос про интервалы.
Потому что у меня их будет порядка 4 в день.
Повторюсь- температура в доме не измеряется. Она делается вами от наружной.
Тогда и интервалы не очень нужны.
Про ПИД много читал-думал, много заморочек там... ну его, не стоит )
По разнице температур.... оно наверное правильней, но там тоже есть подводные камни
ПИД, конечно, нет смысла делать, не та точность регулирования .
И средней температуры подачи вполне хватает.
И никакой разницы температур! Только уличная и график зависимости.
Я бы не сказал, что надо плясать только от улицы. Вот сейчас у нас температура скачет, причем так как я живу один, то днем вообще не топлю.
Про интервалы понял. Тогда надо иметь процедуру, которая будет возвращать текущую температуру текущего интервала.
Вот код головного устройства:
/ версия 1.23 30.12.2013 #include <OneWire.h> //подключаем шину 1-ware #include <Wire.h> #include <DS3231.h> //подключаем библиотеку RTC3231 #include <LiquidCrystal_I2C.h> //экран #include <avr/wdt.h> //watchdog #include <Bounce.h> //библиотека дребезга кнопок #include <EEPROM.h> //включаем EEPROM #include <RCSwitch.h>//библиотека для передатчика/приемника #define led1 11 //доп.светодиод #define led2 9 //зел. остывание #define led3 10 //красн. нагрев #define relay 12 //релюшка # #define zummer 4 //зуммер #define swich1 6 //кнопки вниз #define swich2 5 //вверх #define swich4 7 //enter int TSensorPin = 8; // ds18b20 местный на ноге 8 OneWire ds(TSensorPin);// создаем объект температурного датчика RCSwitch mySwitch = RCSwitch(); // объект приемник/передатчик // настройка часов RTC DS3231 Clock; bool h12 = false; //True is 12-h, false is 24-hour.; bool PM; bool Century = false; LiquidCrystal_I2C lcd(0x27, 16, 2); //Задаем размерность дисплея. byte ledlight = 1; //яркость светодиодов EEPROM 55 byte ledlightset = 0; byte controlE4 = 1; //контроль перезагрузок EEPROM 54 int flagmenu = 0; //флаг выбора меню int setwait = 300; //время возврата в главное меню int wait = setwait; int ledwite = 0;//время для мигания светодиодов работы котла byte light = 1; //подсветка экрана boolean warningOn = false; // задержка проверки аварии т сенсора boolean termoblock = true; // блокировка кипятильника при аварии float termo1 = 99.9; //температура местная float termo2 = 99.9; //температура дистанционная float termoS = 88; //температура внутри устройства byte flagtermo = 0; //флаг датчика температуры: 0 - местный, 1 - дистанционный float termoset = 25; // желаемая температура днем, байты 23 и 24 float ntermoset = 23; // желаемая ночная температура, байты 21 и 22 boolean flagnight = false; // флаг ночи byte nightstart = 21; //начало ночи byte nightend = 5; //конец ночи int timer = 0; // timer2 = 0, timer3 = 0; // переменная для проверки отсутствия дист. датчика, мигалки светодиодов int timer433 = 0; int settimer = 3000; boolean flagkotel = false; //флаг котел включен или нет boolean flagrelay = false; //флаг релюшки float termokey = termo1; //температура для проверки релюшкой float tGist = 0.7;//гистерезис EEPROM 26 float gistset = 0.0;//переменная для настройки гистерезис int gst = 0;//установка гистерезиса в EEPROM байт 26 boolean sw1 = false; boolean sw2 = false; boolean sw4 = false; int x = 0; void setup() { Wire.begin(); //Serial.begin(9600); lcd.init(); // Инициализация lcd lcd.backlight(); // Включаем подсветку lcd.clear(); lcd.setCursor(0, 0); lcd.print("BAXI'k TERMO"); // Выводим текст lcd.setCursor(0, 1); // Устанавливаем курсор в начало 2 строки lcd.print("V 1.23 Loading..."); // Выводим текст controlE4 = EEPROM.read(54); //контроль перезагрузок EEPROM 54 mySwitch.enableReceive(0); // приемник на пине 2 //пишем в память при первой компиляции ?? //EEPROM.write(51, 0); //пишем в EEPROM //EEPROM.write(52, 0); //пишем в EEPROM //EEPROM.write(53, 0); //пишем в EEPROM //EEPROM.write(54, 0); //пишем в EEPROM //EEPROM.write(55, 0); //пишем в EEPROM //EEPROM.write(56, 0); //пишем в EEPROM //EEPROM.write(57, 0); //пишем в EEPROM //EEPROM.write(58, 0); //пишем в EEPROM //EEPROM.write(59, 0); //пишем в EEPROM //EEPROM.write(60, 0); //пишем в EEPROM // EEPROM.write(41, 0); //пишем в EEPROM // EEPROM.write(42, 0); //пишем в EEPROM //EEPROM.write(43, 0); //пишем в EEPROM // контроль перезагрузки if (controlE4 == 1) { EEPROM.write(44, 1); //пишем в EEPROM сработала WD } //EEPROM.write(45, 0); //пишем в EEPROM //EEPROM.write(46, 0); //пишем в EEPROM //EEPROM.write(47, 0); //пишем в EEPROM //EEPROM.write(48, 0); //пишем в EEPROM //EEPROM.write(49, 0); //пишем в EEPROM //EEPROM.write(50, 0); //пишем в EEPROM // начальные настройки часов // Clock.setSecond(50);//Set the second // Clock.setMinute(59);//Set the minute // Clock.setHour(11); //Set the hour // Clock.setDoW(5); //Set the day of the week // Clock.setDate(31); //Set the date of the month // Clock.setMonth(5); //Set the month of the year // Clock.setYear(13); //Set the year (Last two digits of the year) // читаем EEPROM flagtermo = EEPROM.read(25); // выбор датчика // яркость светодиодов и контроль наприжения ledlightset = EEPROM.read(55); //яркость светодиодов EEPROM 55 // желаемая температура днем //читаем EEPROM и собираем byte hi = EEPROM.read(23); byte low = EEPROM.read(24); float set = word(hi, low); //собираем число termoset = (set / 10); //получаем запятую ) // желаемая температура ночью //читаем EEPROM и собираем byte hin = EEPROM.read(21); byte lown = EEPROM.read(22); float setn = word(hin, lown); //собираем число ntermoset = (setn / 10); //получаем запятую ) // ночной режим nightstart = EEPROM.read(19); //читаем в EEPROM nightend = EEPROM.read(20); //читаем в EEPROM gst = EEPROM.read(26); // гистерезис из памяти gistset = float (gst); tGist = gistset / 10; // гистерезис // яркость светодиодов if (ledlightset == 0) { ledlight = 2; } if (ledlightset == 1) { ledlight = 100; } if (ledlightset == 2) { ledlight = 254; } // Первоначальные установки выходов pinMode (swich1, INPUT); pinMode (swich2, INPUT); // pinMode (swich3, INPUT); pinMode (swich4, INPUT); // pinMode (A0, INPUT); pinMode (led1, OUTPUT); pinMode (led2, OUTPUT); pinMode (led3, OUTPUT); pinMode (relay, OUTPUT); pinMode(zummer, OUTPUT); //зуммер analogWrite (led1, 0); analogWrite (led2, 0); analogWrite (led3, 0); digitalWrite (relay, LOW); delay(2000); timer = settimer; wdt_enable (WDTO_8S); //запуск watchdog lcd.clear(); } void loop() //основной цикл { //мигаем светодиодами if (ledwite > 100) //мигалка работы котла { if (flagkotel == false) { analogWrite (led2, ledlight); delay(200); analogWrite (led2, 0); } else { analogWrite (led3, ledlight); delay(200); analogWrite (led3, 0); } } //Serial.println(termokey); keycont1(); //проверяем кнопки в главном меню errors(); //смотрим нет ли ошибок if (wait == (setwait / 2))// иногда измеряем внутреннюю температуру { termoS = Clock.getTemperature(); // температура внутри устройства termo1 = getTemp(); // температура внутренний termoread(); } if (flagmenu == 0) { menu0(); termoread(); // температуру relaycontroL(); //смотрим, не пора ли включить котел ) } if (flagmenu == 1) { menu1(); } if (flagmenu == 2) { menu2(); } if (flagmenu == 3) { menu3(); } if (flagmenu == 4) { menu4(); } if (flagmenu == 5) { menu5(); } if (flagmenu == 6) { menu6(); } if (flagmenu == 7) { menu7(); } if (flagmenu == 8) { menu8(); } timeout();//если ничего не нажато- то возврат в главное меню } //вырубаем подсветку если включена в главном меню void LightBack() { if (light == 0) { lcd.noBacklight(); // выключаем подсветку //lcd.clear(); } else { lcd.backlight(); // Включаем подсветку } } void menu0() //выводим меню0 - часы и температура Главное меню ***************** { int second, minute, hour; hour = Clock.getHour(h12, PM); minute = Clock.getMinute(); second = Clock.getSecond(); lcd.setCursor(0, 0); //часы if (hour < 10) lcd.print('0'); lcd.print(hour, DEC); lcd.print(':'); if (minute < 10) lcd.print('0'); lcd.print(minute, DEC); lcd.print(':'); if (second < 10) lcd.print('0'); lcd.print(second, DEC); lcd.print(' '); if (termo2 == 99.9) //ошибка датчика внешнего { lcd.print("E:----"); } else { lcd.print("E:"); lcd.print(termo2, 1); } lcd.setCursor(9, 1); //lcd.print("I:"); if (termo1 == 99.9) { lcd.print("I:----");//ошибка датчика внутреннего } else { lcd.print("I:"); lcd.print(termo1, 1); } lcd.setCursor(0, 1); lcd.print("R:"); if (flagtermo == 0 && EEPROM.read(53) == 2) { lcd.setCursor(15, 1); lcd.print("*"); lcd.setCursor(15, 0); lcd.print(" "); } if (flagtermo == 1 && EEPROM.read(53) == 2) { lcd.setCursor(15, 0); lcd.print("*"); lcd.setCursor(15, 1); lcd.print(" "); } if (flagnight == false) { lcd.setCursor(2, 1); //включен режим день lcd.print("D"); lcd.print(" "); lcd.print(termoset, 1); //lcd.print(demo, 1); } else { lcd.setCursor(2, 1); //включен режим ночь lcd.print("N"); lcd.print(" "); lcd.print(ntermoset, 1); } } void menu1() //выводим меню1 установка желаемой температуры днем *************** { lcd.setCursor(2, 0); lcd.print("Day termo Set"); lcd.setCursor(6, 1); lcd.print(termoset, 1); } void menu4() //выводим меню2 выбор датчика ******************** { flagtermo = EEPROM.read(25); // выбор датчика lcd.setCursor(0, 0); lcd.print("Sensor:"); lcd.setCursor(7, 0); if (flagtermo == 0) { lcd.print("Internal"); //внутренний lcd.setCursor(9, 1); lcd.print(termo1, 1); } if (flagtermo == 1) { lcd.print("External"); //внешний lcd.setCursor(9, 1); lcd.print(termo2, 1); } } void menu3() //выводим меню3 гистерезис ********************** { lcd.setCursor(0, 0); lcd.print("Hysteresis:"); lcd.setCursor(12, 0); lcd.print(tGist, 1); lcd.setCursor(6, 1); lcd.print("Set"); gistset = tGist; } void menu2() //выводим меню4 установка температура режима ночь ********************** { lcd.setCursor(1, 0); lcd.print("Night termo Set"); lcd.setCursor(6, 1); lcd.print(ntermoset, 1); } void menu5() //начало и завершение режима ночь ********************** { lcd.setCursor(3, 0); lcd.print("Night Time"); lcd.setCursor(12, 0); lcd.setCursor(7, 1); lcd.print("Set"); } void menu6() //выводим меню6 настройка часов ********************** { int second, minute, hour; hour = Clock.getHour(h12, PM); minute = Clock.getMinute(); second = Clock.getSecond(); lcd.setCursor(4, 0); lcd.print("Time set"); lcd.setCursor(4, 1); //часы if (hour < 10) lcd.print('0'); lcd.print(hour, DEC); lcd.print(':'); if (minute < 10) lcd.print('0'); lcd.print(minute, DEC); lcd.print(':'); if (second < 10) lcd.print('0'); lcd.print(second, DEC); lcd.print(' '); } void menu7() // ***************************INFO******************************* ошибки { byte ea, eb, ec, ed, ee; byte x; ea = EEPROM.read(41); eb = EEPROM.read(42); ec = EEPROM.read(43); ed = EEPROM.read(44); ee = EEPROM.read(45); lcd.setCursor(0, 0); lcd.print("Errors:"); // выводим коды ошибок if (ea != 0) // пропал дистанционный датчик { lcd.setCursor(0, 1); lcd.print("E01"); } if (eb != 0) // авария датчика температуры { lcd.setCursor(3, 1); lcd.print("E02"); } if (ec != 0) // { lcd.setCursor(6, 1); lcd.print("E03"); } if (ed != 0) //срабатывала перезагрузка { lcd.setCursor(9, 1); lcd.print("E04"); } if (ee != 0) // { lcd.setCursor(12, 1); lcd.print("E05"); } } void menu8() //******************************SERVIS MENU ********************** { lcd.setCursor(02, 0); lcd.print("Service Menu"); } void termoread() //обрабатываем температуру ************************* { receiver(); // ждем температуру с дистанционника if (flagtermo == 0) { termokey = termo1; } if (flagtermo == 1) { termokey = termo2; } if (termo2 == 99.9) //отсутствует дистанционный датчик переходим на внутренний { termokey = termo1; } if (termokey < 10 && termokey != 99.9) //при глюках включаем тревогу { if (termoblock == false) { warning (); } } if (termokey > 40 && termokey != 99.9) //при глюках включаем тревогу { if (termoblock == false) { warning (); } } if (termo1 == 99.9 && termo2 == 99.9) //отсутствуют оба датчика { if (termoblock == false) { warning (); } } } //Функции чтения с внутреннего датчика температуры**************** float getTemp() { byte data[12]; byte addr[8]; if ( !ds.search(addr)) { ds.reset_search(); return 99.9; } if ( OneWire::crc8( addr, 7) != addr[7]) { return 99.9; } if ( addr[0] != 0x10 && addr[0] != 0x28) { return 99.9; } ds.reset(); ds.select(addr); ds.write(0x44, 1); // delay(800); byte present = ds.reset(); ds.select(addr); ds.write(0xBE); for (int i = 0; i < 9; i++) { data[i] = ds.read(); } ds.reset_search(); byte MSB = data[1]; byte LSB = data[0]; float TRead = ((MSB << 8) | LSB); float Temperature = TRead / 16; return Temperature; } // подпрограмма зуммера********************************************************************* void beep( int delt ) // подпрограмма зуммера { tone(zummer, 2093); delay(delt); noTone(zummer); delay(delt); } // не пора ли включать котел ********************************************************* void relaycontroL() { int x = 1; float term; byte z; z = EEPROM.read(53); nightcontrol(); // смотрим день у нас или ночь if (flagnight == false) { term = termoset; } if (flagnight == true) { term = ntermoset; } float minus = term - tGist; float plus = term + tGist; if (termokey < minus) { flagrelay = true; } if (termokey > plus) { flagrelay = false; } if (z == 0) { flagrelay = false; } if (z == 1) { flagrelay = true; termoblock = false; } if (flagrelay == true && termoblock == false) //если котел включен и блокировка снята, то включаем { digitalWrite (relay, LOW); // включаем котел flagkotel = true; } else { digitalWrite (relay, HIGH); //выключаем котел flagkotel = false; } } void timeout() //если ничего не нажато****************************************** { if (wait < 0 && flagmenu != 0) { flagmenu = 0; lcd.clear(); beep(50); wait = setwait; } if (wait < 0 && flagmenu == 0) { wait = setwait; termoblock = false; // отключение тревоги } wait = wait - 1; if (ledwite > 100) //таймер для светодиодов { ledwite = 0; } ledwite = ledwite + 1; if (timer < 0 && light == 1) { light = 0; LightBack(); } if (timer < 0) { timer433 = timer433 + 1; timer = settimer; } timer = timer - 1; } void warning () // авария датчика температуры ****************************************** { byte z; z = EEPROM.read(42); lcd.clear(); lcd.setCursor(3, 0); lcd.print("WARNING !!!"); lcd.setCursor(0, 1); lcd.print("t Sensor Failed!"); if (z == 0) //если ошибки не было то пишем её { EEPROM.write(42, 1); } beep(50); beep(50); beep(50); delay(100); beep(150); beep(150); beep(150); beep(50); beep(50); beep(50); delay(500); lcd.clear(); termoblock = true; } void keycont1() //проверяем кнопки в главном меню ***************************************** { debounce(); //читаем кнопки if (sw2 == true) //нажатие кнопки1 { if (light == 1) { wait = setwait; flagmenu = flagmenu + 1; //листаем менюшки вверх timer = settimer; if (flagmenu > 8) { flagmenu = 0; } lcd.clear(); } if (light == 0) //если подсветка была выключен то.... { light = 1; LightBack(); timer = settimer; } delay (100); } if (sw1 == true) //нажатие кнопки3 { if (light == 1) { wait = setwait; timer = settimer; flagmenu = flagmenu - 1; //листаем менюшки вниз if (flagmenu < 0) { flagmenu = 8; } lcd.clear(); } if (light == 0) //если подсветка была выключен то.... { light = 1; LightBack(); timer = settimer; } delay (100); } if (sw4 == true && flagmenu == 0) //нажатие кнопки2 вкл\выкл подсветка { if (light == 1) { light = 0; LightBack(); } else { light = 1; LightBack(); timer = settimer; } delay(100); } // смотрим на кнопку enter sw4 if (sw4 == true && flagmenu == 4) //выбор сенсора { wait = setwait; if (flagtermo == 0) { flagtermo = 1; EEPROM.write(25, flagtermo); //пишем в EEPROM } else { flagtermo = 0; EEPROM.write(25, flagtermo); //пишем в EEPROM } delay (200); } if (sw4 == true && flagmenu == 3) // гистерезис { wait = setwait; hysteresis(); } if (sw4 == true && flagmenu == 1) // дневная температура установка { wait = setwait; settermoon(); } if (sw4 == true && flagmenu == 5) // ночное время { wait = setwait; nighttime(); } if (sw4 == true && flagmenu == 2) // установка ночной температуры { wait = setwait; nighttermoset(); } if (sw4 == true && flagmenu == 6) // установка часов { wait = setwait; settime(); } if (sw4 == true && flagmenu == 8) // сервисное меню { wait = setwait; servismenu(); } if (sw4 == true && flagmenu == 7) // сброс ошибок { wait = setwait; errorClear(); } } //**********************************СБРОС ОШИБОК***************************************** void errorClear() { EEPROM.write(41, 0); //пишем в EEPROM EEPROM.write(42, 0); //пишем в EEPROM EEPROM.write(43, 0); //пишем в EEPROM EEPROM.write(44, 0); //пишем в EEPROM EEPROM.write(45, 0); //пишем в EEPROM EEPROM.write(46, 0); //пишем в EEPROM EEPROM.write(47, 0); //пишем в EEPROM EEPROM.write(48, 0); //пишем в EEPROM EEPROM.write(49, 0); //пишем в EEPROM EEPROM.write(50, 0); //пишем в EEPROM lcd.clear(); lcd.setCursor(4, 0); lcd.print("Cleared"); delay (500); beep(50); beep(50); delay (500); lcd.clear(); } //меню установка гистерезиса **************************************************** void hysteresis() { lcd.clear(); delay(200); lcd.setCursor(0, 0); lcd.print("Hysteresis:"); lcd.setCursor(0, 1); lcd.print("On:"); lcd.print((termoset - tGist), 1); lcd.setCursor(8, 1); lcd.print("Off:"); lcd.print((termoset + tGist), 1); lcd.setCursor(12, 0); lcd.print(tGist, 1); lcd.blink(); gistset = tGist; delay(500); while (1) { debounce(); //читаем кнопки if (sw2 == true)//кнопка вверх { gistset = gistset + 0.1; if (gistset > 3) { gistset = 0; } delay (200); lcd.setCursor(3, 1); lcd.print((termoset - gistset), 1); lcd.setCursor(12, 1); lcd.print((termoset + gistset), 1); lcd.setCursor(12, 0); lcd.print(gistset, 1); } if (sw1 == true)//кнопка вниз { gistset = gistset - 0.1; if (gistset < 0) { gistset = 3; } delay (200); lcd.setCursor(3, 1); lcd.print((termoset - gistset), 1); lcd.setCursor(12, 1); lcd.print((termoset + gistset), 1); lcd.setCursor(12, 0); lcd.print(gistset, 1); } if (sw4 == true)//кнопка ENTER :) { delay(200); lcd.noBlink(); break; } } lcd.clear(); lcd.setCursor(4, 0); lcd.print("SETTING"); lcd.setCursor(6, 1); lcd.print(gistset, 1); tGist = gistset; gistset = gistset * 10; gst = int(gistset); EEPROM.write(26, gst); //пишем в EEPROM delay (500); beep(50); beep(50); delay (500); lcd.clear(); } // Устанавливаем желаемую температуру днем *************************************** void settermoon() { float set = termoset; lcd.clear(); delay(200); lcd.setCursor(0, 0); lcd.print("Day termo:"); lcd.setCursor(0, 1); lcd.print("On:"); lcd.print((set - tGist), 1); lcd.setCursor(8, 1); lcd.print("Off:"); lcd.print((set + tGist), 1); lcd.setCursor(10, 0); lcd.print(set, 1); // lcd.setCursor(9, 1); lcd.blink(); delay(500); while (1) { debounce(); //читаем кнопки if (sw2 == true)//кнопка вверх { set = set + 0.1; if (set > 35) { set = 15; } lcd.setCursor(3, 1); lcd.print((set - tGist), 1); lcd.setCursor(12, 1); lcd.print((set + tGist), 1); lcd.setCursor(10, 0); lcd.print(set, 1); delay(200); } if (sw1 == true)//кнопка вниз { set = set - 0.1; if (set < 15) { set = 35; } lcd.setCursor(3, 1); lcd.print((set - tGist), 1); lcd.setCursor(12, 1); lcd.print((set + tGist), 1); lcd.setCursor(10, 0); lcd.print(set, 1); delay(200); } if (sw4 == true)//кнопка ENTER :) { delay(200); lcd.noBlink(); break; } } termoset = set; lcd.clear(); lcd.setCursor(5, 0); lcd.print("SETTING"); lcd.setCursor(7, 1); lcd.print(termoset, 1); //разбираем и пишем в EEPROM int eepromset = int(set * 10);//избавляемся от запятых byte hi = highByte(eepromset); //разбивка числа на 2 байта byte low = lowByte(eepromset); EEPROM.write(23, hi); EEPROM.write(24, low); delay (500); beep(50); beep(50); delay (500); lcd.clear(); } //установка часов ************************************* void settime() { int second, minute, hour; int sethour, setminute; hour = Clock.getHour(h12, PM); minute = Clock.getMinute(); second = Clock.getSecond(); sethour = hour; setminute = minute; second = 0; lcd.clear(); lcd.setCursor(0, 0); lcd.print("Hour:"); lcd.print(sethour); lcd.print(" "); lcd.setCursor(0, 1); lcd.print("Minute:"); lcd.print(setminute); lcd.print(" "); delay(300); lcd.setCursor(7, 0); lcd.blink(); while (1) //устанавливаем часы { debounce(); //читаем кнопки if (sw2 == true)//кнопка вверх { sethour = sethour + 1; if (sethour > 23) { sethour = 0; } delay (200); lcd.setCursor(5, 0); lcd.print(sethour); lcd.print(" "); } if (sw1 == true)//кнопка вниз { sethour = sethour - 1; if (sethour < 0) { sethour = 23; } delay (200); lcd.setCursor(5, 0); lcd.print(sethour); lcd.print(" "); } if (sw4 == true) { lcd.setCursor(9, 1); hour = sethour; delay(200); break; } } while (2) //устанавливаем минуты { debounce(); //читаем кнопки if (sw2 == true)//кнопка вверх { setminute = setminute + 1; if (setminute > 59) { setminute = 0; } delay (200); lcd.setCursor(7, 1); lcd.print(setminute); lcd.print(" "); } if (sw1 == true)//кнопка вниз { setminute = setminute - 1; if (setminute < 0) { setminute = 59; } delay (200); lcd.setCursor(7, 1); lcd.print(setminute); lcd.print(" "); } if (sw4 == true) { minute = setminute; delay(200); break; } } // сохраняем установки времени Clock.setSecond(second); //Set the second Clock.setMinute(minute); //Set the minute Clock.setHour(hour); //Set the hour lcd.clear(); lcd.noBlink(); lcd.setCursor(7, 0); lcd.print("Time"); lcd.setCursor(5, 1); lcd.print("SETTING"); delay (500); beep(50); beep(50); delay (500); lcd.clear(); } // устанавливаем ночную температуру ******************************************** void nighttermoset() { float set = ntermoset; lcd.clear(); delay(200); lcd.setCursor(0, 0); lcd.print("N. termo:"); lcd.setCursor(0, 1); lcd.print("On:"); lcd.print((set - tGist), 1); lcd.setCursor(8, 1); lcd.print("Off:"); lcd.print((set + tGist), 1); lcd.setCursor(9, 0); lcd.print(set, 1); // lcd.setCursor(9, 1); lcd.blink(); delay(500); while (1) { debounce(); //читаем кнопки if (sw2 == true)//кнопка вверх { set = set + 0.1; if (set > 35) { set = 15; } lcd.setCursor(3, 1); lcd.print((set - tGist), 1); lcd.setCursor(12, 1); lcd.print((set + tGist), 1); lcd.setCursor(9, 0); lcd.print(set, 1); delay(200); } if (sw1 == true)//кнопка вниз { set = set - 0.1; if (set < 15) { set = 35; } lcd.setCursor(3, 1); lcd.print((set - tGist), 1); lcd.setCursor(12, 1); lcd.print((set + tGist), 1); lcd.setCursor(9, 0); lcd.print(set, 1); delay(200); } if (sw4 == true)//кнопка ENTER :) { delay(200); lcd.noBlink(); break; } } ntermoset = set; lcd.clear(); lcd.setCursor(5, 0); lcd.print("SETTING"); lcd.setCursor(7, 1); lcd.print(ntermoset, 1); //разбираем и пишем в EEPROM int eepromset = int(set * 10);//избавляемся от запятых byte hi = highByte(eepromset); //разбивка числа на 2 байта byte low = lowByte(eepromset); EEPROM.write(21, hi); EEPROM.write(22, low); delay (500); beep(50); beep(50); delay (500); lcd.clear(); } // устанавливаем продолжительность ночи void nighttime() { int startset = nightstart; int endset = nightend; lcd.clear(); lcd.setCursor(0, 0); lcd.print("Start:"); lcd.print(startset); //lcd.print(" "); lcd.setCursor(9, 0); lcd.print("End:"); lcd.print(endset); delay(300); lcd.setCursor(8, 0); lcd.blink(); while (1) //устанавливаем начало ночи { debounce(); //читаем кнопки if (sw2 == true)//кнопка вверх { startset = startset + 1; if (startset > 23) { startset = 0; } lcd.setCursor(6, 0); lcd.print(startset); lcd.print(" "); lcd.setCursor(8, 0); delay(200); } if (sw1 == true)//кнопка вниз { startset = startset - 1; if (startset < 0) { startset = 23; } lcd.setCursor(6, 0); lcd.print(startset); lcd.print(" "); delay(200); } if (sw4 == true) { lcd.setCursor(15, 0); delay(200); break; } } while (2) //устанавливаем завершение ночи { debounce(); //читаем кнопки if (sw2 == true)//кнопка вверх { endset = endset + 1; if (endset > 23) { endset = 0; } lcd.setCursor(13, 0); lcd.print(endset); lcd.print(" "); lcd.setCursor(15, 0); delay(200); } if (sw1 == true)//кнопка вниз { endset = endset - 1; if (endset < 0) { endset = 23; } lcd.setCursor(13, 0); lcd.print(endset); lcd.print(" "); lcd.setCursor(15, 0); delay(200); } if (sw4 == true) { lcd.noBlink(); delay(200); break; } } nightstart = startset; nightend = endset; lcd.clear(); lcd.setCursor(4, 0); lcd.print("SETTING"); lcd.setCursor(0, 1); lcd.print("Start:"); lcd.print(nightstart); //lcd.print(" "); lcd.setCursor(9, 1); lcd.print("to:"); lcd.setCursor(13, 1); lcd.print(nightend); EEPROM.write(19, nightstart); //пишем в EEPROM EEPROM.write(20, nightend); //пишем в EEPROM delay (500); beep(50); beep(50); delay (500); lcd.clear(); } // Сервисное меню ************************************************************************************* void servismenu() { int fa, fb, fc, fd, fe; fa = EEPROM.read(51); // время ожидания с дистанционника до ошибки fb = EEPROM.read(52); //звук приемника fc = EEPROM.read(53); //режим работы котла 0-вык, 1-вкл, 2-авт fd = EEPROM.read(54); //controlE4 контроль перезагрузок fe = EEPROM.read(55); // яркость светодиодов ledlight //byte setF; lcd.clear(); lcd.setCursor(0, 0); //температура внутри устройства lcd.print("S:"); lcd.setCursor(0, 1); lcd.print("1F"); lcd.print(fa); lcd.setCursor(5, 1); lcd.print("2F"); lcd.print(fb); lcd.setCursor(10, 1); lcd.print("3F"); lcd.print(fc); lcd.setCursor(2, 0); lcd.print("4F"); lcd.print(fd); lcd.setCursor(6, 0); lcd.print("5F"); lcd.print(fe); lcd.setCursor(12, 0); lcd.print(termoS, 1); lcd.blink(); lcd.setCursor(4, 1); while (1) //установки f1 { debounce(); //читаем кнопки if (sw2 == true)//кнопка вверх { fa = fa + 1; if (fa > 60) { fa = 1; } lcd.setCursor(2, 1); lcd.print(fa); lcd.print(" "); lcd.setCursor(4, 1); delay(200); } if (sw1 == true)//кнопка вниз { fa = fa - 1; if (fa < 1) { fa = 60; } lcd.setCursor(2, 1); lcd.print(fa); lcd.print(" "); lcd.setCursor(4, 1); delay(200); } if (sw4 == true) { lcd.setCursor(8, 1); delay(200); break; } } while (2) //установки f2 { debounce(); //читаем кнопки if (sw2 == true)//кнопка вверх { fb = fb + 1; if (fb > 1) { fb = 0; } lcd.setCursor(7, 1); lcd.print(fb); lcd.setCursor(8, 1); delay(200); } if (sw1 == true)//кнопка вниз { fb = fb - 1; if (fb < 0) { fb = 1; } lcd.setCursor(7, 1); lcd.print(fb); lcd.setCursor(8, 1); delay(200); } if (sw4 == true) { lcd.setCursor(13, 1); delay(200); break; } } while (3) //установки f3 { debounce(); //читаем кнопки if (sw2 == true)//кнопка вверх { fc = fc + 1; if (fc > 2) { fc = 0; } lcd.setCursor(12, 1); lcd.print(fc); lcd.setCursor(13, 1); delay(200); } if (sw1 == true)//кнопка вниз { fc = fc - 1; if (fc < 0) { fc = 2; } lcd.setCursor(12, 1); lcd.print(fc); lcd.setCursor(13, 1); delay(200); } if (sw4 == true) { lcd.setCursor(5, 0); //lcd.noBlink(); delay(200); break; } } while (4) //установки f4 { debounce(); //читаем кнопки if (sw2 == true)//кнопка вверх { fd = fd + 1; if (fd > 1) { fd = 0; } lcd.setCursor(4, 0); lcd.print(fd); lcd.setCursor(5, 0); delay(200); } if (sw1 == true)//кнопка вниз { fd = fd - 1; if (fd < 0) { fd = 1; } lcd.setCursor(4, 0); lcd.print(fd); lcd.setCursor(5, 0); delay(200); } if (sw4 == true) { lcd.setCursor(9, 0); //lcd.noBlink(); delay(200); break; } } while (5) //установки f5 { debounce(); //читаем кнопки if (sw2 == true)//кнопка вверх { fe = fe + 1; if (fe > 2) { fe = 0; } lcd.setCursor(8, 0); lcd.print(fe); lcd.setCursor(9, 0); delay(200); } if (sw1 == true)//кнопка вниз { fe = fe - 1; if (fe < 0) { fe = 2; } lcd.setCursor(8, 0); lcd.print(fe); lcd.setCursor(9, 0); delay(200); } if (sw4 == true) { lcd.noBlink(); delay(200); break; } } lcd.clear(); lcd.setCursor(4, 0); lcd.print("SETTING"); EEPROM.write(51, fa); //пишем в EEPROM EEPROM.write(52, fb); //пишем в EEPROM EEPROM.write(53, fc); //пишем в EEPROM EEPROM.write(54, fd); //пишем в EEPROM EEPROM.write(55, fe); //пишем в EEPROM яркость светодиодов if (fe == 0) { ledlight = 2; } if (fe == 1) { ledlight = 100; } if (fe == 2) { ledlight = 254; } delay (500); beep(50); beep(50); delay (500); lcd.clear(); } void receiver() // слушаем эфир 433 Мгц ******************************************************************* { int temp; byte recivewait; int x = 1; // индикация считывания температуры unsigned long value; float temp2; byte p1; p1 = EEPROM.read(52); //читаем в EEPROM звук приема есть\нет recivewait = EEPROM.read(51); byte e1, e2; if (mySwitch.available()) // если что-то принято, начинаем разбор передачи { value = mySwitch.getReceivedValue(); if (value > 100 && value < 400) // принята температура { temp = value; temp2 = float (temp); termo2 = temp2 / 10; timer433 = 0; // сбрасываем таймер for (x = 1; x < 4; x++) { analogWrite (led1, (ledlight / 2)); delay(100); analogWrite (led1, 0); delay(100); } if (p1 == 1) { beep(50); } if (EEPROM.read(25) == 1) //если были на дистанцинном то на него и возврат { flagtermo = 1; } } mySwitch.resetAvailable(); } if ( timer433 > recivewait) //отсутствие приема { termo2 = 99.9; timer433 = 0; // сбрасываем таймер flagtermo = 0; //переходим на внутренний датчик termokey = termo1; if (EEPROM.read(41) == 0) //если ошибка еще не записана, то пишем { EEPROM.write(41, 1); } } } void debounce() //убираем дребезг кнопок и опрашиваем кнопки ******************************** { Bounce bouncer1 = Bounce(swich1, 5); Bounce bouncer2 = Bounce(swich2, 5); Bounce bouncer4 = Bounce(swich4, 5); wdt_reset(); //сбрасываем watchdog if ( bouncer1.read() == HIGH) //нажатие кнопки1 вниз { sw1 = true; beep(50); } else { sw1 = false; } if ( bouncer2.read() == HIGH) //нажатие кнопки2 вверх { sw2 = true; beep(50); } else { sw2 = false; } if ( bouncer4.read() == HIGH) //нажатие кнопки4 enter { sw4 = true; beep(50); } else { sw4 = false; } } // проверяем день у нас или ночь***************************************************** void nightcontrol() { int hour; hour = Clock.getHour(h12, PM); // if (hour == nightstart) { flagnight = true; } if (hour == nightend) { flagnight = false; } } // *************************** обработка ошибoк *************************************** void errors() { byte ea, eb, ec, ed, ee; byte x; ea = EEPROM.read(41); eb = EEPROM.read(42); ec = EEPROM.read(43); ed = EEPROM.read(44); ee = EEPROM.read(45); x = (ea + eb + ec + ed + ee); if (x != 0) { analogWrite (led1, (ledlight / 2)); // если есть ошибки то горит светодиод led1 } else { analogWrite (led1, 0); } }Посмотрел на него, спустя 2 года ...... это кошмар 0_0
Вот код дистанционного датчика
#include <OneWire.h> //подключаем шину 1-ware #include <Wire.h> #include <RCSwitch.h> #include "LedControl.h" //#include <avr/wdt.h> //#include <EEPROM.h> //включаем EEPROM LedControl lc=LedControl(12,11,10,1); float f = 0; //число для вывода на дисплей int f2; //вывод на диплей целого числа int LedLight = 1; //яркость дисплея int TSensorPin = 5;//датчик температуры на 5 выводе int termo; //температура для передачи в эфир OneWire ds(TSensorPin);// создаем объект температурного датчика RCSwitch mySwitch = RCSwitch(); //передатчик int transtime=30; //переменная времени отправки unsigned long timer=0, prevtimer=0,prevtimer2=0, t1, t2; //таймеры прерываний void setup() { mySwitch.enableTransmit(7); // пин,на который подключен передатчик // Serial.begin(9600); lc.shutdown(0,false); lc.setIntensity(0,1); lc.clearDisplay(0); //wdt_enable (WDTO_8S); //запуск watchdog } void loop() { float termoset; timer=millis(); if (timer-prevtimer > 5000) // иногда измеряем температуру { termoset = getTemp(); //получаем и преобразуем температуру для отправки f = termoset; prevtimer=timer; SetBright(); //определяем яркость дисплея } if (timer-prevtimer2 > transtime*1000) // иногда отправляем в эфир температуру { sendRC(); prevtimer2=timer; } output(); //вывод на дисплей температуры //wdt_reset(); //сбрасываем watchdog } // ***********************************MAX7219 ИНДИКАЦИЯ***************** void output() { float hundreds; //десятки float tens; //единицы float ones; //дусятые boolean floatPoint = false; int data1, data2, data3; //смотрим дробное у нас число или нет if (int(f * 10) != int(f) * 10) { floatPoint = true; // число дробное } else { floatPoint = false; // число не дробное } //потрошим число на сотни, десятки и единицы //выделяем десятки hundreds=(int(f) / 10); data1 = int(hundreds); //выделяем единицы tens=(int(f) % 10); data2=int(tens); //выделяем десятые ones=((f-int(f))*10); data3 = int(ones); if (data1 == 0) data1=17; //если число < 10 то рисуем пустышку lc.setDigit(0,3,data1,false); lc.setDigit(0,2,data2,true); //точка включена всегда lc.setDigit(0,1,data3,false); if (floatPoint == false) { lc.setDigit(0,1,0,false); //число не дробное рисуем 0 } lc.setRow(0,0,B01100011); //знак градуса } ///***********************Яркость дисплея***************************** void SetBright() { long int j; // Прикладываем обратное напржение - это зарядит собственную емкость вывода 2 pinMode(2, OUTPUT); pinMode(3, OUTPUT); digitalWrite(2, HIGH); digitalWrite(3, LOW); pinMode(2, INPUT); // Переключаем 2й вывод на вход digitalWrite(2, LOW); // и отключаем на нем подтягивающий резистор // Считаем сколько времени потребуется, чтобы емкость разрядилась до логич. 0 for ( j = 0; j < 128000; j++) { if (digitalRead(2)==0) break; } if (j > 7000) //очень яркий свет { LedLight=1; } else { LedLight=7; } lc.setIntensity(0,LedLight); } //***************************************************** //Функции чтения с датчика температуры float getTemp() { byte data[12]; byte addr[8]; if ( !ds.search(addr)) { //no more sensors on chain, reset search ds.reset_search(); return 99; } if ( OneWire::crc8( addr, 7) != addr[7]) { return 99; } if ( addr[0] != 0x10 && addr[0] != 0x28) { return 99; } ds.reset(); ds.select(addr); ds.write(0x44,1); byte present = ds.reset(); ds.select(addr); ds.write(0xBE); output(); for (int i = 0; i < 9; i++) { data[i] = ds.read(); output(); } ds.reset_search(); byte MSB = data[1]; byte LSB = data[0]; float TRead = ((MSB<<8) | LSB); float Temperature = TRead / 16; return Temperature; } // подпрограмма отправки данных 433mHz void sendRC () // 433 { float t, t2; int code; if (f > 1 && f < 40) { t2 = f; t = t2 * 10; code = int(t); mySwitch.send(code, 20); //и моргаем светодиодом pinMode(2, OUTPUT); pinMode(3, OUTPUT); digitalWrite(2, LOW); analogWrite(3, 1); delay(300); digitalWrite(2, LOW); digitalWrite(3, LOW); } }Не менее кошмарно. + Почемуто забыл активировать watchdog в "передатчике"...) Однако все работает нормально )
Stas046 добавь пожалуйста схемы подключений головного устройсва и выносного датка
Так как по "молодости" лепил все "из головы" целиком все не нарисовал, а зря :( . Хорошо хоть листочки набросков сохранил. Чтобы все восстановить займет 1-2 вечера. Перересую все на листок, а если терпения хватит то в sPlan`е. Это сейчас дорос до sPlan, Sprint Layout, ЛУТа, тиньки всякие... а тогда еще учился )))) Опять на код смотрю....это пипец, сейчас-бы все переделал, но все работает без проблем.
не совсем понял как этот термостат на работу котла влияет....чем регулирует работу котла?
В навесных котлах а впрочем и в напольном варианте есть подключение комнатного датчика (это я говорю про новые модели котлов :) а не про те где уголь или дрова закидуюся лопатой, руками, ведрами на выбор ) и через эти контакты и упровляет прибор температурой отопительного контура
В зависимости от температуры в помещении включает или выключает котел. В котле есть спецом для этого контакты: замкнуты-вкл., разомкнуты-выкл. У меня BAXI Main four 24.
Да стас а чтобы ты хотел переделать в своем проэкте ?
В зависимости от температуры в помещении включает или выключает котел. В котле есть спецом для этого контакты: замкнуты-вкл., разомкнуты-выкл. У меня BAXI Main four 24.
все ясно спасибо за пояснения
у меня была идея по тому же принципу регулирования ручку на регуляторе серврприводом таскать...но выключить смогу а вот главное включить уже не получиться...тока больше меньше и все(
Да стас а чтобы ты хотел переделать в своем проэкте ?
Логика работы остается та-же, она меня полностью устраивает. Но вот сам код.... Он-то рабочий, но если мягко, не красивый )))) Нубства там много )))) Это по сути, вторая вещь на МК которую я сделал (после простенького контроллера для аквариума).
Например:
pinMode (swich1, INPUT);
можно вообще не объявлять, ноги и так по умолчанию настроены на вход, delay много, подтягивающие резисторы у меня внешние-нафиг, внутренних за-глаза ну и тд. Это все от переизбытка памяти в 328 меге )))) По-нормальному там и 8ки должно хватить. Сейчас "заболел" тиньками-13, а там всего 1Кб памяти! Борьба идет за каждый байт, вот где начинаешь оптимально прогу писать.
Да стас а чтобы ты хотел переделать в своем проэкте ?
Логика работы остается та-же, она меня полностью устраивает. Но вот сам код.... Он-то рабочий, но если мягко, не красивый )))) Нубства там много )))) Это по сути, вторая вещь на МК которую я сделал (после простенького контроллера для аквариума).
Например:
pinMode (swich1, INPUT);
можно вообще не объявлять, ноги и так по умолчанию настроены на вход, delay много, подтягивающие резисторы у меня внешние-нафиг, внутренних за-глаза ну и тд. Это все от переизбытка памяти в 328 меге )))) Сейчас "заболел" тиньками-13, а там всего 1Кб памяти! Борьба идет за каждый байт, вот где начинаешь оптимально прогу писать.
В навесных котлах а впрочем и в напольном варианте есть подключение комнатного датчика (это я говорю про новые модели котлов :) а не про те где уголь или дрова закидуюся лопатой, руками, ведрами на выбор ) и через эти контакты и упровляет прибор температурой отопительного контура
Отстали от жизни. Сейчас это возможно и на котлах с дровами.
Отстали от жизни. Сейчас это возможно и на котлах с дровами.
:) :) :)
кода я еще работал по сервису котлов (лет 10 назад) то и горелки были на лузге от подсолничника
и автоматическая подача топлива в топку котла (уголь, угольная пыль) но это было в промышленных
масштабах
Головное устройство. На самом деле в одном устройстве трудится ProMini прошитая в uno, а в другом ужу голая atmega328 с объвязкой. Но сути это не меняет.
Дистанционный датчик. Также, ProMini ставшая UNO или 328я с объвязкой. Индикация на МАХ7219 (хотелось мне попробывать эту штучку), можно переделать на регистрах, можно и напрямую к меге, но это уже будет динамическая индикация. Там свои камни. Обратите внимание на конденсатор С5, его нужно припаять как можно ближе к ножкам микросхемы или прямо к ним. Несколько 7219 работали без него, а некоторые нет. Вообще, считается хорошим тоном на каждый корпус микросхемы ставить по одному конденсатору.
Stas046 спасибо огромное за схемы подключений вашых устройств да помоему и в первом можно было поставить просто ATmeua328 попробую переделать ваши исходники в баском авр порезультатам отпишусь :-))
Дмитрий
Спасибо за проект, собрал, работает. Но вот с радиомодулями как-то не задалось, постоянные глюки. Кто-нибудь может переделать скетчи на nRF24L01?