Официальный сайт компании Arduino по адресу arduino.cc
Запись в EEPROM
- Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии
Сб, 26/01/2013 - 14:55
Не могу разобраться в старших-младших байтах. Нужно записать число 3000 в память и потом прочитать его - покажите пожалуйста примерчик как это сделать.
Вначале решите задачу просто "3000 разобрать/собрать" в две байтовые локальные переменные. А потом будете заморчаватся как эти две переменные в EEPROM сохранить (я же так понял "сохранить один байт" уже проблем не вызывает).
Разобрать:
http://arduino.cc/en/Reference/LowByte
http://arduino.cc/en/Reference/HighByte
Собрать:
или
http://arduino.cc/en/Reference/WordCast
Ну или вот разбор "по крутому", без ардуино функций
С сохранением байта проблем нет. По ссылкам я уже смотрел, но там чайнику ничего не понять. Методология как бы понятна - разбиваю число на 2 байта (старший -младший), пишу в память, читаю, собираю. Примеров на С++ найти не смог.
С сохранением байта проблем нет. По ссылкам я уже смотрел, но там чайнику ничего не понять.
Ну тогда я не знаю что "чайнику понять". Вызов готовой функции это сложно? Ну проще уже просто ничего в природе не бывает. Разве что "сложить переменные". Я понимаю если еще вариант со сдвигами пугает. Но с highByte(),lowByte() и word()? Они же как раз "для чайников" и писались. В "боевом коде" вы их редко встретите (просто не нужны, зная битовые операции и без них не сложно)
Примеров на С++ найти не смог.
Не ну знаю как вы искали. В крайнем случае я вроде уже дал вам примеры. Причем "в двух вариатах" и через функции и через битовые операции.
Спасибо за пример. Буду пробовать.
С сохранением байта проблем нет. По ссылкам я уже смотрел, но там чайнику ничего не понять. Методология как бы понятна - разбиваю число на 2 байта (старший -младший), пишу в память, читаю, собираю. Примеров на С++ найти не смог.
Цитируемый тут "сдвиг на 8 позиций" (>>8) - как раз те самые примеры, ведь Ваши три тысячи представляются в двоичном коде как-то так:
~$ echo "obase=2;3000" | bc
101110111000
Есть два способа.
Первый - с помощью битовых операций, описанный выше.
И второй - работа с памятью:
Пример:
Ну точнее было-бы назвать это "через указатели". Хотя раз highByte() и lowByte() вызывали проблемы, то не думаю что через указатели будет "понятней".
Но раз пошло "писькомерство" :), то вот еще один вариант, через структуры и объединения.
Топикстартеру: это "факультативно", если будет интерестно погуглить разобратся как оно работает. Это скорее не пример "нужно обязательно разобратся", а "наш ответ чемберлену/Максиму" ;) "Программерские этюды" :)
А еще нагугливается куча всяких "библиотек-расширений" которые все эти задачи "разобрать/собрать" берут на себя. Сразу умеют int и прочие стандартные типы сохранять.
http://playground.arduino.cc/Code/EEPROMWriteAnything
http://playground.arduino.cc/Code/EepromUtil
http://playground.arduino.cc/Code/EEPROMex
и т.д. и т.п.
А вот есть ли смысл сразу проверять то, что записали? Или оно все равно может позже прочитаться с ошибкой?
А вот есть ли смысл сразу проверять то, что записали? Или оно все равно может позже прочитаться с ошибкой?
Ну, теоретически может. Раз есть ресурс "сколько циклов записи выдерживает" - значить рано или поздно он закончится.
Но IMHO больший смысл имеет чтение ПЕРЕД записью. Если содержимое ячейки и "что собираемся записать" уже совпадает - нечего не делаем. Экономим ресурс EEPROM. А еще, можно, время от времени, менять адреса по котороым пишем. Если данных темного, то ресурс можно увеличить "размазывая" данные по адресному полю с течением времени.
Спасибо за помощ. Записываю и читаю с разделением на 2 байта. Хотел использовать библиотеку EEPROMex , но там косяки. Замены по рекомендации автора библиотеки ничего не дают. Может после модернизации будет работать.
А еще, можно, время от времени, менять адреса по котороым пишем. Если данных темного, то ресурс можно увеличить "размазывая" данные по адресному полю с течением времени.
А как их потом читать? Ведь мы в программе достаточно жестко зашиваем "координаты" тех или иных данных... Если мы их начинаем раскидывать в случайном порядке по всей памяти - надо где-то хранить координаты последих записанных данных. Или увеличить записываемые данные дополнительным полем "дата" и потом, читая все устройство целиком, выбирать максимальное значение даты. Не получится ли это дольше?
А еще, можно, время от времени, менять адреса по котороым пишем. Если данных темного, то ресурс можно увеличить "размазывая" данные по адресному полю с течением времени.
А как их потом читать? Ведь мы в программе достаточно жестко зашиваем "координаты" тех или иных данных... Если мы их начинаем раскидывать в случайном порядке по всей памяти - надо где-то хранить координаты последих записанных данных. Или увеличить записываемые данные дополнительным полем "дата" и потом, читая все устройство целиком, выбирать максимальное значение даты. Не получится ли это дольше?
Ну тут уже на что фантазии хватит и от конкретного проекта зависит. Можно "по понедельникам" в одни адреса, по вторникам - в другие. Можно руками менять раз в месяц. Можно, к примеру, обнулить все EEPROM и записывать "в первую ячейку отличную от нуля". А читать, наоборот "идем с конца пока будет что-то не ноль, это и есть наши данные".
Можно - не делать запись вообще. Записывать только когда "выключаемся". Следить за питанием, поставить какой-нибудь конденсатор который может несколько микросекунд удержать дуину "на плаву". Начала "падать питание" - быстренько сохранили из памяти в EEPROM.
Вообщем это уже простор для вашей фантазии и потребностей. Если вы пишите в EEPROM два раза в день - можно и не морочится.
Читаю одновременно два параметра. Как правильно записать. Получается повторное декларирование.
Так естественно, просто объедините в функцию...
Читаю одновременно два параметра. Как правильно записать. Получается повторное декларирование.
Сами спросили - сами ответили :) Все верно - повторное деклалирование.
Пользуйтесь уже готовым массиом.
Так естественно, просто объедините в функцию...
А если в функцию, то не проще ли уже
То же самое сделайте и с записью
Так естественно, просто объедините в функцию...
А если в функцию, то не проще ли уже
В общем дело вкуса...
Доброго здравия. Подскажите если не в тягость: При загрузке нового скетча через IDE очищается eeprom. Геморно потом снова перепрописывать, к то му же каждый час данные меняются. Есть возможность загружать скетчь, чтоб не трогать eeprom?
Необходимо изменить фьюз EESAVE микроконтроллера
Всё гениальное - просто (А. Эйнштейн). Принято, спасибо.
Вот ещё, может кому пригодиться, малёк закоментировал для себя:
Взято отсюда, проверено работает.
е
можете помоч почти с подобным премером?
можете помоч почти с подобным премером?
не, никак, мы токма позыркать тут...
Вначале решите задачу просто "3000 разобрать/собрать" в две байтовые локальные переменные. А потом будете заморчаватся как эти две переменные в EEPROM сохранить (я же так понял "сохранить один байт" уже проблем не вызывает).
Разобрать:
http://arduino.cc/en/Reference/LowByte
http://arduino.cc/en/Reference/HighByte
Собрать:
или
http://arduino.cc/en/Reference/WordCast
можете помоч в подобном премере?
Люди, есть кнопка (передатчик) и реле (приёмник), реле должно помнить состояние себя, причём оно может его забыть, например перезагрузившись по watchdog. Если кнопка забудет - плевать, её просто нажмут второй раз.
В общем, пришла идея писать это состояние в память, а т. к. включается/выключается регулярно, то писать каждый раз в новое место (следующее за прошлым местом или в начало если прошлым был конец). Покритикуйте функцию.
Которая говорит, куда писала:
Которая пишет молча:
Поляризованное реле не "забывает" своего состояния, а , наоборот, помнит.....
https://www.google.ru/search?q=%D0%BF%D0%BE%D0%BB%D1%8F%D1%80%D0%B8%D0%B...
Лень доставку ждать :)
А про память есть мнение?
Чё то бардак какой то... Если записываем в ячеку состояние, то нужно сначала прочитать из какой то ячейки номер ячейки в которой записано последнее состояние перед отключением (или перезагрузкоой).
А ты читаешь из ячейки, только что объявленной переменной "i".
цЫкл же?
В том и смысл: мы не знаем куда писать. Ищем то место, которое отличается от 0xFF. "Стираем", записав поверх старой информации 0xFF и в следующий байт пишем. Не?
Читающая функция будет наподобие. Ну и ессно потом допишу "перед тем как писать, прочитать - если то же самое - ничё не делать".
Тут-то суть именно в том чтобы избавиться от "куда писали", потому что - ну пишем мы в первые байты, и в самые последние два - собсно адрес. Значит, эти последние два байта будут изнашиваться в (1024-2)/2=511 раз быстрее. Не? Мы же пишем переменно один/много байт информации в много байт памяти. И два байта адреса в два байта памяти. Надеюсь понятно...
Все правильно. Я бы еще избавился от постоянного поиска нужной ячейки и делал бы его только при старте МК.
По поводу записи/чтения EEPROM. Есть такая библиотека, которая умеет сохранять/читать числа с любой размерностью byte int long или даже массивы, причем делает это автоматически. Я пользовался - классная штука. Кому нужно могу на github-е выложить
Ну или вот разбор "по крутому", без ардуино функций
Подскажите как число 999 999 999 (9-ти значное) записывать в память? т.е. метод разделить на старший и младший байт из этой темы не подойдет?
т.е. разделить число на 4 байта
Пойдет, только делите на большее чисто байт. Например так для 3-x байт:
byte b1=value>>16;
byte b2=value>>8;
byte b3=value;
По аналогии хоть 128 битное число раскладывайте, разница будет только в количестве байт.
Ясна спасибо.
Пробую запустить код на запись \ чтение памяти ds1302. Использую доработанную библиотеку отсюда: ссылка
По аналогии из этой темы написал:
При компиляции пишет ошибку на строку 2: error: no matching function for call to 'makeWord(uint8_t, uint8_t, uint8_t)'
Подскажите как переписать функцию сбора значения из памяти...
А строка 9 точно верно?
может надо
да верно, опечатался...
Строка word(rtc.readRAM(addr),rtc.readRAM(addr+1)); = Компилируется
Строка word(rtc.readRAM(addr),rtc.readRAM(addr+1),rtc.readRAM(addr+2)); = не компилируется.
Если переделать для памяти конроллера, то так же ошибка. word(EEPROM.read(addr),EEPROM.read(addr+1),EEPROM.read(addr+2));
Не силен в этом. Подскажите как можно собрать значение?
Способ был указан выше
return
((rtc.readRAM(addr) << 0) & 0xFF) + ((rtc.readRAM(addr+1) << 8) & 0xFF00)
+ ((rtc.readRAM(addr+2) << 16) & 0xFF0000);Спасибо всем. Все работает ;)
А я сделал так. Просто взял придумал 256 иричную систему исчислений :)
Считываю так:
Записываю так:
Короче много способов я думаю можно придумать чтобы разложить число по байтно.
изобретатели велосипедов, посмотрете библиотеку eepromex
Не мучайтесь, вот готовая библиотека
https://github.com/ssvs111/ARDUINO_EEPROM2
Tails_MP, напишите в подфоруме "ищу исполнителя"
Народ доброго дня суток, прошу помощи кто поможет разобраться с EEprom библиотекой. мне нужно после нажатия определенного пункта меню записоватькод Ibuton ключа в eeprom, а потом выводить эти ключи на lcd 1602, определенный ключ в определенном месте..
заранее всем спасибо за помощь)))