Помогите с кодом :)
- Войдите на сайт для отправки комментариев
Пнд, 13/06/2016 - 16:23
База - Ардуино Нано в 3.0
Цель - сделать благое дело и реанимировать кухонную утварь.
Есть печка без мозгов. Стоит пылится. И тут мне пришла в голову гениальная мысль. А не оживить ли ее?! Почитав форумы - сделал выбор в пользу Ардуинки. После вкуривания Справочника языка по Ардуино родился у меня следующий код.
//////////////////////////////////////////////////////// //Определение для часов реального времени ДС1307 #include <Arduino.h> #include <Wire.h> // this #include still required because the RTClib depends on it #include "RTClib.h" RTC_DS1307 rtc; char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"}; ////////////////////////////////////////////////////////// /* Define digital pins used to read the encoder */ #define DT 2 #define CLK 3 #define SW 4 int counter; //переменная для присвоения значений ///////////////////////////////////////////////////////////// //Другое разное int n = 0; //Счетчик цикла byte minTimer = 0; // Таймер работы духовки //////////////////////////////////////////////////////////// //Подключения дисплея #include <LiquidCrystal.h> LiquidCrystal lcd(12, 11, 10, 9, 8, 7); //////////////////////////////////////////////////////////// //Порт и переменная и прочее для поучения значения темпиратуры и вычислений byte analogPin = 0; // номер порта к которому подключен потенциометр int tempInput = 0; // переменная для хранения считываемого значения темпиратуры byte temp = 0; //переменная для хранения заданного значения темпиратуры ///////////////////////////////////////////////////////////// int hotterPin = 15; // Светодиод, подключенный к вход/выходу 13 - ТЭН int coollerPin = 4; // Вентилятор выдува горячего воздуха из корпуса. ////////////////////////////////////////////////////////////// byte timerBuffer = 0; //Промежуточная переменная для вычисления byte midiPin = 6; //Пин звукового сигнала ///////////////////////////////// void setup() { lcd.begin(20, 4); //объявление размеров дисплея (кол-во символов, кол-во строк) // Print a message to the LCD и установка курсора lcd.setCursor(1, 1); lcd.print("Hello :)"); delay(5000); //Определение входов энкодера. pinMode(DT, INPUT); pinMode(CLK, INPUT); pinMode(SW, INPUT); digitalWrite(SW, HIGH); //Определение пина управления теном и вентилдятором, назначает режим работы - выход pinMode(hotterPin, OUTPUT); pinMode(coollerPin, OUTPUT); //Определение пина резонатора pinMode(midiPin, OUTPUT); //кусок от РТЦ. if (! rtc.begin()) { lcd.print("Couldn't find RTC"); while (1); } if (! rtc.isrunning()) { lcd.print("RTC is NOT running!"); // following line sets the RTC to the date & time this sketch was compiled rtc.adjust(DateTime(F(__DATE__), F(__TIME__))); // This line sets the RTC with an explicit date & time, for example to set // January 21, 2014 at 3am you would call: // rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0)); } //конец куска от РТЦ } /* Main program */ void loop() { if (digitalRead(SW) != LOW) //Чтение нажатия кнопки энкодера { ++n; //Прибавление еденички к счетчику цикла while (n == 10000) //вход в цикл измерения параметров, чтения и отображения времени. 1 раз в N оборото. { n = 0; tempInput = analogRead(analogPin); //Чтение значения темпиратуры. *******Нужно провести какие-то пересчеты промежуточные lcd.clear(); lcd.setCursor(4, 0); if (minTimer > 0) //при выполнении условия духовка работает. { //Код работы духовки при значении таймера больше нуля. if (tempInput > temp) //Проверка условия вкл/выкл ТЭНа. { digitalWrite(hotterPin, LOW); // выключает тен духовки } else { digitalWrite(hotterPin, HIGH); // включает тен духовки } DateTime now = rtc.now(); //Чтения текущего времени из РТЦ if (timerBuffer == (now.minute(), DEC)) { // Нет никакого действия } else { minTimer = minTimer - 1; timerBuffer = (now.minute(), DEC); if (minTimer == 0) digitalWrite(hotterPin, LOW); //Выключение ТЭНа for (int i = 0; i <= 30; i++) //Время пищания 30 оборотов { digitalWrite(midiPin, HIGH); delay(400); digitalWrite(midiPin, LOW); delay(200); digitalWrite(midiPin, HIGH); delay(400); digitalWrite(midiPin, LOW); delay(1000); } } }//конец рабочего кода lcd.print("Time left:"); lcd.print(minTimer); lcd.setCursor(2, 2); lcd.print("Temp:"); lcd.print(tempInput); } else //иначе идет индикация времени. { DateTime now = rtc.now(); lcd.print(" ("); lcd.print(daysOfTheWeek[now.dayOfTheWeek()]); lcd.print(") "); lcd.setCursor(6, 1); lcd.print(now.day(), DEC); lcd.print('/'); lcd.print(now.month(), DEC); lcd.print("/"); lcd.print(now.year(), DEC); lcd.setCursor(5, 3); lcd.print("Time:"); lcd.print(now.hour(), DEC); lcd.print(':'); lcd.print(now.minute(), DEC); } if (tempInput > 50) //Проверка услови вкл/выкл вентилятора выдува из корпуса духовки { digitalWrite(coollerPin, HIGH); // включает вентилятор на выдув из корпуса духовки } else { digitalWrite(coollerPin, LOW); //выключает вентилятор на выдув из корпуса духовки } } //конец цикла измерения параметров и отображения времени. else { goToMenu(); } } //Конец цикла всей программы /*************************Обработка энкодера**************/ void encoder() { byte DialPos; byte Last_DialPos; /* Read the status of the dial */ DialPos = (digitalRead(CLK) << 1) | digitalRead(DT); /* Is the dial being turned anti-clockwise? */ if (DialPos == 3 && Last_DialPos == 1) { counter--; } /* Is the dial being turned clockwise? */ if (DialPos == 3 && Last_DialPos == 2) { counter++; } /* Save the state of the encoder */ Last_DialPos = DialPos; } /**********************Menu*************************/ void goToMenu() //Переход есть. Расписать все красиво. Привязать к энкодеру. { while (1) { byte var = 0; encoder(); if ( counter > 6) counter = 1; var = counter; lcd.clear(); lcd.print("Rotate the knob to select menu. Press the knob to select."); if (var == 1 && digitalRead(SW) = LOW) { menuOne(); } else if (var == 2 && digitalRead(SW) = LOW) { menuTwo(); } else if (var == 3 && digitalRead(SW) = LOW) { menuThree(); } else if (var == 4 && digitalRead(SW) = LOW) { menuFour(); } else if (var == 5 && digitalRead(SW) = LOW) { menuFive(); } else if (var == 6 && digitalRead(SW) = LOW) { menuSix(); } } menuExit: } /**************меню - 1 - установка таймера в минутах**********/ void menuOne () { while (digitalRead(SW) == LOW) { encoder (); if (counter > 240) counter = 240; lcd.clear(); minTimer = counter; lcd.print("Timer:"); lcd.print(minTimer); lcd.print("min"); delay(300); } counter = 0; } /**************меню - 2 - установка темпиратуры**********/ void menuTwo () { while (digitalRead(SW) == LOW) { encoder (); if ( counter > 220) counter = 220; lcd.clear(); temp = counter; lcd.print("Temp"); lcd.print(temp); lcd.print("C"); delay(300); } counter = 0; } /**************меню - 3 - обнуление таймера и термпиратуры**********/ void menuThree () { while (digitalRead(SW) == LOW) { lcd.print("Press OK to resrt Timer and Temp."); } minTimer = 0; temp = 0; } /**************меню - 4 - установка времени**********/ void menuFour () { int yy = 0; byte mon = 0; byte dd = 0; byte hh = 0; byte mm = 0; // This line sets the RTC with an explicit date & time, for example to set // January 21, 2014 at 3am you would call: // rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0)); counter = 2016; //Присваивание 2016 для первого значения года while (digitalRead(SW) == LOW) //Установка года { encoder (); lcd.clear(); yy = counter; lcd.print("Year:"); lcd.print(yy); delay(300); } counter = 1; while (digitalRead(SW) == LOW) // Установка месяца { encoder (); if ( counter > 12) counter = 0; lcd.clear(); mon = counter; lcd.print("Month"); lcd.print(mon); delay(300); } counter = 1; while (digitalRead(SW) == LOW) // Установка даты { encoder (); if ( counter > 31) counter = 0; lcd.clear(); dd = counter; lcd.print("Date"); lcd.print(dd); delay(300); } counter = 0; while (digitalRead(SW) == LOW) //Установка часа { encoder (); if ( counter > 24) counter = 0; lcd.clear(); hh = counter; lcd.print("Hour"); lcd.print(hh); delay(300); } counter = 0; while (digitalRead(SW) == LOW) // Установка минут { encoder (); if ( counter > 60) counter = 0; lcd.clear(); mm = counter; lcd.print("Minutes"); lcd.print(mm); delay(300); } counter = 0; rtc.adjust(DateTime(yy, mon, dd, hh, mm, 0)); // Отправка значения в РТЦ } /**************меню - 5 - выбор рабочих тенов**********/ void menuFive () { lcd.print(" V procrsse"); } /**************меню - 6 - выход из меню **********/ void menuSix () { while (digitalRead(SW) == LOW) // Установка минут { lcd.clear(); lcd.print("To exit from menu press ok"); } goto menuExit; ///////////////////С переходом не ясно. Откатать. }
Вроде бы все хорошо, но не все ((( Выдает сей код 3 ошибки, от которых я решительно не могу избавиться, а по сему прошу Вашей помощи! Там наверное какая-то мелочь и по этому прошу сильно не пинать. Просто ткните пальцем, что не так. За ранее спасибо.
Приведите текст сообщений об ошибках.
И сразу поменяйте в ifах (187-207) && digitalRead(SW) = LOW) на && digitalRead(SW) == LOW)
Спасибо за подсказку!
А вот и ошибки:
У вас while не закрыт, начиная со строки 076 - открывающая скобка есть, закрывающая - непонятно где. Кол-во открывающих и закрывающих скобок должно быть одинаково - ищите, где пропущена закрывающая скобка. Навскидку - я сказал, проверил, скопировав ваш код в Notepad++ - точно, показывает парную скобку для while в строке 076 перед else в строке 123 - непорядок.
Ну а две последующие ошибки проистекают из первой.
Управление нагревателем (строки 85-92) слишком уж "в лоб" прописано, почитайте http://radiostorage.net/?area=news/1961 , разберитесь, что я имею в виду.
Строки 141-148 - та же история с вентилятором.
Разобрался с теми ошибками. Всему виной была скобки ))
Но возникли новые вопросы.
На данный момент самый глобальный - обработка прерываний от инкрементного энкодера.
На данный момент код имеет следующий вид:
В 73 и 74 строках разрешаем прерывания 0 и 1. У каждого прерывания своя функция. А что дальше делать - ума не приложу. Перепробовал массу вариантов и не удается получить приемлемый вариант. Получаются большие скачки значений при вращении энкодера на 1 щелчек и при вращении в одну сторону приходят значения как в сторону увеличения, так и уменьшения.
П.С. Код обработки прерываний вытер, нет сил моих показывать его людям.
Нашел на форуме решение проблемы (:
Если вдруг кому нужно - http://arduino.ru/forum/programmirovanie/lcd-enkoder#comment-86489