объем EEPROM в китайском DS1307 real time clock module
- Войдите на сайт для отправки комментариев
Имеется китайский модуль I2C RTC DS1307 AT24C32 Real Time Clock Module.
Из названия следует, что в нем уставлена EEPROM AT24C32, объем которой 32 кбит = 8 кб. Но в моем экземпляре данный чип промаркирован как ATMLH134 320M. Через wire по стандартному адресу девайса 0x50 успешно записал и считал байт 222 в 10 ячейке, для примера. Возникает вопрос: как узнать объем моего конкретного чипа? даташит на него не нашел. А насиловать его многократной циклической записью с начала, что будет как я понял происходить при превышении конечного адреса, я не хочу. Да и придумывать, что же именно туда писать такое, что потом легко выдаст цикличность - как-то нет желания. Возможно придется это делать, но может кто-н сталкивался уже с подобным и имеет ответ на этот вопрос?
писать 1 2 3 4 5 6 7 8.. как наткнешься на 1 значит все, второй круг
мб там 320 мбит?)
Надо еще подумать над тем, как адресовать 8кб ячеек. Я когда-то пробовал с ней развлекаться, но дальше записать-прочитать дело не пошло...
ошибся чуток, 32/8 =4, т.е. там 4кб должно быть, если этот чип аналог того что в описании.
а писать последовательно 0, 1, 2, 3.. так только до 255 можно. потом уже надо два байта писать.. и как-то все это учесть. По идее должно сработать, в начале хрень будет другая вместо 0, 1, 2.. после циклической перезаписи. Так-то eeprom вряд ли настолько мелкий по объему, что это дело его убьет.. но все ж хотелось бы наименее затратный и простой способ узнать. Китайцу-продавцу написал еще, вдруг ответит чего и правду)
насчет 320 мбит.. вряд ли, там эта надпись второй строкой идет, возможно и нет в ней смысла. но первая строка занимает все место, так что на всякий случай написал и вторую. На китайских сайтах что-то такое мне попадалось, но не скачать ничего оттуда было. и кругом одни иероглифы, и гугл не помогает))
ошибся чуток, 32/8 =4, т.е. там 4кб должно быть, если этот чип аналог того что в описании.
а писать последовательно 0, 1, 2, 3.. так только до 255 можно. потом уже надо два байта писать.. и как-то все это учесть. По идее должно сработать, в начале хрень будет другая вместо 0, 1, 2.. после циклической перезаписи. Так-то eeprom вряд ли настолько мелкий по объему, что это дело его убьет.. но все ж хотелось бы наименее затратный и простой способ узнать. Китайцу-продавцу написал еще, вдруг ответит чего и правду)
насчет 320 мбит.. вряд ли, там эта надпись второй строкой идет, возможно и нет в ней смысла. но первая строка занимает все место, так что на всякий случай написал и вторую. На китайских сайтах что-то такое мне попадалось, но не скачать ничего оттуда было. и кругом одни иероглифы, и гугл не помогает))
зачем до 255, если в дефолте они пустые пиши просто 1 пока 1 не найдешь
там ячейка на 100к перезаписей расчитана, то что ты 1 раз туда просто так запишешь 1 ей погоды не сделает
да и перебрать все не так уж и долго и затратно
о, дошло)) хотя может и не совсем то. что-то я тупанул совсем. можно ж просто записать 1 в начальную ячейку, а дальше читать все подряд, пока не наткнусь на свою единицу=) обнулив перед этим то что в примеред делал, да и вообще проверить надо на всякий случай сначала, пустые ли они все.
а в друг они мусором забиты?
можешь не ту 1 найти
только что закончил с проверкой, мусор был до 29 ячейки, в остальных - 255. почистил. ща пишу проверку на объем..
все проверил, единичка только в начале, и на всякий случай накинул +1 на предполагаемый размер 4кб - показало еще единицу после этого по адресу 4096.
Где-то обсуждалась память DS1307, так вот, если я не пропустил ничего - поздравляю всех обладателей подобных модулей: помимо часов у вас есть EEPROM на 4кбайта. AT24C32 по даташиту имеет миллион циклов перезаписи, что на порядок больше того что у нас в МК. Как с этим дела у моего видимо китайского аналога не знаю, но все равно круто. будет куда чего сохранять, не особо заботясь о ближайших 10-20 годах)) а заменить в случае чего модуль часов намного дешевле и проще, чем дуину со всем, к ней подключенным. Дату и время часы после моих манипуляций показывают как и раньше, с февраля примерно убежали на полторы минуты.
миллион на ячейку или всеко миллион раз записать?
и зачем всю ардуину?
если у тебя Uno то можно только чип заменить, стоит он рублей 400
скорее всего имеется в виду ячейка, остальные ведь не трогаются по идее. написано только это:
Endurance: 1 Million Write Cycles
насчет чипа да, можно в том случае если он достаточно крупный. а мелкие паять я лично не умею, если вообще возможно на меге например самому такое проделать.
Во всю использую AT24C32 - там 4 килобайта. В библиотеке функция блочной записи работает только с "ровными" блоками и при достижении конца блока начинает писать в него же с начала. После любой записи надо ждать 10-20 мс до следующей операци с AT24C32. А так отличный шустрый и надежный чип.
что то мне не верится что там надпись 320М. может таки 32СМ?
вроде, больше похоже на 32DM... а мне показалось что 320 ))) ну и ладно, главное что все уже стало ясно.
Во всю использую AT24C32 - там 4 килобайта. В библиотеке функция блочной записи работает только с "ровными" блоками и при достижении конца блока начинает писать в него же с начала.
Библиотека-то как называется?
Библиотека своя на основании примеров
i2ceeprom
i2ceeprom.h
i2ceeprom.cpp
ales2k, а можно пример использования вашей билиотеки для работы с eeprom.
Простой кусочек кода из какогото примера - не помню из какого.
Спасибо!!
Функция i2c_eeprom_write_block принимает аргумент
unsigned
int
eeaddress
, для чего вы перед отпрвавкой eeaddress преобразовываете в int:Wire.write((
int
)(eeaddress >> 8));
при условии что отправляется байт? Может преобразовать сразу в байт:Wire.write((
byte
)(eeaddress >> 8));
Так же обратите внимание на аргументvoid
* data,
при передачи его в функцию вы преобразовываете в byte*:(
byte
*)somedata
, а затем внутри функции делаете тоже самое еще раз:const
byte
* current = reinterpret_cast<
const
byte
*>(data);
так может тогда логичнее делать это один раз например только внутри:i2c_eeprom_write_block(0x50, 0,
somedata,
sizeof
(somedata))
.По первому пункту абсолютно согласен, не обратил внимания, по второму преобразование внутри функции сделано для совместимости, а пример давний, еще до этого изменения.
Спасибо за уточнения.
Интересно этот компилятор такие простые ошибки отлавливает при оптимизации выполнения и выкидывает не нужные действия?
Офтопик
Может на форуме завести раздел для библиотечек. Я бы поделился накопленными и написанными и подправили косяки заодно.
Скорее всего компилятор оптимизирует, так что если проверить хотябы по размеру скоплированного файла - размер будет одинаковый.
Добрый день!
Будьте любезны, подскажите как при помощи этого кода:
сохранять несколько переменных, например: current_day=3; day_X=27; temp_min=18; temp_max=22; light_on=6; light_off=21; и т.д., а затем при необходимости считывать?
Проблема именно в организации сохранения значений при записи, а так же разнесении символов по переменным при считывании.
Будьте добры, посоветуйте.
Для меня это ОЧЕНЬ замечательная находка для сохранения небольших данных при отключении питания.
ОГРОМНОЕ спасибо ales2k за реализацию библиотеки.
Проблема именно в организации сохранения значений при записи, а так же разнесении символов по переменным при считывании.
Как выглядит код, который сохранит значения переменных в EEPROM, а затем считает их и присвоит переменным.
Может под каждую переменную выделить свои адреса и писать только в них, а значит и считывать в переменные из конкретных адресов?
Как выглядит код, который сохранит значения переменных в EEPROM, а затем считает их и присвоит переменным.
Может под каждую переменную выделить свои адреса и писать только в них, а значит и считывать в переменные из конкретных адресов?
Ну как вариант, может по аналогии с SD картой получится?
ну только без myFile.close(); и тому подобного
Я бы сделал структуру и сохранял всю структуру целиком, затем читал всю структуру.
По примеру как это сделано с массивом char
somedata[] =
"this is data from the eeprom"
;
Никакой существенной разницы.
Только стоит помнить о ресурсе EEPROM примерно 10000 записей в одно место.
Ну как вариант, может по аналогии с SD картой получится?
Этот вариант к адекватным не относится.
Я бы сделал структуру и сохранял всю структуру целиком, затем читал всю структуру.
"Каждый сам творец своего счастья" так что
http://playground.arduino.cc/Code/Struct
Покажите, пожалуйста, пример с двумя переменными - послужит образцом.
Извините, опоздал с просьбой.
Спасибо, буду читать.
Как то так
Обратите внимание на типы переменных, если у вас все типы переменных byte (char), то применять структуры бессысленно.
Поправь - ты 2 раза пишешь в EEPROM
И зачем данные структуры переменным присваивать - ими и так пользоваться можно и удобно
Поправил, ну так вы же не знаете как потом будут этим пользоваться. Может у AndyResh кода на 2 листа с этими переменными, что ему теперь весь код править...
Гениально! БЛАГОДАРЮ!
Я бы и поправил весь код если бы нужно было, а так - вообще замечтательно!
Как же ВЫ мне помогли, и последующим поколениям тоже.
На примере стало понятно откуда все берется и куда потом деётся.
Ctrl+F7 в редакторе FAR'а :)
Ctrl+F7 в редакторе FAR'а :)
В IDE Ctrl+F достаточно))
Тут вот какая загогулина получается. Понимаю рассудком, что чудес на свете не бывает, однако...
Создал папку \SOFT\ARDUINO\libraries\i2ceeprom , в нее положил файлы i2ceeprom.h и i2ceeprom.cpp
инклудил, собственно в шапку скетча #include <i2ceeprom.h> , а IDE 1.0.2 ругается:
sketch_LCD1602_RTC_Reley_DHT_31_10_2013.ino: In function 'void setup()':
sketch_LCD1602_RTC_Reley_DHT_31_10_2013:105: error: 'i2c_eeprom_read_buffer' was not declared in this scope
Как буд-то на видит библиотеку. От чего может так получится?
Ниже "портянка" целиком, версия на стадии написания/отладки/дописания
P.S. В листинге некоторые форумчане могут заметить части своих кодов)) За что им отдельная благодарность!
Нужно перезайти в среду разработки
...так ведь несколько раз это делал, пока переименовывал то в FAR'e, то показалось, что что-то с кодировкой внутри библиотек, то перебирал варианты с шапкой: #include <i2ceeprom.h> или #include 'i2ceeprom.h" (DHT у меня только так заработал), и каждый раз рестартил IDE.
Если какая-то банальность или моя невнимательность - придется застрелиться))
А так, может подскажете в каком направлении копать дальше, вроде и в более сложные вопросы приходилось вникать, а тут..?
О Боже! Что за волшебство?!
С конструкцией
все заработало, точнее - откомпелилось.
Проверить на железе нет возможности от RTC до МЕГИ нога отвалилась, а на работе паяльник непредусмотрен должностью))
Вечером отпишусь, как устраню железный баг.
Почитал даташит на еепром этот, там написано что можно писать страницами до 32 байт. глядя на реализацию этого дела, становится понятно, что оно будет пошустрее, чем если писать каждый байт по отдельности - как минимум, не надо передавать в еепром каждый раз адрес. да и отправка адреса устройства по i2c тоже время занимает. Функция записи блока, которая тут валяется вместе с остальными, записывает побайтно из этого блока в еепром. Можно модифицировать. Пока лишь сделал набросок проверочный, может сегодня доделаю и полностью готовый вариант. Как оказалось, можно записать так только 30 байт. Наверно 32 имелось в виду вместе с байтами адреса, которых 2. но в даташите это описали как 32 байта данных. ну и пох. После завершения этой функции надо обождать чуток, я ждал 50мс перед проверочным чтением. Может хватит и 20.
Причем при записи 32 значений последние 2 не записываются, но и не происходит переполнения и записи с начала текущей страницы. Почему так - не знаю.
Если из функции записи блока для каждых 30 байт записывать постранично - будет намного быстрее. Тк помимо прочего еще и delay(20) или около того не нужен после записи каждого байта.
Сделал функцию, но почему-то хрень она записывает. Если размер блока 30 - еще норм. если больше - происходит ерунда. Даже с задержкой в секунду между записями страниц. Есть у кого идеи?
Здесь какой-то код есть, тоже со страничной записью, но возможно там просто ограничили длину записываемой последовательности, мне так показалось. Чето там немного мудреное для меня, кому интересно посмотрите. Так-то по уму надо заменить цикл с Wire.Write(*data) на Wire.Write(*data, count), но вряд ли это что-то исправит. ночью проверю
http://forum.arduino.cc/index.php?topic=90594.0
Баг железный устранил, однако работать, как планировалось, программа на стала. При запуске дисплей чистый, на кнопки реагирует, по меню ходит, но текущий день (current_day), день Икс (day_X), а так же дата с RTC выглядели ужастно. Так текущий день подгрузился 1501 (неадекватный параметр натолкнул на мысль, что ячейки на EEPROM RTC были заведомо не пусты); дата не отображалась, а при попытке забить ее вручную из меню, писала, что сохранилась, но по факту этого не происходило.
Курю код дальше.
Код по ссылке рабочий. Но каким образом работает там функция записи страницами - никак не пойму. может кто пояснить? там же адрес отправляется один и тот же..
все, дошло. там они этот аргумент функции меняют как переменную в теле функции.... я к такому как-то не привык, не заметил даже. ну примерно ясно теперь. кроме & ~ () вот этого.
так что обновите свой функционал! и задержку можно поискать вместо 50 какую поменьше можно поставить, наверно.
нашел, все-таки нужную тему..
Пробую добавить библиотеку:
Скачут ошибки:
Что не так?..
Помоему у тебя какието проблемы с библиотекой <Wire.h>, попробуй обновить...
Потому что IDE у него лохматой 0022 версии.
Потому что IDE у него лохматой 0022 версии.
Максим, а где взять свежее ? Что-то весь сайт перерыл, там только Arduino 1.0.5 и Arduino 1.5.6-r2...
с обозначениями у них беда, но 1.0.5 и есть более новая, чем 0022 :)