EEPROM
- Войдите на сайт для отправки комментариев
Втр, 31/03/2020 - 11:54
Помогите с проблемой! С делал термостат для накопительного бойлера. Сам я не программист поэтому брал коды из разных скетчей. В общем проблема с EEPROM (тоесть с сохранением установленной температурой). Через примерно 2 месяца безупречной работы после выключения питания изменяется EEPROM то есть уставка температуры к примеру если было 40 то при включении становится 104 это для бойлера не приемлимо. Где ошибка?
#include <EEPROM2.h> #include <SPI.h> #include <Wire.h> #include <OneWire.h> #include <Adafruit_GFX.h> // Скачанная библиотека для дисплея. #include <Adafruit_SSD1306.h> // Скачанная библиотека для дисплея. https://yadi.sk/d/9F_uW1wIZUDna #define OLED_RESET 4 #define POWER_MODE 1 // 0 Внешнее питание, 1- Паразитное Adafruit_SSD1306 display(OLED_RESET); extern uint8_t MediumFontRus[]; unsigned int preMillis = 0; unsigned int T_set ; OneWire ds(4); //Подключение датчика температуры DS18B20 к выводу D4 // bmp конвертер http://git.robotclass.ru/tools/bmptobin.html //значёк термометр const unsigned char PROGMEM smileBmp[] = { 0x03, 0x80, 0x00, 0x0e, 0xe0, 0x00, 0x08, 0x20, 0x00, 0x08, 0x20, 0x00, 0x08, 0x20, 0x00, 0x08, 0x20, 0x00, 0x08, 0x23, 0x00, 0x08, 0x20, 0x00, 0x08, 0x20, 0x00, 0x08, 0x23, 0xc0, 0x08, 0x20, 0x00, 0x08, 0x20, 0x00, 0x08, 0x23, 0x00, 0x0b, 0xa0, 0x00, 0x0b, 0xa3, 0xe0, 0x0b, 0xa0, 0x00, 0x0b, 0xa0, 0x00, 0x0b, 0xa0, 0x00, 0x0b, 0xa3, 0xe0, 0x0b, 0xa0, 0x00, 0x0b, 0xa0, 0x00, 0x0b, 0xa3, 0x00, 0x0b, 0xa0, 0x00, 0x0b, 0xa0, 0x00, 0x0b, 0xa0, 0x00, 0x0b, 0xa0, 0x00, 0x1b, 0x90, 0x00, 0x33, 0x98, 0x00, 0x47, 0xc4, 0x00, 0x47, 0xc4, 0x00, 0x47, 0xc4, 0x00, 0x47, 0xc4, 0x00, 0x20, 0x08, 0x00, 0x30, 0x10, 0x00, 0x18, 0x20, 0x00, 0x07, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; // пример вывода изображения https://robotclass.ru/tutorials/graphics-lcd-nokia-5110/ void setup() { //Считаем из постоянной памяти заданную температуру T_set=EEPROM_read_byte(0); Serial.begin(9600); int SW_up = 7; int SW_dwn = 8; int pin = 9; //Выход pinMode(SW_up, INPUT); //Кнопка "+" pinMode(SW_dwn, INPUT); //Кнопка "-" pinMode(pin, OUTPUT); //Выход digitalWrite(SW_up, 1); digitalWrite(SW_dwn,1); display.begin(SSD1306_SWITCHCAPVCC, 0x3c); //Инициализация дисплея display.cp437(true); // эта команда исправляет сдвиг русских символов на один } void loop() { byte data[2];////работа с датчиком температуры DS18B20 ds.reset(); ds.write(0xCC, POWER_MODE); ds.write(0x44, POWER_MODE); //Конвертация температуры датчиком delay(900); // не меньше 750ms для паразитного питания ds.reset(); ds.write(0xCC, POWER_MODE); /*Игнорировать адрес - используется для обращения к единственному устройству на шине, при этом адрес устройства игнорируется (можно обращаться к неизвестному устройству)*/ ds.write(0xBE, POWER_MODE); //Считать ОЗУ датчика data[0] = ds.read(); data[1] = ds.read(); int T_curr = (data[1]<<8)+data[0]; //Сдвиг на 8 бит влево (<<8) T_curr = T_curr>>4; ////Управление кнопками "+" , "-" if (millis() - preMillis > 10) //Пауза, которая выдерживается при удержании кнопки { preMillis = millis(); { if(digitalRead(7)==HIGH) { delay(5); T_set++; //Прибавляем к переменной T_set единицу } if(digitalRead(8)==HIGH) { delay(5); T_set--; //Убавляем от переменной T_set единицу } } {EEPROM_write_byte(0, T_set); // сохраняем в память последнее значение уставки } } ////Управление реле от температуры if (T_curr >= T_set) //Если текущая температура больше установленной, то выключаем реле { digitalWrite (9, LOW); } if (T_set > T_curr) // Если установка больше текущей, то включаем реле { digitalWrite (9, HIGH); } if ( T_curr >= 70) // Если температура больше или равна 70 то { display.clearDisplay(); // Очищаем экран и display.setTextColor(WHITE); // Цвет текста. display.setTextSize(2); // Размер текста display.setCursor(0,0); // Координаты текста откуда начать писать (Х,У) display.print(utf8rus("Критическая")); // Выводим предупреждение display.setCursor(30,0); display.print(utf8rus("Температура")); display.display(); digitalWrite (11, HIGH); delay(25);digitalWrite (11, LOW); // И включаем бузер на 11 вывод } ////Вывод показаний на дисплей display.clearDisplay(); // Очистить буфер. display.setTextColor(WHITE); // Цвет текста. display.setTextSize(2); // Размер текста display.setCursor(2,3); // Координаты текста откуда начать писать (Х,У) display.print(utf8rus("Уставка=")); ////Написать текущую температуру display.setTextSize(5); display.setCursor(40,22); display.print(T_curr); display.setTextSize(2); display.setCursor(100,18); display.print(utf8rus("о")); ////Написать уставку температуры display.setTextSize(2); display.setCursor(100,3); display.print(T_set); ////Рамка: Линия (начало Х, начало У, конец Х, конец У, цвет) display.drawLine(0, 18, 128, 18,WHITE); //горизонтальная линия посередине 1 display.drawRect (0, 0, 128 , 64, WHITE ); //прямоугольник display.drawBitmap(5, 25, smileBmp, 22, 38, WHITE); // отрисовка и вывод изображеня. координаты/ название/ размер/ цвет display.display(); // Чтобы сделать символы видимыми на дисплее }
В 0 адресе eeprom не храни ничего, начинай хотя бы с 0x10
Неприемлемо каждые 10мс еепром насиловать.
Вы пишете в ЕЕПРОМ температуру каждые 10 миллисекунд, независимо от того. изменяется она или нет. Абсолютно неудивительно. что ЕЕПРОМ в результате выходит из строя. ведь гарантированный ресурс ее всего 100 тыс перезаписей. Удивительно скорее то. что оно так долго держится,
В общем вот эту строку надо ставить где то в другом месте правильно?
104
{EEPROM_write_byte(0, T_set);
// сохраняем в память последнее значение уставки
В общем вот эту строку надо ставить где то в другом месте правильно?
например, внутри условий нажатия кнопок
Чёт не идёт у меня. пробовал делать так. Но не записывается в память при включении уставка не сохраняется значение 255.
выложите исправленный код целиком
так я и думал :)
Вы пишете значение температуры в ячейку 0х10, а читаете из нулевой....
Блин разобрался забыл изменить адрес в строке 59
Спасибо подсказали. Скажите теперь всё правильно. Работать будет?. а то опять через два месяца 104 будет, Хорошо я ночью случайно проснулся а там такое. Хорошо там есть тепловой предохранитель. а тобы рванул наверно.
Возьмите за правило использовать EEPROM.update, а не write. Именно в данном скетче смысла особо нет, поскольку у вас нет кнопки сохранения, а только кнопки изменения, но в будущем может пригодится, imho. Ну и опять же, если вынести адрес ячейки в define или переменную const, будет проще при отладке.
Может и в другом месте рванет. Это же ваша программа, никто другой на неё гарантию давать не может.
Работать будет?. а то опять через два месяца 104 будет, Хорошо я ночью случайно проснулся а там такое.
неудивительно, когда берешься не за свое дело:
"Сам я не программист поэтому брал коды из разных скетчей. "
-ответсвенные программы, которые могут "рвануть" - не пишут копипастой "из разных скетчей". Надо четко понимать. что делается в коде.
А пока не понимаете - ограничтесь миганием светодиодом или созданием чего-то вроде "умного вкентилятора для туалета"
Всем большое спасибо за помощь! Как раз перестраховался. Я насчёт умного вентилятора. Попробовал на нём. Так примерно такая же программа и такой же косяк с eeprom. Если проработает 2 месяца буду и бойлер подключать.
Возьмите за правило использовать EEPROM.update, а не write. Именно в данном скетче смысла особо нет, поскольку у вас нет кнопки сохранения, а только кнопки изменения, но в будущем может пригодится, imho. Ну и опять же, если вынести адрес ячейки в define или переменную const, будет проще при отладке.
Спасибо! Очень позновательно!
Извините, но дополню - EEPROM создано для запоминания действий оператора или критических ситуаций. Для всего остального есть внешняя память, которую легко заменить, в отличие от процессора.
Извините, но дополню - EEPROM создано для запоминания действий оператора или критических ситуаций. Для всего остального есть внешняя память, которую легко заменить, в отличие от процессора.
Для хранения настроек, которые меняются пару раз в день максимум - она также замечательно подходит, imho.
Не обязательно. Можно сохранять хоть каждую секунду. Всё зависит от того как организуешь.