Как сохранить значение перед сбросом
- Войдите на сайт для отправки комментариев
Ср, 14/11/2012 - 20:24
Здравствуйте.
Проблема выглядит следующим образом. Есть некая система работающая постоянно. Управляет отоплением. Система работает на базе контроллера (UNO). Более детальные установки и корректировки производяться с компьютера ,который подключается по необходимости. В момент подключения Ардуино сбрасывает все данные в исходные состояния. Данные меняются часто и постоянно, сохранять их в ERPROM не хорошо ресурс ограничен. Данных не много достаточно 10 ячеек ERPROM. Но ,восстановление их системой занимает 3-4 часа.
Можно ли определить в Ардуино ,что сейчас будет сброс ,чтобы выполнить сохранение. Или может есть какой другой вариант. Спасибо.
Знать что будет сброс может только модуль вкантового вычисления суперпозиции ресета, экстрасенс, человек из будующего или вы когда открываете сериал соединение. )
Можно задержать сброс и сохранить переменные или вообще отогнуть ногу ресет МК и сброса вообще никогда не будет.
Я не понимаю в чем ваша проблема. Если вы часто что-то коректируете передавая по UART, то в чем проблема сохранять эти данные при изменении? Какая разница, что вы их сохраните в ЕЕПРОМ до сброса или после? ведь количество перезаписей в ЕЕПРОМ от этого не уменьшится.
Если у вас есть данные, которые быстро меняются, то зачем их вообще сохранять если они быстро меняются? Насколько часто меняются? раз в час? а если так то при ежечасной перезаписи ячейки хватит на 11 лет.
А если вы имеете ввиду под "детальные установки и корректировки производяться с компьютера" перепрошивку МК, то либо мудрите ресет с задержкой, либо дополнительную кнопку по нажатию, которой переменные будут сохраняться в ЕЕПРОМ.
Ещё раз попробую описать. Работает система и оптимизирует свои показатели на основе сбора статистики (период 1 мин). Время на сбор статистики (постояно меняющейся) примерно 3-4 часа. Когда статистика собрана ,то система работает в оптимальном режиме. Я решаю, например установить таймер на некое действие или ещё что либо. Для этого мне надо подключиться к Ардуино с компьютера. При подключении происходит сброс и весь накопленный опыт пропадает.
Я согласен ,что если сделать кнопку сохранить ,то проблемы нет. Но это примитив. Можно отказаться от сброса отпаяв ногу. Ну и самое примитивное переписать на бумажку все значения.
Меня интересует что то вроде события OnShutdown, OnClose ,ну или какое то аппаратное решение. И не надо экстрасенсов предлагать.
Вижу ещё один вариант. Подключить SRAM по I2C и загонять туда данные. При инииализации их считывать. Эта память не протрётся ,её и подпитать наверно можно. Если кто с этим работал поделитесь.
Спасибо.
При соединении с компа не обязательно должен быть ресет. Раньше при использовании родного ИДЕ так и было, сейчас использую MS Visual Studio 2010 с установленым плагином для ардуино. Так тут подключайся/отключайся сколько влезет - программа продолжает работать и никакой перегрузки не происходит.
Еще как вариант сделать кнопку при нажатии которой все данные сохранятся в еппром, после чего можно спокойно подключатся. Ну и при старте программы доставать их оттуда в сетапе. -- Уже предлагалось выше, не заметил.
Вижу ещё один вариант. Подключить SRAM по I2C и загонять туда данные. При инииализации их считывать. Эта память не протрётся ,её и подпитать наверно можно.
Тогда уж что-нибудь вроде Nonvolatile RAM. Подводите сигнал с RESET микроконтроллера к ноге STORE микросхемы и данные пишутся в ее EEPROM (из ее же RAM'а). Цена вопроса - 2-3 доллара.
А еще есть чисто RAM-микрухи, но с интегрированной в них батарейкой и заявленным ресурсом несколько лет.
Дуинка резетится от втыкания - вытыкания USB, если она была под внешним питанием. Т.е она работает, работает, втыкнули в нее USB (просто втыкнули в нее и комп, без открытия порта, передачи чего-либо) она резетится (Во всяком случае, у меня так было).
Если топикстартер имеет ввиду именно это, то на мой взгляд самое простое - сделать так, чтобы ПИТАНИЕ на дуину по USB не шло (например, перерезать "+" в USB кабеле).
Нашел решение своей проблемы.
В микросхеме часов DS1307 есть 56 байт энергонезависимой памяти NVRAM. Записывать можно что угодно и сколько угодно раз. Всё сохраняется т.к. есть батарейка. Сделал так ,при изменении параметров происходит запись в эту память ,ну а при инициализации и сбросе всё восстанавливается. Теперь при подключении к Ардуино с компьютера или при отключении необходимые данные не пропадают ,а сохраняются . Что то вроде файла ini.
На самом деле, можно беспалевно пользоваться EPROMом его ресурс перезаписи значительно превышает 100.000 записей, и сильно зависит от их частоты.
Так-что разместив в одной ячейке указатель адреса, и всякий раз проверяя данные после записи, изменяя указатель в случае сбоя, можно использовать встроенный EPROM долго и счастливо...
Обсуждали. Данные меняются 1 раз в минуту ,60 раз в час ,1440 раз в сутки ,43200 раз в месяц. EPROM хватит на 2 с небольшим месяца потом в этих ячейках будет "дырка".
Число циклов до первого сбоя около 5647899\43200=130 месяцев и это ещё без ремапа! Кроме того приведено число циклов перезаписи с максимально возможной интенсивностью и даже при таких условиях речь идёт о разовом сбое, а не о прожженой ячейке. Тут знаете-ли четырёхбайтные счётчики, через ноль перекручиваются, так-что.
А проверять корректность записи нужно всегда и с вашей кнопкой, а то мобилка зазвонит, зажигалка счёлкнет, всякое бывает...
Откуда вы взяли эту цифру 5647899?
Например отсюда:
Из даташита:
Сейчас запустил этот тест по уничтожению ячейки ради интереса, как встанет отпишусь, но уже перевалило за 200000 перезаписей.
Я с вами всё равно не согласен ,т.к. написано в даташите 100000 ,значит нарушать не положено. Тем более через 2 с небольшим месяца попадаешь в зону риска. А это отопление моего жилища и впереди зима.
Ваш кусок кода ничего не доказывает ,да и как у вас такое число получилось тоже не ясно. Записывать в ячейку то 2 то 3 (0010 или 0011 двоичное представление), т.е. переписывать один единственный бит это не серьёзно. Надо записывать ,хотя бы 0 и 255 (0000 и 1111 ). Да и время не плохо бы дать на реакцию после записи. Вам есть ещё поле для эксперементов, если ещё ячейки остались нетронутые.
Вот две таблицы из даташита на контроллер (стр 22 и 23) ,разве здесь не о времени на реакцию записи.
Здесь о времени записи, EEPROM.h написана так что пока запись не окончена при последующей записи программа ждет. А попытка записи/чтения в/из ячейку, которая еще записывается скорее всего приведет к искажению данных.
Т.е. в EEPROM.h есть задержка времени? Не знал. Странно, но там нет такого. И как это пока запись не окончена программа ждет.
В моём представлении процессор,регистры ,RAM намного быстрее ,чем EEPROM и Flash. Даже если всё это в одном корпусе.
zhuki, таблица показывает минимальное время записи, которое меньше сделать нельзя. (Я читал и смотрел примеры).
В описании достаточно ясно всё прописано. Сначала нужно дать разрешение записи, затем - строб, если строб не успел дать, данные не запишутся. Вообще про это есть хорошие примеры (жаль ссылку дать не могу, не помню), там всё конкретно.
Удачи!
Если быть точнее то это происходит в библиотеке avr/eeprom.h, которая обернута в EEPROM.h, это бит EEWE и пока он взведен нельзя ни читать ни писать. Но этой задержки естественно не будет, если записывать/читать ЕЕПРОМ с интервалом больше чем 1,8мс (3,6мс).
Вот строка из примера работы с ЕЕПРОМ на С:
вот на асме:
Тоесть если вы попытаетесь записать/прочитать сразу после предыдущей записи, то программа будет крутиться в цикле и ждать сброса EEWE.
В нашем же случае, когда мы хотим убить ячейку как можно быстрее эта задержка будет.
Итак результат. Первый сбой произошел на 6321455 цикле перезаписи! Очень не плохо! Последующие после 12477, 1129, 2891, 6257. Можно считать, что ячейка сносилась.
В принципе если данные не так важны, то можно смело писать/стирать и не париться.
Еще можно организовать дублирование данных и проверку, то есть копировать каждый байт например 3 раза и записывать в 3 ячейки ЕЕПРОМ, а при чтении сравнивать эти копии и если 1 из 3 байт не равен оставшимся двум, то за верное значение принять то что в этих двух байтах. Вероятность того, что две ячейки дадут сбой одновременно и (или), при котором байты одинакого покоцаются стремится к нулю.
Тогда для задачи поставленной выше ЕЕПРОМ хватит на ~10 лет.
Жалко ячейку то ! сносу не было , 10 лет могла работать, а максим за сутки угробил ))
"Все что должен знать схемотехник о долговечности EEPROM" (с точки зрения MICROCHIP):
максимальное количество циклов стирания/записи - "а кто ж его знает"
порог массового нарастания сбоев - 2.000.000
порог надежного стирания/записи - 1.000.000 (здесь схемы коррекции ошибок еще успевают справляться с нарастающим количеством сбоев)
Ну, а гарантированные (гарантируемые?) пороги - см. даташиты на ИС.
Спасибо всем .Дискуссия получилась интерестная и познавательная.
Что же касается дела,то имея на борту NVRAM ,я все таки предпочитаю использовать ее. Всем спасибо.
Ваш кусок кода ничего не доказывает ,да и как у вас такое число получилось тоже не ясно. Записывать в ячейку то 2 то 3 (0010 или 0011 двоичное представление), т.е. переписывать один единственный бит это не серьёзно. Надо записывать ,хотя бы 0 и 255 (0000 и 1111 ). Да и время не плохо бы дать на реакцию после записи. Вам есть ещё поле для эксперементов, если ещё ячейки остались нетронутые.
Имеющий ум, да сочтит :-) А экпериментов, была проведена масса, разных, это я для вас, ардуринщиков, накалякал, и у кого-то оно даже заработало :-) 2-3 или 0-255 для атмеги не принципиально. Не в коем случае, не пытаюсь Вас в чём то переубедить, ибо изначальная задача Ваша, решалась не памятью, но лёгким движением ножа, или демонтажем перемычки.
А тем кто умеет считать, и логически мыслить, тема действительно пригодится. Главное в ней то, что ресурс перезаписи больше чем количество ячеек. И обходится самыми примитивными алгоритмама ремап-а, увеличивающими и без того не малый ресурс.
PS. Кому интересно, вставьте задержку в цикл, получите другую цифру, но не скоро :-) Цифра так-же зависит от качества питания меги, которая весьма прожорлива в режиме программирования.