Чтение с последней заполненной ячейки EEPROM...
- Войдите на сайт для отправки комментариев
Здраствуйте. Такой вопрос касаемо записи/чтения EEPROM. Есть один проект в котором будет происходить частая запись и чтение в EEPROM память Arduino (Nano Atmega168). При включенной Ардуинке запись происходит последовательно в каждую ячейку начиная с 0 и до 512, после заполнения EEPROM переходит вначало и перезапись/чтение начинается с нулевой ячейки... Но при выкл. и вкл. питания запись начнётся опять с нулевой ячейки не пройдя всю память, а откл. питания может быть частенько.
Хочу реализовать, что бы при Откл. и Вкл. питания чтение началось не с нулевой ячейки памяти, а с последней ячейки куда была произведена запись и продолжила далее записываться / читаться, тем самым получится продлить жизнь микросхеме EEPROM памяти и сделать износ более равномерным.
Часть кода для визуального понимания:
byte E_1; // переменная для экономии ресурсов ОЗУ EEPROM int addr = 0; // Начальный адрес памяти EEPROM int L; // переменная для преобразования ручных поворотов через map() //другой код... void setup() { //другой код... L = EEPROM.read(addr) * 118; //умножаем значение из памяти на 118 } void finction() { //другой код... if (Right_Pin_1 == true || Left_Pin_1 == true) E_1 = 1; //если истина хотя бы 1 переменная, присваиваем E_1 единицу if (Right_Pin_1 == false && Left_Pin_1 == false && E_1 == 1) { //если все переменные лож и E_1 равна 1, тогда... EEPROM.update(addr, L / 118); //делим на 118 и записываем обновлённые значения в EEPROM в ячейку addr addr = addr + 1; //переходим на следующую ячейку памяти для записи if (addr == 512) { //если дошли до последней ячейки (для Arduino NANO Atmega168) addr = 0; //переходим обратно в первую ячейку и по кругу... } E_1 = 0; //меняем значение переменной E_1 на 0 } } void loop() { //другой код... //другой код... //другой код... }
Так, вроде, в приведённом коде нет ничего на тему
Хочу реализовать, что бы при Откл. и Вкл. питания чтение началось не с нулевой ячейки памяти, а с последней ячейки куда была произведена запись
Или я что-то пропустил? Как Вы это хотите реализовать?
смысла нет писать весь код.
Вопрос в том, что возможно ли такое реализовать или нет?
Может не совсем понятно выразился просто, когда описывал идею :)
Простите, так я не понял. В первом посте не было никакого вопроса вообще и я подумал, что у Вас есть идея и Вы хотите ею поделиться. А Вы просто спрашивали можно ли такое сделать? Да, конечно, можно.
неподкинете пример каким образом реализовать, буду очень благодарен)))
Ну, вариантов много. Общее у них одно: нужно сохранять адрес последней использованной ячейки там где отключение питания не приведёт к потере информации. Можно сохранять адрес после каждого использования EEPROM, а можно предусмотреть какой-нибудь аварийный bac-up питания (на ионисторе, например) и сохранять не постоянно, а только при пропадании внешнего питания. Ионистора хватит на то, чтобы сохранить.
В любом случае: сохраняем адрес последней использованной ячейки, а при включении питания (в функции setup) считываем сохранённое значение и продолжаем работать с этого адреса.
Можно придумать миллион вариантов куда именно сохранять. Каждый из вариантов может быть полезным, а может оказаться идиотизмом в зависимости от задачи и множества факторов, которые. кроме Вас никто не знает.
Например:
1. Записывать на SD карту. При включении питания (в setup) считывать с карты номер ячейки и продолжать от него
2. Выгружать на внешний Web-сервер или файловый сервер, а при включении питания считывать оттуда
Я уж не говорю про экзотику типа "сервой поворачиваем вал потенциометра на 1/512 его хода на единицу адреса. Тогда по текущему сопротивлению всегда можно узнать адрес или ещё круче, присобачить роботизированную руку, чтобы она адрес на обоях записывала, а при включении питания его оттуда считывать и распозновать.
Ну, это уже шутки пошли, но в принципе, подумайте. Общую идею я рассказал.
подкину вариант:
у меня в одном проекте в аналогично сохраняются записи фиксированной длины в епром. Одно из полей записи содержит время. Кажется типа time_t, обычное астрономическое киевское время. Перезаписываю запись с минимальным временем.
Пишите не 512 ячеек памяти, а 511. А в 512-ю посоянно записывайте номер ячейки для записи. Вот Вам и будет от куда брать номер ячейки при потере питания.
А в 512-ю посоянно записывайте номер ячейки для записи.
Она накроется первой и весь епром выбросите :(
А в 512-ю посоянно записывайте номер ячейки для записи.
Она накроется первой и весь епром выбросите :(
как вариант делать как в файловой системе
как вариант делать как в файловой системе
Угу.
Секторами по 512 байт.
Если считаем что другой энергонезависимой памяти в системе нет, то правильных пути 3
1. Присмотрется к диапазону значений сохраняемой переменной. Если он не 0-255, то одно из неиспользуемых значений использовать как маркер свободной ячейки. После записи в эту ячейку маркер переписываем в следующую по порядку. Если же диапазон занят полностью то можна делать искуственное исключение значения переходя к 2-х байтовому. Т.е. исключаем например 0xff заменив на пару 0xff,0xff, а маркер свободной станет 0xff,0xfe. Другие варианты от 0xff,0x00 до 0xff,0xfd можно применять еще для чего полезного.
2. Как выше намекалось, по адресу 0 храним адрес указателя на свободную. Указатель на свободную ячейку после каждой записи увеличиваем. При некоторой ситуации не сильно часто (раз в месяц, по завершению цикла прохода памяти, просто при включении и т.д.), меняем положение указателя перезаписывая его по адресу 0.
3. Аппаратно фиксируем отключение. Никаких ионисторов и пр. там не надо, хватит электролита на плате. Те 10мсек он обеспечит с запасом. Надо только быстро, в идеале по прерыванию , реагировать на исчезновение внешнего питания на входе. Через резистор с самого входа, до диода и стабилизатора завести сигнал на пин контроллера. Ну и в прерывании записывать указатель на свободную ячейку по адресу 0.
ПС. все методы предполагают выведение 1-2 ячеек из пространства для сохранения данных. Это очень просто делается прямо при записи и чтении.
Кстати, раз уж зашла речь про епром - спрошу здесь, чтоб тему не создавать, если автор не против.
Везде пишут про ресурс памяти в циклах чтение/запись. Следует ли это понимать так, что чтение так же старит ячейку, как и запись? Ну, то есть, нет смысла прочитать значение из памяти, и если оно такое же как нужно, то не записывать его заново? А то вот бродят такие мысли когда сохраняю структуру с настройками - порядка 30 байт, а меняется там, в основном, одно-два поля, т.е. пару байт всего.
//то чтение так же старит ячейку, как и запись?
Нет конечно.
//Ну, то есть, нет смысла прочитать значение из памяти, и если оно такое же как нужно, то не записывать его заново?
Есть смысл. Именно надо предварительно читать и не переписывать такое же.
как вариант делать как в файловой системе
Угу.
Секторами по 512 байт.
Пишите байтами, я о таблице говорю, сама идеология решения, правда потеряем ровно половину, как минимум, но это лучше чем совсем ничего, есть правда еще решение реализовать алгоритм SSD как функция, в них это работает безупречно )))
//реализовать алгоритм SSD как функция
???
Контроллер SSD
Главной задачей контроллера является обеспечение операций чтения/записи, и управление структурой размещения данных. Основываясь на матрице размещения, в какие ячейки уже проводилась запись, а в какие еще нет.
Всем спасибо за достаточно большое количество нужной информации, кое что полезное уяснил для себя помимо вопроса :)
как вариант делать как в файловой системе
Угу.
Секторами по 512 байт.
Пишите байтами, я о таблице говорю, сама идеология решения...
Идеология решения ФС опирается на то, что в минимальном элементе данных (секторе) можно разместить достаточно много записей элементов каталога.
Сколько элементов записей каталога поместится в одном байте?
Кстати, раз уж зашла речь про епром - спрошу здесь, чтоб тему не создавать, если автор не против.
Везде пишут про ресурс памяти в циклах чтение/запись. Следует ли это понимать так, что чтение так же старит ячейку, как и запись? Ну, то есть, нет смысла прочитать значение из памяти, и если оно такое же как нужно, то не записывать его заново? А то вот бродят такие мысли когда сохраняю структуру с настройками - порядка 30 байт, а меняется там, в основном, одно-два поля, т.е. пару байт всего.
Если писать eeprom.put() то оно вроде так и реализовано уже в ардуине.