Запись первоначальных данных в EEPROM
- Войдите на сайт для отправки комментариев
Здравствуте.
Хочу сделать счетчик импульсов с выводом на двухстрочный дисплей на Arduino UNO.
У водосчетчика, с которого получаю и считаю импульсы есть начальные показания. Эти показания необходимо при загрузки скетча прописать в EEPROM для дальнейшего использования и сохренения при отключении питания.
Самый простой способ, который нашел это сделать две загрузки скетча:
1. В Setup прописать команду записи в ячейку памати первоначальных значений и загрузить скетч;
2. Закоментировать строку с выше указанной записью и снова загрузить скетч.
При первой загрузке у меня все получается на дисплее выводится первоначальные данные счетчика, но после того как я удаляю из Setup строку с записью и загружаю скетч в контроллер, при чтении из EEPROM на дисплее получается нуль. Как-будто в прошлый раз данные не записались или стерлись при повторной загрузке.
#include <EEPROM.h> #include <Wire.h> // библиотека для управления устройствами по I2C #include <LiquidCrystal_I2C.h> // подключаем библиотеку для LCD 1602 LiquidCrystal_I2C lcd(0x27,16,2); // присваиваем имя lcd для дисплея 16х2 volatile boolean lcdOnFlg = HIGH; //флаг включеного монитора volatile long lcdOnTime = 0; //время включения монитора int litrs = 110; int address = 0; void setup() { lcd.init(); // инициализация LCD дисплея lcd.backlight(); // включение подсветки дисплея lcd.setCursor(0,0); lcd.print("Litrs:"); attachInterrupt(1, lcdOn, FALLING); Serial.begin(9600); <strong>//EEPROM.put(address,litrs); // Записать первоначального значения счетчика 110 в ячейку с адресом 0 //delay(100);</strong> //EEPROM.get(0, litrs); } //прерывание от кнопки включения дисплея void lcdOn() { if ((millis()-lcdOnTime) >200) { if(lcdOnFlg == LOW) //если экран выключен, то поднимаем флаг и запоминаем время включения { lcdOnTime = millis(); //запоминаем время сработки прерывания lcdOnFlg = !lcdOnFlg ; //поднимаем флаг } } lcdOnTime = millis(); } void loop() { // Получаем данные из EEPROM litrs = EEPROM.read(address); lcd.setCursor(0,1); // ставим курсор на 1 символ второй строки lcd.print(litrs); if(lcdOnFlg == HIGH) //если флаг поднят - экран горит { if ((millis()-lcdOnTime) >10000) //проверяем время которое горит экран не более 10 секунд { lcd.noBacklight(); //через 10 секнд гасим экран lcdOnFlg = !lcdOnFlg; //опускаем флаг } else { lcd.backlight(); } } Serial.println(litrs); }
Подскажите где ошибка в записи или в чтении и есть ли какой-то другой не сложный алгоритм записи первоначальных данных. Спасибо.
Подскажите, а где в Вашей программе идет запись в EEPROM?
У avrdude, которым заливается UNO есть параметр -е - стирать EEPROM. Надо его (-е) удалить из platform.txt который находится в Arduino\hardware\arduino\avr
У avrdude, которым заливается UNO есть параметр -е - стирать EEPROM. Надо его (-е) удалить из platform.txt который находится в Arduino\hardware\arduino\avr
Да это я понимаю - а где записывают? Стереть каждый может...
Да это я понимаю - а где записывают? Стереть каждый может...
см строку N20
Лично я бы не парился с двойной загрузкой скетча, а сделал бы считывание данных для записи из сериал.
То есть при запуске программа проверяет не были ли данные записаны в EEPROM (сигнатуру,так какую придумать) и если нет, то ждать их ввода из сериал. Тогда при первой загрузке сразу можно и нужные данные ввести без перекомпиляции.
#20 не прописывает для сохренения при отключении питания...
#20 не прописывает для сохренения при отключении питания...
А что же, по вашему, EEPROM.put() делает?
Записывает какие-то первоначальные показания, но не производит сохренение при отключении питания.
Записывает какие-то первоначальные показания, но не производит сохренение при отключении питания.
То есть, опять же по-вашему, EEPROM не сохраняет данные при отключении питания?
Сохраняет, конечно. Но, полагаю, что ценность прибора, который при случайной перезагрузке не сохраняет текущие показание водомера, а начинает считать каждый раз со 110 - стремится к нулю.
Сохраняет, конечно. Но, полагаю, что ценность прибора, который при случайной перезагрузке не сохраняет текущие показание водомера, а начинает считать каждый раз со 110 - стремится к нулю.
Я пока не дописал код, который записывает изменённые показания, я застрял с начальными :)
Ем слона по частям.
Спасибо всем за советы буду пробовать.
В СЕТАП()
если в ячейке № значение не равно контрольному (например 85 или другое кроме 255)
1) записать стартовые значения счетчика
2) записать в ячейку № контрольное число
В СЕТАП()
если в ячейке № значение не равно контрольному (например 85 или другое кроме 255)
1) записать стартовые значения счетчика
2) записать в ячейку № контрольное число
Не получится - сработает 1 раз. Тут надо привязаться к чему-то конкретному, например ко времени, но это потребует аппаратных доработок.
В СЕТАП()
если в ячейке № значение не равно контрольному (например 85 или другое кроме 255)
1) записать стартовые значения счетчика
2) записать в ячейку № контрольное число
Не получится - сработает 1 раз. Тут надо привязаться к чему-то конкретному, например ко времени, но это потребует аппаратных доработок.
Всё получится, оно и должно сработать один раз, а в другое место eeprom уже пишется счётчик из loop, а выводится уже сумма начального значения и счетчикал
Да, логично, ступил. Но тогда это значение и надо писать 2 раза в EEPROM и сравнивать их.
Мой вариант работает. Скажу больше - после загрузки скетча нужен один старт программы (он происходит без нашего участия). Дальше коментируем условие и снова загружаем скетч. При этом в фузах должен быть установлен бит EESAVE. При больших объемах данных исключение функции начальной записи еепром позволит уменьшить размер скетча. ТС-у это конечно не нужно.
Вот пример для записи массива
Мой вариант работает. Скажу больше - после загрузки скетча нужен один старт программы (он происходит без нашего участия). Дальше коментируем условие и снова загружаем скетч. При этом в фузах должен быть установлен бит EESAVE. При больших объемах данных исключение функции начальной записи еепром позволит уменьшить размер скетча. ТС-у это конечно не нужно.
Поздравляю, уважаемый, но в изначальном ТЗ этого не озвучивалось. Короче - Вы сами не знали, чего хотели.
Что конкретно нужно удалить просто два символа -e?
Мой вариант работает. Скажу больше - после загрузки скетча нужен один старт программы (он происходит без нашего участия). Дальше коментируем условие и снова загружаем скетч. При этом в фузах должен быть установлен бит EESAVE. При больших объемах данных исключение функции начальной записи еепром позволит уменьшить размер скетча. ТС-у это конечно не нужно.
Как установить бит EESAVE?
Поменял я платы, была у меня такая:
Перепрошил в такую
И все заработало!
Знатоки в чем может быть отличие?
Отличие в том, что Вы неверно выставили тип платы в настройках.