Не сохраняются данные в EEPROM
- Войдите на сайт для отправки комментариев
Вс, 22/03/2015 - 11:49
Такая проблеммка: делаю термостат на ардуино по такому образцу: http://arrduinolab.blogspot.ru/2014/09/arduino.html
Одно реле переделал на реле времени. Установки времени через дисплей должны записываться в EEPROM, но почему то не сохраняются. Реле срабатывает каждую секунду и в меню данные времени для реле обнуляются.
// термостат, один датчик DS18B20, два выхода // подробнее http://youtu.be/y62Ps_D9B1M // // v 0.1 beta #include <EEPROM.h> #include <OneWire.h> #include <LiquidCrystal.h> #define OUT1 2 // выходы для реле #define OUT2 3 unsigned long currentTime; unsigned long loopTime; byte tempOUT1, tempOUT2; byte timer1, timer2; LiquidCrystal lcd(8, 9, 4, 5, 6, 7); OneWire ds(11); // 11 вход датчика 18b20 byte gradus[8] = { 0b00110, 0b01001, 0b01001, 0b00110, 0b00000, 0b00000, 0b00000, 0b00000 }; void erorr(){ // останавливает работу программы и сигнализирует ошибку digitalWrite(OUT1, HIGH); // выключаем реле digitalWrite(OUT2, HIGH); while(1){ // крутим бесконечный цикл digitalWrite(13, !digitalRead(13)); delay(500); } } //// byte key(){ //// для кнопок ЛСДшилда int val = analogRead(0); if (val < 50) return 5; else if (val < 150) return 3; else if (val < 350) return 4; else if (val < 500) return 2; else if (val < 800) return 1; else return 0; } //// void setMenu(){ // установка температуры byte pos; digitalWrite(OUT1, HIGH); // выключаем реле digitalWrite(OUT2, HIGH); lcd.clear(); lcd.setCursor(0, 0); // что нужно отрисовать один раз lcd.print("OUT1: "); lcd.setCursor(0, 1); lcd.print("OUT2: "); lcd.blink(); while(1){ // крутим бесконечный цикл byte KEY = key(); // читаем состояние кнопок lcd.setCursor(6, 0); // выводим на экран lcd.print(tempOUT1); lcd.write(1); lcd.print("C "); lcd.setCursor(6, 1); lcd.print(tempOUT2); lcd.write(1); lcd.print("C "); ////// обработка кнопок if (pos == 0){ // если в первой позиции lcd.setCursor(5, 0); // устанавливаем курсор if (KEY == 2) { // если нажата кнопка tempOUT1--; // изменяем значение EEPROM.write(1, tempOUT1); // сохраняем в еепром } else if (KEY == 5){ tempOUT1++; EEPROM.write(1, tempOUT1); } } if (pos == 1){ lcd.setCursor(5, 1); if (KEY == 2) { tempOUT2--; EEPROM.write(2, tempOUT2); } else if (KEY == 5){ tempOUT2++; EEPROM.write(2, tempOUT2); } } if (KEY == 3) pos--; // крутим позицию else if (KEY == 4) pos++; if (pos > 1) pos = 0; delay(200); } } void setMenu2(){ // установка таймера byte pos; digitalWrite(OUT1, HIGH); // выключаем реле digitalWrite(OUT2, HIGH); lcd.clear(); lcd.setCursor(0, 0); // что нужно отрисовать один раз lcd.print("TIME1: "); lcd.setCursor(0, 1); lcd.print("TIME2: "); lcd.blink(); while(1){ // крутим бесконечный цикл byte KEY = key(); // читаем состояние кнопок lcd.setCursor(7, 0); // выводим на экран lcd.print(timer1); lcd.print("S "); lcd.setCursor(7, 1); lcd.print(timer2); lcd.print("S "); ////// обработка кнопок if (pos == 0){ // если в первой позиции lcd.setCursor(6, 0); // устанавливаем курсор if (KEY == 2) { // если нажата кнопка timer1--; // изменяем значение EEPROM.write(3, timer1); // сохраняем в еепром } else if (KEY == 5){ timer1++; EEPROM.write(3, timer1); } } if (pos == 1){ lcd.setCursor(6, 1); if (KEY == 2) { timer2--; EEPROM.write(4, timer2); } else if (KEY == 5){ timer2++; EEPROM.write(4, timer2); } } if (KEY == 3) pos--; // крутим позицию else if (KEY == 4) pos++; if (pos > 1) pos = 0; delay(200); } } float getTemp(){ // возвращает температуру с датчика byte data[12]; // и останавливает программу на секунду byte addr[8]; if (!ds.search(addr)) { lcd.clear(); lcd.print("No sensor."); erorr(); } ds.reset_search(); if (OneWire::crc8(addr, 7) != addr[7]) { lcd.clear(); lcd.print("Sensor CRC erorr"); erorr(); } ds.reset(); ds.select(addr); ds.write(0x44); delay(1000); ds.reset(); ds.select(addr); ds.write(0xBE); for (int i = 0; i < 9; i++) data[i] = ds.read(); int raw = (data[1] << 8) | data[0]; // Переводим в температуру if (data[7] == 0x10) raw = (raw & 0xFFF0) + 12 - data[6]; return raw / 16.0; } void setup() { // Serial.begin(9600); lcd.createChar(1, gradus); lcd.begin(16, 2); lcd.clear(); pinMode(13, OUTPUT); pinMode(12, OUTPUT); pinMode(OUT1, OUTPUT); pinMode(OUT2, OUTPUT); currentTime = millis(); // считываем время, прошедшее с момента запуска программы loopTime = currentTime; tempOUT1 = EEPROM.read(1); // читаем настройки tempOUT2 = EEPROM.read(2); // из еепром timer1 = EEPROM.read(3); // читаем настройки timer2 = EEPROM.read(4); // из еепром } void loop() { if (key() == 2) setMenu(); // если нажата влево, уходим в меню if (key() == 5) setMenu2(); // если нажата вправо, уходим в меню2 else if (key() == 4) analogWrite(10, 20); // если вниз, глушим подсветку else if (key() == 3) digitalWrite(10, HIGH); float temperature = getTemp(); // читаем температуру digitalWrite(12, HIGH); timer1 *= 1000; // переводим в милисекунды timer2 *= 1000; // переводим в милисекунды currentTime = millis(); if (millis() >= (loopTime+timer1)) { digitalWrite(OUT1, !digitalRead(OUT1)); loopTime = currentTime; if (digitalRead(OUT1)) { loopTime = currentTime+(timer2-timer1); } } if (temperature < tempOUT1) { digitalWrite(OUT2, LOW); // сверяем температуру } // и управляем выходами if (temperature > tempOUT2) { digitalWrite(OUT2, HIGH); } lcd.setCursor(0, 0); /// вывод инфы на экран lcd.print("1:"); lcd.print(tempOUT1); lcd.write(1); // lcd.print("C"); if (digitalRead(OUT1)) lcd.print(" OFF "); // показываем состояние выхода else lcd.print(" ON"); lcd.setCursor(0, 1); lcd.print("2:"); lcd.print(tempOUT2); lcd.write(1); if (digitalRead(OUT2)) lcd.print(" OFF "); else lcd.print(" ON"); lcd.setCursor(9, 0); // показываем температуру с датчика lcd.print("|"); lcd.print(temperature, 1); lcd.write(1); lcd.print("C"); lcd.setCursor(9, 1); lcd.print("|"); lcd.print(millis()); }
С ЕЕПРОМ все нормально. Проблема в том, что вы делаете после чтения из нее.
Во-первых, вы обьявили переменные типом byte, прочитайте описание типа и какие максимальные значения он может принимать.
далее вы делаете это:
и ладно бы если вы это сделали один раз, так вы это делаете раз в секунду и каждую секунду значение увеличиваете в 1000 раз.
Так же, если хотите держать свой термостат месяцами включенным, не рекомендую использовать эту конструкцию:
http://arduino.ru/forum/programmirovanie/kak-vklyuchit-na-nekotoroe-vremya#comment-20650
Спасибо. Ввёл новые переменные для цикла t1 и t2 и их уже привожу к милисекундам.
Так же, если хотите держать свой термостат месяцами включенным, не рекомендую использовать эту конструкцию:
http://arduino.ru/forum/programmirovanie/kak-vklyuchit-na-nekotoroe-vremya#comment-20650
Спасибо. Буду изучать.
Так же, если хотите держать свой термостат месяцами включенным, не рекомендую использовать эту конструкцию:
http://arduino.ru/forum/programmirovanie/kak-vklyuchit-na-nekotoroe-vremya#comment-20650
maksim, я так понял использование такой конструкции неприемлемо, если планируется крутить программу более 50 дней? Правильно?
У меня будет термоконтроллер перезагружаться чаще. Кстати он при установках температуры и таймеров ресетится.