EEPROM на AT24C32 и библиотека uRTCLib - запись массива.

Тема в разделе "Arduino & Shields", создана пользователем Gomez, 4 сен 2018.

  1. Gomez

    Gomez Гик

    Есть стандартный модуль с DS3231 + AT24C32.
    Применяется в погодной станции, которая показывает график атмосферного давления за прошедшие 24 часа.
    Для этого у меня есть массив
    int pressArr[120] (поскольку ширина OLED-дисплея 128 пикселей, замеряю давление каждые 12 минут, чтобы удобно было выводить массив попиксельно в виде графика).
    При новом измерении через 12 минут, пишу полученное значение в конец массива, сдвигая все данные в нем влево, удаляя первое значение в массиве.

    Но хочется задействовать EEPROM, поскольку в случае отключения данные из массива, конечно, улетучатся. :)

    Думаю, что в любом случае не стоит писать такой длинный массив каждые 12 минут в EEPROM "с нуля", поскольку предыдущие показатели не изменяются.
    Правильно ли будет постепенно заполнять какое-то количество ячеек памяти, например, 500, просто записывая в следующую ячейку текущее давление, а после достижения 500-ой ячейки записать с первой ячейки текущий массив и снова писать в следующие ячейки данные каждые 12 минут?

    Как я понимаю, тогда в EEPROM (на случай отключения девайса и восстановления массива из EEPROM) нужно хранить как минимум еще два значения
    1) В какую ячейку производилась запись последний раз. :)
    2) Когда в последний раз производилась запись, чтобы рассчитать, сколько измерений было пропущено, чтобы в этом месте графика не было точек.

    Короче, я запутался. :D Может, для подобного есть какие-то общепринятые приемы и алгоритмы, а я изобретаю велосипед, не имея профильного образования? :)
     
  2. DIYMan

    DIYMan Guest

    Понимаешь всё правильно.
     
    Gomez нравится это.
  3. DetSimen

    DetSimen Guest

    Почитай за кольцевой буфер
     
    Gomez и parovoZZ нравится это.
  4. parovoZZ

    parovoZZ Гуру

    Заведи переменную-указатель на ячейку с текущими данными. Чтобы не запариваться с арифметикой, количество ячеек в массиве можно сделать кратным байту (256, 512). Тогда переменная-указатель сама будет обнуляться без лишних телодвижений. Идея в чем - никакие данные никуда сдвигать не надо.
     
    Mitrandir нравится это.
  5. Gomez

    Gomez Гик

    О, спасибо! В общем, я был близок к "изобретению" кольцевого буфера, если в следующих шагах догадался бы, что мне не нужно по достижению конца выделенного отрезка все стирать и переписывать весь массив с первой ячейки. :D
     
  6. DetSimen

    DetSimen Guest

    Нууу... Нальешь при случае.
     
    Gomez нравится это.
  7. Daniil

    Daniil Гуру

    Если есть возможность, то для увеличения срока службы еепром можно поставить по питанию кондер по-толще и производить запись всех точек только при пропадании основного питания - пока кондер разряжается.
     
  8. Это и называется кольцевой буфер.
     
  9. b707

    b707 Гуру

    нет смысла усложнять - если сохранять давление каждые 12 минут, описанный выше механизм и так позволит писать в ЕЕПРОМ примерно 800 лет :)
     
    Gomez нравится это.
  10. parovoZZ

    parovoZZ Гуру

    в китайскую - нет.
     
  11. Ионистора на 1 фарад хватит? (Ставил 1000 мкФ, не успевает сохранять) Тоже нужно придумать фикус для сохранения данных перед выключением. Думаю так сделать на питание Дуни подавать чуть больше 5 вольт. После выключателя поставить диод после него ионистора параллельно. Мониторить дуней напряжение до диода. В случае падения, сохранять все данные. Смотрел что китайцы часто накалывают с ионисторами подсовывая дешёвые батарейки вместо них. Как купить настоящий х.з.
     
  12. Gomez

    Gomez Гик

    Я тоже думал про ионисторы и проч. Но городить такое, чтобы недорогой модуль прожил не 100, а 300 лет - как - то махнул рукой на эту затею. :) Вдруг через 300 и атмосферного давления-то не будет. ;)

    В принципе, одно "слабое" место - ячейки, куда пишется переменная-указатель и время. Хотя если упороться, их можно писать в ячейки в зависимости от дня недели. :D Или раз в год менять адреса. :D
     
  13. parovoZZ

    parovoZZ Гуру

    как так? Неправильный код какой-то.
     
    Сусемьбек нравится это.
  14. Daniil

    Daniil Гуру

    как только пропадёт питание надо отключить всех активных потребителей (дисплей в 1ую очередь).
    Если используется дуня, то она сама по себе прожорлива.
    я немножко перфекционист)
    Но это правильная замечание и я с ним согласен, только 1 запись в 12 мин, т.е. 5 записей в час мне дало ~9 лет (резерв 1 млн записей у еепром).
     
    Сусемьбек нравится это.
  15. Вечер добрый. Кот правильный), выше как раз описали причину. Кроме Дуни много исче чего висит. Экранчик, накачка высоковольтного трансформатора. Потребление от 60 до 110 ма. У меня другая задача. Очень чуткий слюдяной датчик на дозиметре, но его ресурс 300 часов. (ДозиметрДиспользуется для поисковых целей и включается ненадолго 10-30 минут)и нужно сделать чтоб при выключении сохранялось сколько времени он отработал. Можно и каждую минуту сохранять но еепром жалко, там много ещё чего сохранятся. Пробовал без диода , по падению напряжения меньше 4.8 вольт. Не успевает сохранять. Вот и думаю ионистора 1 ф должно хватить выше крыши.
     
  16. Gomez

    Gomez Гик

    Там речь шла про "вышеуказанный механизм" - кольцевой буфер, то есть в ту же самую ячейку запись будет производиться, например, в 256 раз реже. :)

    Осталось решить проблему с записью переменной-указателя в одну и ту же ячейку и времени последней записи.

    Отцы-основатели, а что, если увеличить размер массива на одно значение и просто при записи текущего значения в следующую ячейку писать флаг, обозначающий окончание массива?

    Ведь перебрать весь массив из EEPROM придется только при включении девайса, в setup{}

    Остается еще время... То ли опять же писать в следующую ячейку... О! Так время и будет флагом, там же будет не трёхзначное число, похожее на давление.
    Как бы время минималистичнее записать... Интересует только интервал 24 часа, поскольку если девайс отключался на дни, это все равно не отобразится на 24-часовом графике. ;)
    А! Ну у меня же 12-минутные интервалы... 00:00 - 0, 23:48 - 119. Итак, если в какой-то ячейке число меньше, скажем, 600, значит, это флаг окончания массива, соответственно считываем массив, а значение флага используем для вычисления пропуска в измерениях.
     
    Последнее редактирование: 5 сен 2018
  17. Gomez

    Gomez Гик

    То есть у Вас должно сохраняться число от 1 до 30, например. Это всего одна ячейка памяти. Ну и выделите 100 ячеек или 1000 строго под запись этого числа, и пишите его раз в минуту в следующую ячейку по кругу, обнуляя предыдущую ячейку. При включении девайса в этом диапазоне адресов циклом находите ячейку, где есть хоть что-то > 0.
     
    Сусемьбек нравится это.
  18. DIYMan

    DIYMan Guest

    Ещё вариант оптимизации - не писать в ячейку, если в ней уже такое же значение ;) Именно так реализован метод EEPROM.update. Тогда, в случае ограниченного диапазона входящих значений - можно поиметь профит. Минус - бОльшее время отработки, т.к. надо сперва вычитать из ячейки.
     
    Daniil и Сусемьбек нравится это.
  19. Gomez

    Gomez Гик

    Тут возникли проблемы и мысли...
    1) А точно ли затрагивается только та ячейка, в которую пишешь? Как организована запись на аппаратном уровне? Вдруг чип работает исключительно со страницами по 32 байт "глубоко в душе", то есть переписывает всю страницу при любом изменении, касающимся ячеек на странице? Тогда все эти "скользящие записи" для экономии ресурса не будут работать...

    2) Удивительно медленно происходит перебор значений eeprom двумя последовательными циклами.
    В первом я нахожу конец массива по флагу, и прерываю цикл.
    Во втором я заполняю массив считываемыми значениями из eeprom, отталкиваясь от адреса ячейки, полученного в первом цикле.
    И вот двухбайтовое rtc.eeprom_read(position, &intPressure);
    (не знаю, во всех библиотеках или только в этой) работает в цикле секунд 10-20 (в совокупности, конечно).
    И это у меня еще цикл в 48 итераций для теста, а я хотел "на боевом" в 480...

    Видимо, надо опять "хитрить", писать в ячейки однобайтовые значения давления, например "p - 500", тогда будет влезать в один байт. И, видимо, читать не перебором, а считывать весь кольцевой буфер сразу и уж в памяти Ардуины с ним возиться? :)
     
    Последнее редактирование: 6 сен 2018
  20. parovoZZ

    parovoZZ Гуру

    чтение из eeprom происходит очень быстро (цифер не помню), а вот запись медленно - 3.4 мс в атомарном режиме. Благо что, ждать её не надо - закинули байт, дернули запись и занимаемся дальше своими делами. Через 3.4 мс проверили флаг окончания записи - следующий байт записали и т.д.
    а даташит не почитать?

    Вот нашел по чтению
     
    Последнее редактирование: 6 сен 2018
    DetSimen нравится это.