Здравствуйте. Помогите мне найти ошибку в программе – или подскажите, как поправить. В общем сделал я контроллер для аквариума: 5 реле, датчик температуры, часы реального времени, инфракрасный приемник. В общем в зависимости от режима работы (флаг света = 0 – автоматический режим, =1 – включен, =0 –выключен, и флаг остального оборудования так же.) происходило управление –если режим авто – то соответственно свет включался и выключался в заданное время и оборудование тоже включалось по определенным условиям – в зависимости от температуры или времени. Переключение флага сделал через инфракрасный пульт (по умолчанию, после включения питания все флаги стоят в авторежиме) и все нормально работало – но потом решил добавить блок синезуба, чтобы с телефона можно было управлять. Соответственно удалил или закоментил все выводы в сериал порт, кроме показ температуры (чтобы программа на андроиде получала по сериалу эти циферки и показывала). Далее ввел дополнительные условия полученных данных из серала (строки после войд луп и до условия с пульта ИР) телефон передавал цифры от 0 до 6 – и соответственно по этим цифрам менялись флаг света и оборудования. Но тут устройство затупило. Вероятно я все это очень криво сделал, или где то накосячил с { }. В общем симптомы такие – на пульт вообще не реагирует, при нажатии кнопки в программе андроида (передача сигналов 1-6, 0 устанавливается первоначально) периодически щелкает реле и показывает температуру в программе (нажал кнопку – через пару секунд поменялась температура) – в общем ощущение, что условия у меня пошли как то неправильно работать. В общем товарищи – подскажите, что нужно поменять – или где я накосячил????? Файл для андроид в mit app inventor http://vk.com/doc3522071_361298844?hash=74b5dfefd79f791305&dl=9258df8293097fd561 Код (Text): #include <OneWire.h> #include <DallasTemperature.h> #include <Wire.h> #include <DS1307new.h> #include <IRremote.h> #define ONE_WIRE_BUS 2 //на 2 пин подключаем датчик температуры OneWire oneWire(ONE_WIRE_BUS); // Pass our oneWire reference to Dallas Temperature. DallasTemperature sensors(&oneWire); //для часиков uint16_t startAddr = 0x0000; // Начальный адрес для хранения в NV-RAM uint16_t lastAddr; // новый адрес для хранения в NV-RAM uint16_t TimeIsSet = 0xaa55; // По этой переменной проверяется то, что время не нужно устанавливать заново int Relay1 = 3; //реле на нагреватель int Relay2 = 4; // реле на воздух int Relay3 = 6; // реле на фильтр int Relay4 = 7; // реле на свет int Relay5 = 8; // реле на кулеры int theat=24; //температура при которой включается нагреватель int tcool=29; //температура при которой включается кулер int svet = 0; //флаг по умолчанию равен нулю - свет int oborud = 0; //флаг по умолчанию равен нулю - все остальное оборудование int av=0;//флаг по умолчанию равен одному - auto режим int vkl = 9; //время (в часах), когда включается свет - первый интервал int vykl = 15; //время (в часах), когда выключается свет второй интервал int vkl2 = 18; //время (в часах), когда включается свет - второй интервал int vykl2 = 21; //время (в часах), когда выключается свет - второй интервал int vklvozduh = 4; //время (в часах), когда включается компрессор int vyklvozduh = 6; //время (в часах), когда включается компрессор int RECV_PIN = 11; // пин на инфракрасный приемник char incomingByte; // переменная для входящих значений по сериал порту // Инициализация ИК приемника IRrecv irrecv(RECV_PIN); decode_results results; void setup(void) { pinMode(Relay1, OUTPUT); //ставим силовые реле на выход pinMode(Relay2, OUTPUT); pinMode(Relay3, OUTPUT); pinMode(Relay4, OUTPUT); pinMode(Relay5, OUTPUT); digitalWrite(3, HIGH);// Выключаем реле (у меня обратное реле, т.е. HIGH - выключено, LOW - включено - у кого наоборот поменяйте все HIGH на LOW digitalWrite(4, HIGH); digitalWrite(6, HIGH); digitalWrite(7, HIGH); digitalWrite(8, HIGH); Serial.begin(9600); irrecv.enableIRIn(); // Включение IR приемника int on = 0; // для IR unsigned long last = millis(); // для IR // Запускаем наши часики (RTC) RTC.setRAM(0, (uint8_t *)&startAddr, sizeof(uint16_t)); RTC.getRAM(54, (uint8_t *)&TimeIsSet, sizeof(uint16_t)); if (TimeIsSet != 0xaa55) { RTC.stopClock(); RTC.fillByYMD(2015,01,24); //устанавливаем дату RTC.fillByHMS(23,57,0); //устанавливаем время RTC.setTime(); TimeIsSet = 0xaa55; RTC.setRAM(54, (uint8_t *)&TimeIsSet, sizeof(uint16_t)); RTC.startClock(); } else { RTC.getTime(); } RTC.setCTRL(); sensors.begin(); } void loop(){ if (Serial.available() > 0) { // далее проверяет прход по сериал порту - например от bluetooth и в зависимости от цифры - выставляет флаги incomingByte = Serial.read(); // 0 - все авто. 1- свет авто, 2 - свет вкл, 3 - свет выкл, 4 - оборудование - авто, 5 оборудование вкл if(incomingByte == '0') { // 6 - оборудование выкл oborud=0; svet=0; } if(incomingByte == '1') { svet=0; } incomingByte = Serial.read(); if(incomingByte == '2') { svet=1; } if(incomingByte == '3') { svet=2; } incomingByte = Serial.read(); if(incomingByte == '4') { oborud=0; } if(incomingByte == '5') { oborud=1; } if(incomingByte == '6') { oborud=2; } {if (irrecv.decode(&results)) { ///Далее идет код проверки IR датчика //Serial.println(results.value); //вывожу код нажатой кнопки в сериал - там можете узнать свой код...(если надо узнать код - раскоменте) if (results.value==3672802284) {// Кнопка "A" - переключает режимы света поменяйте на свой код кнопки if (svet==0) { //устанавливаю режимы флага света на последовательное переключение - 0 - auto, 1 - вкл, 2 - выкл - и далее по кругу svet=1;} else if (svet==1) { svet=2;} else{ svet=0;} } if (results.value==732942060) {// Кнопка "B" - включает и отключает оборудование поменяйте на свой код if (oborud==0) {//устанавливаю режимы флага оборудования на последовательное переключение - 0 - auto, 1 - вкл, 2 - выкл - и далее по кругу oborud=1;} else if (oborud==1) { oborud=2;} else{ oborud=0;} } irrecv.resume(); // Получение нового значения через пульт } switch (svet) { //блок управления светом case 2:// если свет выключен //Serial.println("Svet vykluchen"); digitalWrite(7, HIGH); break; case 1:// если свет включен //Serial.println("Svet vkluchen"); digitalWrite(7, LOW); break; case 0: // оборудование в авто режиме (по умолчанию - при отключении от эл-ва автоматом включается) //Serial.println("Svet auto"); RTC.getTime(); if ((vkl < RTC.hour & RTC.hour < vykl) | (vkl2 < RTC.hour & RTC.hour < vykl2) ) // если время больше времени включения и меньше времени выключения (в часах), включаем свет - иначе - отключаем {digitalWrite(7, LOW);} else {digitalWrite(7, HIGH);} break; } switch (oborud) { //блок управления оборудованием (кроме света) case 2:// если все оборудование выключено // Serial.println("Oborudovanie vykluchen"); digitalWrite(3, HIGH); digitalWrite(4, HIGH); digitalWrite(6, HIGH); digitalWrite(8, HIGH); break; case 1:// если все оборудование включено // Serial.println("Oborudovanie vkluchen"); digitalWrite(3, LOW); digitalWrite(4, LOW); digitalWrite(6, LOW); digitalWrite(8, LOW); break; case 0: // оборудование в авто режиме (по умолчанию - при отключении от эл-ва автоматом включается) //Serial.println("Oborudovanie auto"); digitalWrite(6, LOW); //фильтр включен всегда sensors.requestTemperatures(); // запрашиваем данные датчика температуры float temp = sensors.getTempCByIndex(0); // привязываем переменную temp к запросу датчика if (temp< theat){ //если температура меньше theat то включить нагреватель, иначе - выключить digitalWrite(3, LOW);} else { digitalWrite(3, HIGH);} sensors.requestTemperatures();// запрашиваем данные датчика температуры if (temp>tcool){ //если температура больше tcool то включить кулеры, иначе - выключить digitalWrite(4, LOW);} else { digitalWrite(4, HIGH);} Serial.println(temp); RTC.getTime();// запрашиваем время if (vklvozduh < RTC.hour & RTC.hour < vyklvozduh) // если время больше времени включения компрессора и меньше времени выключения компрессора (в часах), включаем пузырьки :) {digitalWrite(8, LOW);} else {digitalWrite(8, HIGH);} break; } }}}
Не экономьте время, при написании программы, очень важно, удобство чтения кода. Вот как правильно должен выглядеть Ваш код (не вносил изменений, только отступы и привел скобочки к более наглядному виду), в таком коде сложнее ошибиться. Код (Text): #include <OneWire.h> #include <DallasTemperature.h> #include <Wire.h> #include <DS1307new.h> #include <IRremote.h> #define ONE_WIRE_BUS 2 //на 2 пин подключаем датчик температуры OneWire oneWire(ONE_WIRE_BUS); // Pass our oneWire reference to Dallas Temperature. DallasTemperature sensors(&oneWire); //для часиков uint16_t startAddr = 0x0000; // Начальный адрес для хранения в NV-RAM uint16_t lastAddr; // новый адрес для хранения в NV-RAM uint16_t TimeIsSet = 0xaa55; // По этой переменной проверяется то, что время не нужно устанавливать заново int Relay1 = 3; //реле на нагреватель int Relay2 = 4; // реле на воздух int Relay3 = 6; // реле на фильтр int Relay4 = 7; // реле на свет int Relay5 = 8; // реле на кулеры int theat=24; //температура при которой включается нагреватель int tcool=29; //температура при которой включается кулер int svet = 0; //флаг по умолчанию равен нулю - свет int oborud = 0; //флаг по умолчанию равен нулю - все остальное оборудование int av=0;//флаг по умолчанию равен одному - auto режим int vkl = 9; //время (в часах), когда включается свет - первый интервал int vykl = 15; //время (в часах), когда выключается свет второй интервал int vkl2 = 18; //время (в часах), когда включается свет - второй интервал int vykl2 = 21; //время (в часах), когда выключается свет - второй интервал int vklvozduh = 4; //время (в часах), когда включается компрессор int vyklvozduh = 6; //время (в часах), когда включается компрессор int RECV_PIN = 11; // пин на инфракрасный приемник char incomingByte; // переменная для входящих значений по сериал порту // Инициализация ИК приемника IRrecv irrecv(RECV_PIN); decode_results results; void setup(void) { pinMode(Relay1, OUTPUT); //ставим силовые реле на выход pinMode(Relay2, OUTPUT); pinMode(Relay3, OUTPUT); pinMode(Relay4, OUTPUT); pinMode(Relay5, OUTPUT); digitalWrite(3, HIGH);// Выключаем реле (у меня обратное реле, т.е. HIGH - выключено, LOW - включено - у кого наоборот поменяйте все HIGH на LOW digitalWrite(4, HIGH); digitalWrite(6, HIGH); digitalWrite(7, HIGH); digitalWrite(8, HIGH); Serial.begin(9600); irrecv.enableIRIn(); // Включение IR приемника int on = 0; // для IR unsigned long last = millis(); // для IR // Запускаем наши часики (RTC) RTC.setRAM(0, (uint8_t *)&startAddr, sizeof(uint16_t)); RTC.getRAM(54, (uint8_t *)&TimeIsSet, sizeof(uint16_t)); if (TimeIsSet != 0xaa55) { RTC.stopClock(); RTC.fillByYMD(2015,01,24); //устанавливаем дату RTC.fillByHMS(23,57,0); //устанавливаем время RTC.setTime(); TimeIsSet = 0xaa55; RTC.setRAM(54, (uint8_t *)&TimeIsSet, sizeof(uint16_t)); RTC.startClock(); } else { RTC.getTime(); } RTC.setCTRL(); sensors.begin(); } void loop() { if (Serial.available() > 0) { // далее проверяет прход по сериал порту - например от bluetooth и в зависимости от цифры - выставляет флаги incomingByte = Serial.read(); // 0 - все авто. 1- свет авто, 2 - свет вкл, 3 - свет выкл, 4 - оборудование - авто, 5 оборудование вкл if(incomingByte == '0') // 6 - оборудование выкл { oborud=0; svet=0; } if(incomingByte == '1') { svet=0; } incomingByte = Serial.read(); if(incomingByte == '2') { svet=1; } if(incomingByte == '3') { svet=2; } incomingByte = Serial.read(); if(incomingByte == '4') { oborud=0; } if(incomingByte == '5') { oborud=1; } if(incomingByte == '6') { oborud=2; } { if (irrecv.decode(&results)) ///Далее идет код проверки IR датчика { //Serial.println(results.value); //вывожу код нажатой кнопки в сериал - там можете узнать свой код...(если надо узнать код - раскоменте) if (results.value==3672802284) // Кнопка "A" - переключает режимы света поменяйте на свой код кнопки { if (svet==0) //устанавливаю режимы флага света на последовательное переключение - 0 - auto, 1 - вкл, 2 - выкл - и далее по кругу { svet=1; } else if (svet==1) { svet=2; } else { svet=0; } } if (results.value==732942060) // Кнопка "B" - включает и отключает оборудование поменяйте на свой код { if (oborud==0) //устанавливаю режимы флага оборудования на последовательное переключение - 0 - auto, 1 - вкл, 2 - выкл - и далее по кругу { oborud=1; } else if (oborud==1) { oborud=2; } else { oborud=0; } } irrecv.resume(); // Получение нового значения через пульт } switch (svet) //блок управления светом { case 2:// если свет выключен //Serial.println("Svet vykluchen"); digitalWrite(7, HIGH); break; case 1:// если свет включен //Serial.println("Svet vkluchen"); digitalWrite(7, LOW); break; case 0: // оборудование в авто режиме (по умолчанию - при отключении от эл-ва автоматом включается) //Serial.println("Svet auto"); RTC.getTime(); if ((vkl < RTC.hour & RTC.hour < vykl) | (vkl2 < RTC.hour & RTC.hour < vykl2) ) // если время больше времени включения и меньше времени выключения (в часах), включаем свет - иначе - отключаем { digitalWrite(7, LOW); } else { digitalWrite(7, HIGH); } break; } switch (oborud) //блок управления оборудованием (кроме света) { case 2:// если все оборудование выключено // Serial.println("Oborudovanie vykluchen"); digitalWrite(3, HIGH); digitalWrite(4, HIGH); digitalWrite(6, HIGH); digitalWrite(8, HIGH); break; case 1:// если все оборудование включено // Serial.println("Oborudovanie vkluchen"); digitalWrite(3, LOW); digitalWrite(4, LOW); digitalWrite(6, LOW); digitalWrite(8, LOW); break; case 0: // оборудование в авто режиме (по умолчанию - при отключении от эл-ва автоматом включается) //Serial.println("Oborudovanie auto"); digitalWrite(6, LOW); //фильтр включен всегда sensors.requestTemperatures(); // запрашиваем данные датчика температуры float temp = sensors.getTempCByIndex(0); // привязываем переменную temp к запросу датчика if (temp< theat) //если температура меньше theat то включить нагреватель, иначе - выключить { digitalWrite(3, LOW); } else { digitalWrite(3, HIGH); } sensors.requestTemperatures();// запрашиваем данные датчика температуры if (temp>tcool)//если температура больше tcool то включить кулеры, иначе - выключить { digitalWrite(4, LOW); } else { digitalWrite(4, HIGH); } Serial.println(temp); RTC.getTime();// запрашиваем время if (vklvozduh < RTC.hour & RTC.hour < vyklvozduh) // если время больше времени включения компрессора и меньше времени выключения компрессора (в часах), включаем пузырьки :) { digitalWrite(8, LOW); } else { digitalWrite(8, HIGH); } break; } } } } И сразу видим ошибки не вооруженным глазом.
Пришлось разбить сообщение не поместилось. Код (Text): { if (irrecv.decode(&results)) ///Далее идет код проверки IR датчика { Что это, видимо был удален if но открывающие и закрывающие скобки (3-я снизу) остались. Код (Text): if (svet==0) //устанавливаю режимы флага света на последовательное переключение - 0 - auto, 1 - вкл, 2 - выкл - и далее по кругу { svet=1; } else if (svet==1) { svet=2; } else { svet=0; } Код (Text): if (oborud==0) //устанавливаю режимы флага оборудования на последовательное переключение - 0 - auto, 1 - вкл, 2 - выкл - и далее по кругу { oborud=1; } else if (oborud==1) { oborud=2; } else { oborud=0; } Почему в одном случае с else Вы пользуетесь скобочками, другом нет? Более подробно с if else можно ознакомится тут. Если правильно понял мысль, на ардуину передается число от 1 до 6, тогда поменяйте работу с Serial. Код (Text): void loop() { int val = 0; if (Serial.available()>0) { val = Serial.parseInt(); } // Дальше Ваш код, анализирует полученное число } Дальше не смотрел, начните с этого.
Вместо Код (Text): if (oborud==0) //устанавливаю режимы флага оборудования на последовательное переключение - 0 - auto, 1 - вкл, 2 - выкл - и далее по кругу { oborud=1; } else if (oborud==1) { oborud=2; } else { oborud=0; } пишите Код (Text): oborud++; if(oborud == 2) oborud = 0; или Код (Text): if(++oborud == 3) oborud = 0; Меньше кода, лучше читаемость. Аналогично с переменной svet.
Все верно, не перерабатывал код, просто искал ошибки. Но во по поводу Код (Text): if(++oborud == 3) oborud = 0; не соглашусь, мне кажется лучше будет так, Код (Text): if(++oborud == 3) { oborud = 0; } но как говорится дело вкуса. UPD. Ошибся по 2 пункту, это не ошибка. Код (Text): if (oborud==0) //устанавливаю режимы флага оборудования на последовательное переключение - 0 - auto, 1 - вкл, 2 - выкл - и далее по кругу { oborud=1; } else if (oborud==1) { oborud=2; } else { oborud=0; } Данный код рабочий, но это уже C, подробнее тут. Если кому интересно, можете посмотреть. Код (Text): void setup() { Serial.begin(115200); } void loop() { int val = 0; if (Serial.available()>0) { val = Serial.parseInt(); //Serial.println(val); // if (val == 1)val++; // Serial.println(val); // if (val == 1) // val++; // Serial.println(val); if (val==0) { val++; } else //val++; if (val==1) { val=10; } else { val=11; } Serial.println(val); } } Но для меня он сложнее в прочтении, поэтому остаюсь при своих скобочках.
Возможно - с программированием я не очень. Но пытаюсь разобраться через видео уроки и примеры - анализируя разные примеры смог собрать вот такую сборную солянку - для себя все откомментил (чтобы не забыть где что ) - я так понимаю, что я как бы лишний блок сделал? т.е. третья снизу фигурная скобка закрывающая - должна быть удалена и соответсвующая ей октрывающая скобка тоже? у меня вообще со всеми этими скобками проблема -как то в бейсике в школе их не было в смысле когда указано (svet==0) ? лучше все эти скобки вообще убрать? Для анализа наверно лучше тогда воспользоваться не условием if а выбором? CASE? Спасибо - так действительно проще. Вечером попробую исправить и оптимизировать
и еще - я так понимаю, с получением данных по bluetooth - мне лучше часть кода заменить: Код (Text): if (Serial.available() > 0) { // далее проверяет прход по сериал порту - например от bluetooth и в зависимости от цифры - выставляет флаги incomingByte = Serial.read(); // 0 - все авто. 1- свет авто, 2 - свет вкл, 3 - свет выкл, 4 - оборудование - авто, 5 оборудование вкл if(incomingByte == '0') { // 6 - оборудование выкл oborud=0; svet=0; } if(incomingByte == '1') { svet=0; } incomingByte = Serial.read(); if(incomingByte == '2') { svet=1; } if(incomingByte == '3') { svet=2; } incomingByte = Serial.read(); if(incomingByte == '4') { oborud=0; } if(incomingByte == '5') { oborud=1; } if(incomingByte == '6') { oborud=2; } На: Код (Text): int val = 0; if (Serial.available() > 0)// далее проверяет прход по сериал порту - например от bluetooth и в зависимости от цифры - выставляет флаги { // 0 - все авто. 1- свет авто, 2 - свет вкл, 3 - свет выкл, 4 - оборудование - авто, 5 оборудование вкл val = Serial.parseInt(); // 6 - оборудование выкл } switch (val) { case 0: oborud=0; svet=0; break; case 1: svet=0; break; case 2: svet=1; break; case 3: svet=2; break; case 4: oborud=0; break; case 5: oborud=1; break; case 6: oborud=2; break; }
Да, остался лишний блок. Увы придется учится, поищите на форуме достойную книгу для начинающих. Думаю она позволит ускорить процесс обучения. Нет, эти скобки обязательны, типичный if можно записать несколькими способами Вариант 1 Код (Text): if (svett==0) { i++; } Вариант 2 Код (Text): if (svett==0) i++; Но вариант 2, не стал бы советовать начинающим. Причина в том, что он мене читабельный и может стать причиной ошибки. Предположим, что нам нужно написать условие, если svett==0, то необходимо добавить 1 к переменой i и добавить 2 к переменой e. Если просто добавить e+= 2; к варианту 2, он будет выполнен не так как ожидаем. Код (Text): if (svett==0) i++; e+= 2; i++; будет выполнено только если svett==0, а e+= 2; будет выполнено, не зависимо от значения переменой svett. А вариант 1, i++ и e+=2 будет выполнен только если svett==0 Код (Text): if (svett==0) { i++; e+= 2; } Поэтому и не рекомендую, Ваш код в этом месте был рабочим но у меня не хватает знаний пояснить почему. Можете проверить, взяв мой код для теста и поиграться с вариантами. Код (Text): void setup() { Serial.begin(115200); } void loop() { int val = 0; if (Serial.available()>0) { val = Serial.parseInt(); //Serial.println(val); // if (val == 1)val++; // Serial.println(val); // if (val == 1) // val++; // Serial.println(val); if (val==0) { val++; } else //val++; if (val==1) { val=10; } else { val=11; } Serial.println(val); } } Но лучше все таки хорошая книга. Да код с использованием switch и Serial.parseInt() будет более логичным.
В общем программу переработал - нифига хорошего не получилось Код (Text): if(++oborud == 3) { oborud = 0; } С этим блоком - как то реакций не было С блоком работы сериала - Код (Text): { int val = 0; if (Serial.available()>0) { val = Serial.parseInt(); } // Дальше Ваш код, анализирует полученное число } После переключения - сразу все скидывалось на 0 - т.е. авторежим. Я тут еще грешу на bluetooth - он у меня какой то глючный - очень много помех идет - в сериал все четко идет, но если подключаю синезуб - помимо цифр еще куча всякого мусора - непонятные символы... Должны через пару недель новые блоки прийти - надеюсь после замены все будет хорошо... В итоге получилась программа (ниже) - которая работает в авто режиме, имеет возможность переключения режимов пультом, но не реагирует на синезуб... Может я конечно еще накосячил в программе - но вроде просмотрел все... Код (Text): #include <OneWire.h> #include <DallasTemperature.h> #include <Wire.h> #include <DS1307new.h> #include <IRremote.h> #define ONE_WIRE_BUS 2 //на 2 пин подключаем датчик температуры OneWire oneWire(ONE_WIRE_BUS); // Pass our oneWire reference to Dallas Temperature. DallasTemperature sensors(&oneWire); //для часиков uint16_t startAddr = 0x0000; // Начальный адрес для хранения в NV-RAM uint16_t lastAddr; // новый адрес для хранения в NV-RAM uint16_t TimeIsSet = 0xaa55; // По этой переменной проверяется то, что время не нужно устанавливать заново int Relay1 = 3; //реле на нагреватель int Relay2 = 4; // реле на воздух int Relay3 = 6; // реле на фильтр int Relay4 = 7; // реле на свет int Relay5 = 8; // реле на кулеры int theat=24; //температура при которой включается нагреватель int tcool=29; //температура при которой включается кулер int svet = 0; //флаг по умолчанию равен нулю - свет int oborud = 0; //флаг по умолчанию равен нулю - все остальное оборудование int av=0;//флаг по умолчанию равен одному - auto режим int vkl = 9; //время (в часах), когда включается свет - первый интервал int vykl = 15; //время (в часах), когда выключается свет второй интервал int vkl2 = 18; //время (в часах), когда включается свет - второй интервал int vykl2 = 21; //время (в часах), когда выключается свет - второй интервал int vklvozduh = 4; //время (в часах), когда включается компрессор int vyklvozduh = 6; //время (в часах), когда включается компрессор int RECV_PIN = 11; // пин на инфракрасный приемник char incomingByte; // переменная для входящих значений по сериал порту // Инициализация ИК приемника IRrecv irrecv(RECV_PIN); decode_results results; void setup(void) { pinMode(Relay1, OUTPUT); //ставим силовые реле на выход pinMode(Relay2, OUTPUT); pinMode(Relay3, OUTPUT); pinMode(Relay4, OUTPUT); pinMode(Relay5, OUTPUT); digitalWrite(3, HIGH);// Выключаем реле (у меня обратное реле, т.е. HIGH - выключено, LOW - включено - у кого наоборот поменяйте все HIGH на LOW digitalWrite(4, HIGH); digitalWrite(6, HIGH); digitalWrite(7, HIGH); digitalWrite(8, HIGH); Serial.begin(9600); irrecv.enableIRIn(); // Включение IR приемника int on = 0; // для IR unsigned long last = millis(); // для IR // Запускаем наши часики (RTC) RTC.setRAM(0, (uint8_t *)&startAddr, sizeof(uint16_t)); RTC.getRAM(54, (uint8_t *)&TimeIsSet, sizeof(uint16_t)); if (TimeIsSet != 0xaa55) { RTC.stopClock(); RTC.fillByYMD(2015,01,29); //устанавливаем дату RTC.fillByHMS(8,50,0); //устанавливаем время RTC.setTime(); TimeIsSet = 0xaa55; RTC.setRAM(54, (uint8_t *)&TimeIsSet, sizeof(uint16_t)); RTC.startClock(); } else { RTC.getTime(); } RTC.setCTRL(); sensors.begin(); } void loop() { if (Serial.available() > 0) { incomingByte = Serial.read(); if (incomingByte==0) { svet=0; oborud=0; } if (incomingByte==1) { svet=0; } if (incomingByte==2) { svet=1; } if (incomingByte==3) { svet=2; } if (incomingByte==4) { oborud=0; } if (incomingByte==5) { oborud=1; } if (incomingByte==6) { oborud=2; } } if (irrecv.decode(&results)) ///Далее идет код проверки IR датчика { //Serial.println(results.value); //вывожу код нажатой кнопки в сериал - там можете узнать свой код... if (results.value==3672802284) // Кнопка "A" - переключает режимы света поменяйте на свой код кнопки { if (svet==0) { //устанавливаю режимы флага света на последовательное переключение - 0 - auto, 1 - вкл, 2 - выкл - и далее по кругу svet=1; //Serial.println("svet=1"); } else if (svet==1) { svet=2; //Serial.println("svet=2"); } else { svet=0; //Serial.println("svet=0"); } } if (results.value==732942060) // Кнопка "B" - включает и отключает оборудование поменяйте на свой код { if (oborud==0) { //устанавливаю режимы флага света на последовательное переключение - 0 - auto, 1 - вкл, 2 - выкл - и далее по кругу oborud=1; // Serial.println("oborud=1"); } else if (oborud==1) { oborud=2; //Serial.println("oborud=2"); } else { oborud=0; //Serial.println("oborud=0"); } } irrecv.resume(); // Получение нового значения через пульт } switch (svet) //блок управления светом { case 2:// если свет выключен digitalWrite(7, HIGH); break; case 1:// если свет включен digitalWrite(7, LOW); break; case 0: // оборудование в авто режиме (по умолчанию - при отключении от эл-ва автоматом включается) RTC.getTime(); if ((vkl < RTC.hour & RTC.hour < vykl) | (vkl2 < RTC.hour & RTC.hour < vykl2) ) // если время больше времени включения и меньше времени выключения (в часах), включаем свет - иначе - отключаем { digitalWrite(7, LOW); } else { digitalWrite(7, HIGH); } break; } switch (oborud) //блок управления оборудованием (кроме света) { case 2:// если все оборудование выключено digitalWrite(3, HIGH); digitalWrite(4, HIGH); digitalWrite(6, HIGH); digitalWrite(8, HIGH); break; case 1:// если все оборудование включено digitalWrite(3, LOW); digitalWrite(4, LOW); digitalWrite(6, LOW); digitalWrite(8, LOW); break; case 0: // оборудование в авто режиме (по умолчанию - при отключении от эл-ва автоматом включается) digitalWrite(6, LOW); //фильтр включен всегда sensors.requestTemperatures(); // запрашиваем данные датчика температуры float temp = sensors.getTempCByIndex(0); // привязываем переменную temp к запросу датчика if (temp< theat) //если температура меньше theat то включить нагреватель, иначе - выключить { digitalWrite(3, LOW); } else { digitalWrite(3, HIGH); } sensors.requestTemperatures();// запрашиваем данные датчика температуры if (temp>tcool)//если температура больше tcool то включить кулеры, иначе - выключить { digitalWrite(4, LOW); } else { digitalWrite(4, HIGH); } Serial.println(temp); RTC.getTime();// запрашиваем время if (vklvozduh < RTC.hour & RTC.hour < vyklvozduh) // если время больше времени включения компрессора и меньше времени выключения компрессора (в часах), включаем пузырьки :) { digitalWrite(8, LOW); } else { digitalWrite(8, HIGH); } break; } }
Код (Text): if(++oborud == 3) { oborud = 0; } Мы прибавляем 1 к переменной oborud (++oborud) и проверяем равно ли условие 3. Чтобы данное условие сработало, до if, oborud должно равняться 2. Более подробно тут. Код (Text): int val = 0; if (Serial.available()>0) { val = Serial.parseInt(); } Да все правильно, просто не вникал в Ваш код, а Вы просто вставили его, даже не разбирая. Предположим нам надо хранить режим в переменой и менять его в зависимости от полученных данных, тогда надо просто сделать int val = 0; глобальной переменной, вынести за пределы loop. Код (Text): int val = 0; void loop() { if (Serial.available()>0) { val = Serial.parseInt(); } } Что здесь будет происходить, ардуина стартует с режимом 0, после получения команды режим меняется, примеру на 2. И до следующей смены режима он остается тем же, то есть 2-ым. С ним не работал. Удачи в проекте и изучении (Там все очень просто, если идти шаг за шагом).
Это я понял - выносил за луп - все равно сбивала почему то на 0. единственный вариант был - представить val к цифре не используемой в условии - например =7 . Но в общем потом вернулся к первоначальному варианту. Так все работает, но проблема в синезубе - он сплошной мусор в эфир кидает и принимает кучу мусора. Я уже намучался с этим синезубом - с уной он вообще не хочет работать (причем как я понял, поискав в инете - у многих такая проблема бывает), вероятнее всего просто глючный. Сейчас заказал несколько разных синезубов - попробую поэксперементировать. Если через сериал команды подаю - то все переключается - специально вводил команды вывода в сериал, чтобы провести отладку. Это я понял - сам удивился, что не захотело нормально работать..... Хотя сейчас пытаюсь вспомнить - возможно это чисто мой глюк был (у меня там провод отсоединился, который как раз шел на пин ir, а я не заметил) - может как раз тогда я этот вариант скетча проверял В общем - пока подключил устройство в таком режиме - а то рыбкам грустно без света и тепла А как придет синезуб - буду дальше шаманить - все атки хочется сделать уже нормальное устройство с возможностью управления через мобильник или планшет... Спасибо. я понял, что тут не сложно - главное алгоритм правильный разработать, да логику продумать... В принципе первоначальный вариант и не включал в себя управление через доп устройства (пульт, телефон) - но хотелки приходят во время еды