запись во внешнею EEPROM
- Войдите на сайт для отправки комментариев
Сб, 03/03/2012 - 23:31
КАК записать данные во внешний eeprom ? Я использовал вот этот скрипт, однако он выдаёт ошибку: строка 12 символ 1 файл не найден Информацию брал отсюда: timewitharduino.blogspot.com/2009/06/storing-strings-in-eeprom-byte-by.html
01
Const ForReading = 1
02
Const ForWriting = 2
03
04
'-------------------------------------------------------------------------
05
' open USB serial port (COMx);
06
'
07
' If the serial monitor in Arduino IDE is open, you will get an "access denied" error.
08
' Just make sure that the serial monitor is closed (so bytes are not sent by the arduino board).
09
'-------------------------------------------------------------------------
10
11
Set fso = CreateObject("Scripting.FileSystemObject")
12
Set com = fso.OpenTextFile("COM7:9600,N,8,1", ForWriting)
13
14
15
'---------------------------------------------
16
' read content of text file line by line;
17
' write line to COMx;
18
'---------------------------------------------
19
20
Set objFSO = CreateObject("Scripting.FileSystemObject")
21
Set objFile = objFSO.OpenTextFile("C:\arduino\arduino-0018\libraries\BookClock\quotes.txt", ForReading)
22
23
MsgBox("Ready to write file content to COM")
24
25
Do While objFile.AtEndOfStream <> True
26
'------------------------------------------------------------------------
27
' read 10 characters at a time; arduino serial buffer cannot take more than 32 characters;
28
' writing a character to eeprom takes about 11 ms (assuming that there is no serial.prints in the loop);
29
' therefore, after each batch of 10 chars sent to COM, we should wait no less than 110 ms;
30
' we use 200 to have a margin of safety;
31
'-------------------------------------------------------------------------
32
strChars = objFile.Read(10)
33
com.Write(strChars)
34
WScript.Sleep(200)
35
Loop
36
37
38
objFile.Close
39
com.Close()
40
41
MsgBox("Finished writing to COM")
Ну , во первых если бы вставили нормально, без мусорной нумерации строк легче было-бы читать.
Во вторых, по вашей сылке этого сприпта нет. Так что брали вы его "откуда-то еще" (скорее всего из более ранних статей).
В третьих. Это именно скрипт, а не скетч. Судя по всяму на VBScript. Так что нигде кроме на на большом комьютере вы его запустите. Да и то - только под виндой.
К "ардуине" он имеет очень далекое отношение. Фактически вообще никакого. ОН просто берет файл quotes.txt и малыми порциями отправляет его в com-порт.
Если на этом порте будет висеть ардуина (или что-то другое), и будет что-то делать с принимаемыми данными, и что будет делать - скрипт совершенно не знает.
А вот в ссылке что вы дали (кстати ссылки лучше вставлять как ссылки), похоже и есть ардуино-скетч, который "слушает" на другом конце провода. Принимает эти данные и сохраняет в EEPROM
timewitharduino.blogspot.com/2009/05/getting-arduino-to-write-to-or-read.html вот правильная ссылка
Ну, так а в чем вопрос-то?
По этой ссылке видим два VB скрипта. Один умеет принимать данные из ком-порта (арудины) и записывать их в файл, второй - наоборот. Брать данные из файла и запихивать их в ком-порт.
Оба предназначены для запуска НА КОМПЬЮТЕРЕ, причем только под windows. Не на ардуино. ArduinoIDE, естественно, на попытку их компиляции будет кричать как беременный лось в теплую погоду. Потому что и "язык не тот" и "платформа не та".
Для записи с в EEROOM вам нужно смотреть, все-таки, на ссылку из вашего первого поста. Там есть скетч (то есть то, что запускается на ардуине), который принимает данный из ком-порта и сохраняет их в EEROOM.
спасибо , буду дома попробую
Вот , что есть:
Однако при запуске скрипта выходит ошибка , хотя порт указан верно и отключен serial mnonitor, в чём может быть проблема непонятно ?
s002.radikal.ru/i197/1203/1a/746018d60111.jpg
Вот скетч , который прописан в Arduino:
/* * This sketch is to be used on either one of the 2 kinds of 24LC256 shields: * 1. one standalone, with read/write button on (input) pin 10 and read/write LED om (output) pin 12; * 2. one used in the WiseClock project, with no button and LED; * * For case #1, set WISE_CLOCK to false; for case #2, set WISE_CLOCK to true. * When in the WiseClock, the default (starting) mode is "write", that is, * the incoming bytes on COM port will be written to the eprom. * * This sketch works in conjunction with "writeFileToCom.vbs" script (also included at the bottom of this file), * which reads the content of a text file and sends it to the specified COM. * For the script to work, the serial monitor in Arduino IDE MUST be off, so the COM port can be used by the script alone. * * The mode is changed to "read" when the characters "\r" or "\l" are encountered. * "\r" will display the eprom content as individual characters (one character per line). * "\l" will display the eprom content line by line, each line ending with CR (13). */ #include <Wire.h> /* Simple read & write to a 24LC256 EEPROM using the Wire library. * Addresses are ints - 0000-7FFF (32767) Data is bytes (8 bits x 32767 = 256K) * Functions for R/W of single byte or a page of bytes. Max page is 28 bytes. * * SETUP: _ _ * Arduino GND- A0-|oU |-Vcc to Arduino Vcc * Arduino GND- A1-| |-WP to GND for now. Set to Vcc for write protection. * Arduino GND- A2-| |-SCL to Arduino 5 * Arduino GND-Vss-| |-SDA to Arduino 4 * --- (A2, A1, A0 to GND for 1010000 (0x50) address.) * If set to Vcc adds to address (1010,A2,A1,A0) */ // set to true when using the shield which is part of the Life clock sandwich; // set to false when using a shield with read/write button on pin 10 and read/write LED on pin 12; #define WISE_CLOCK true #define BTN_WRITE_IN_PIN 10 #define LED_WRITE_OUT_PIN 12 // status gets changed by pressing the button (on pin 10) or by sending the command "\r" or "\l"; boolean isWrite; // I2C Bus address of 24LC256 EEPROM; // if more than one eeprom, they will have different addresses (h/w configured); #define I2C_ID 0x50 // global address of the last written byte; unsigned int crtWriteAddress = 0; // global address of the last read byte; unsigned int crtReadAddress = 0; void setup() { if (!WISE_CLOCK) { pinMode(BTN_WRITE_IN_PIN, INPUT); pinMode(LED_WRITE_OUT_PIN, OUTPUT); // initial state is READ; isWrite = false; digitalWrite(LED_WRITE_OUT_PIN, LOW); } else { isWrite = true; } Wire.begin(); // join I2C bus (address optional for master) Serial.begin(9600); Serial.println(isWrite ? "write eprom" : "read eprom"); crtReadAddress = 0; crtWriteAddress = 0; } void writeByte(int i2cId, unsigned int eeaddress, byte data) { int rdata = data; Wire.beginTransmission(i2cId); Wire.send((int)(eeaddress >> 8)); // Address High Byte Wire.send((int)(eeaddress & 0xFF)); // Address Low Byte Wire.send(rdata); Wire.endTransmission(); delay(10); // NEED THIS DELAY! } void writeNextByte(byte data) { writeByte(I2C_ID, crtWriteAddress, data); crtWriteAddress++; } // Address is a page address, 6-bit (0..63). More and end will wrap around. // But data can be maximum of 28 bytes, because the Wire library has a buffer of 32 bytes. void writePage(int i2cId, unsigned int eeaddresspage, byte* data, byte length) { Wire.beginTransmission(i2cId); Wire.send((int)(eeaddresspage >> 8)); // Address High Byte Wire.send((int)(eeaddresspage & 0xFF)); // Address Low Byte for (byte i = 0; i < length; i++) Wire.send(data[i]); Wire.endTransmission(); delay(10); // need some delay } byte readByte(int i2cId, unsigned int eeaddress) { byte rdata = 0xFF; Wire.beginTransmission(i2cId); Wire.send((int)(eeaddress >> 8)); // Address High Byte Wire.send((int)(eeaddress & 0xFF)); // Address Low Byte Wire.endTransmission(); Wire.requestFrom(i2cId, 1); if (Wire.available()) rdata = Wire.receive(); return rdata; } byte readNextByte() { byte rdata = readByte(I2C_ID, crtReadAddress); crtReadAddress++; return rdata; } // should not read more than 28 bytes at a time! void readPage(int i2cId, unsigned int eeaddress, byte *buffer, int length) { Wire.beginTransmission(i2cId); Wire.send((int)(eeaddress >> 8)); // Address High Byte Wire.send((int)(eeaddress & 0xFF)); // Address Low Byte Wire.endTransmission(); Wire.requestFrom(i2cId, length); for (int i = 0; i < length; i++ ) if (Wire.available()) buffer[i] = Wire.receive(); } //------------------------------------------------------------------------------------- // used for the standalone shield, with read/write button (pin 10) and LED (pin 12); #define BOUNCE_TIME_BUTTON 200 // bounce time in ms for the WRITE button; volatile unsigned int btnPressTime = 0; // executed as a result of the menu button being pressed; // determines the menu to be displayed and the menu option to be increased; void processWriteButton() { // debouncing; if (abs(millis() - btnPressTime) < BOUNCE_TIME_BUTTON) return; btnPressTime = millis(); isWrite = !isWrite; digitalWrite(LED_WRITE_OUT_PIN, (isWrite? HIGH : LOW)); crtReadAddress = 0; crtWriteAddress = 0; } //------------------------------------------------------------------------------------- byte lastReadByte = 0; // current line string is built by copying each character to the position of the pointer, then advancimng the pointer; char msgBuffer[200] = {0}; char* msgBufferPtr = &msgBuffer[0]; boolean isCommand = false; boolean isReadLineByLine = false; void loop() { if (!WISE_CLOCK) { // read the state of the WRITE button; if (LOW == digitalRead(BTN_WRITE_IN_PIN)) processWriteButton(); } if (isWrite) { if (Serial.available() > 0) { // read next character from COM port; byte incomingByte = Serial.read(); if (isCommand && (incomingByte == 'r' || incomingByte == 'l')) { isWrite = false; Serial.println("read eprom"); switch (incomingByte) { case 'r': isReadLineByLine = false; break; case 'l': isReadLineByLine = true; break; } } else { isCommand = false; if (incomingByte == '\\') { // don't write the backslash; isCommand = true; } else { // the following debug lines (serial.print...) take about 25 more ms than the write itself (10 ms); // it is a good idea to comment them out if we transfer the content (32K) of a whole file; /* Serial.print("write to addr "); Serial.print(crtWriteAddress); Serial.print(" byte "); Serial.println(incomingByte, BYTE); */ writeNextByte(incomingByte); } } } } else // reading the eeprom; { if (isReadLineByLine) { // read a whole line into the message buffer; lastReadByte = readNextByte(); while (lastReadByte != 13 && lastReadByte != 0xFF) { *msgBufferPtr++ = lastReadByte; lastReadByte = readNextByte(); } *msgBufferPtr++ = 0; Serial.println(msgBuffer); msgBufferPtr = &msgBuffer[0]; // reset buffer pointer; delay(50); } else { if (0xFF != lastReadByte) { Serial.print("read from addr "); Serial.print(crtReadAddress); Serial.print(" byte "); lastReadByte = readNextByte(); Serial.print(lastReadByte, BYTE); Serial.print(" ("); Serial.print(lastReadByte, DEC); Serial.println(")"); delay(50); } } } } /**************************************************************************************** Const ForReading = 1 Const ForWriting = 2 '------------------------------------------------------------------------------------------------ ' open USB serial port (COMx); ' ' If the serial monitor in Arduino IDE is open, you will get an "access denied" error. ' Just make sure that the serial monitor is closed (so bytes are not sent by the arduino board). '------------------------------------------------------------------------------------------------ Set fso = CreateObject("Scripting.FileSystemObject") Set com = fso.OpenTextFile("COM3:9600,N,8,1", ForWriting) '--------------------------------------------- ' read content of text file line by line; ' write line to COMx; '--------------------------------------------- Set objFSO = CreateObject("Scripting.FileSystemObject") Set objFile = objFSO.OpenTextFile("C:\docs\quotes.txt", ForReading) MsgBox("Ready to write file content to COM") Do While objFile.AtEndOfStream <> True '--------------------------------------------------------------------------------------------------------- ' read 10 characters at a time; arduino serial buffer cannot take more than 32 characters; ' writing a character to eeprom takes about 11 ms (assuming that there is no serial.prints in the loop); ' therefore, after each batch of 10 chars sent to COM, we should wait no less than 110 ms; ' we use 200 to have a margin of safety; '--------------------------------------------------------------------------------------------------------- strChars = objFile.Read(10) com.Write(strChars) WScript.Sleep(200) Loop objFile.Close com.Close() MsgBox("Finished writing to COM") *********************************************************************************/а вот Тот, что используется VBscript:
Const ForReading = 1 Const ForWriting = 2 '------------------------------------------------------------------------------------------------ ' open USB serial port (COMx); ' ' If the serial monitor in Arduino IDE is open, you will get an "access denied" error. ' Just make sure that the serial monitor is closed (so bytes are not sent by the arduino board). '------------------------------------------------------------------------------------------------ Set fso = CreateObject("Scripting.FileSystemObject") Set com = fso.OpenTextFile("COM6:9600,N,8,1", ForWriting) '--------------------------------------------- ' read content of text file line by line; ' write line to COMx; '--------------------------------------------- Set objFSO = CreateObject("Scripting.FileSystemObject") Set objFile = objFSO.OpenTextFile("C:\arduino\quotes.txt", ForReading) MsgBox("Ready to write file content to COM") Do While objFile.AtEndOfStream <> True '--------------------------------------------------------------------------------------------------------- ' read 10 characters at a time; arduino serial buffer cannot take more than 32 characters; ' writing a character to eeprom takes about 11 ms (assuming that there is no serial.prints in the loop); ' therefore, after each batch of 10 chars sent to COM, we should wait no less than 110 ms; ' we use 200 to have a margin of safety; '--------------------------------------------------------------------------------------------------------- strChars = objFile.Read(10) com.Write(strChars) WScript.Sleep(200) Loop objFile.Close com.Close() MsgBox("Finished writing to COM")Ну саму ошибку можно перевести как "отказ в доступе к ком-порту".
У вас ардуина висит именно на COM6?
Я попробовал выполнить этот vb-скрипт (скет в ардуину не залиливал, просто пустил скипт) - скрипт отработал нормально.
Ошибок не выбил. Но запускал я его имея права администратора.
Направление в которых стоит покопать:
Возможно вы работате под пользователем у которого в настройках секьюрности запрещено VB-скрипту образатся к ком-портам. Попробуйте "стать админом" (если заработает, тогда уже будете искать "конкретно эту настройку").
Можно попробовать работать с ком-порте не через объект файловой системы. Гугл говорит что можно еще юзать Set comPort = CreateObject("MSCommLib.MSComm")
Убедится что ком-порт точно "никто не держит". Перегрузить машину, ArduinoIDE не запускать. Сразу пустить скрипт.
Проверить (и выключить) если есть какой-то сторонний софт работающий с портами "блютуз-менеджеры", какие-нибудь софт для мобилок и т.п. Вещи типа com0com (эмулятор виртуального нуль-модемного кабеля - от точно дается такую ошибку), всякие "виртуальные com-порты и т.п.
Плюнуть и попытатся, вместо VBScript использовать что-то более современное, типа powershell (то что Microsoft продвигает на смену VBScript). Примерно так blogs.msdn.com/b/powershell/archive/2006/08/31/writing-and-reading-info-from-serial-ports.aspx
leshak спасибо Вам огромное , за столь подобные разъяснения . Вообщем-то всё получилось , в EEPROM удалось записать. Правда сказать на моём ноуте это по какой-то причине сделать не получилось , а вот с стационара всё в норме. Ещё раз спасибо Вам !
Правда сказать на моём ноуте это по какой-то причине сделать не получилось , а вот с стационара всё в норме.
Может на ноуте порт другой юзаете? Посмотрите в Device Manager ТОЧНО на каком порту висит ардуина в данный момент. Они иногда "мигрирует по портам" (в другой USB воткнули, номер был кем-то занят и т.п.)
Ну и это опять подводит к вопросу " а не мешает ли какой-то блютус софт встроенный" (на ноутах он чаще бывает). Попробуйте выключить синезуб. Кстати при этом и ArduinoIDE при заходе в меню Tools будет меньше тормозить. Блютус софт часто создает килограмм ком-портов, и она их все, на всякий случай опрашивает.
Сейчас заметил такую особенность Arduino Duemilanove у меня весит на com4 , так вот в неё нормально шьётся , даже на ноуте, а вот UNO весит на COM6 , вот его не видит данный скрипт. Видимо он действительно занят чем-то ещё
Подниму тему. Я использую память 24C256. Проблема в том что в одну ячейку память можно записать только один байт. То есть число до 255. А мне нужно записывать числа до (скажем) 1023. Как мне это сделать! Здесь есть код ПРИМЕР. Я ничего из него понять не могу. Особенно ту часть кода где устанавливается адрес ячейки. Помогите!!!!!
У меня есть идея скрестит два кода
1 сам пример работы с памятью
#include <Wire.h> //I2C library void i2c_eeprom_write_byte( int deviceaddress, unsigned int eeaddress, byte data ) { int rdata = data; Wire.beginTransmission(deviceaddress); Wire.send((int)(eeaddress >> 8)); // MSB Wire.send((int)(eeaddress & 0xFF)); // LSB Wire.send(rdata); Wire.endTransmission(); } // WARNING: address is a page address, 6-bit end will wrap around // also, data can be maximum of about 30 bytes, because the Wire library has a buffer of 32 bytes void i2c_eeprom_write_page( int deviceaddress, unsigned int eeaddresspage, byte* data, byte length ) { Wire.beginTransmission(deviceaddress); Wire.send((int)(eeaddresspage >> 8)); // MSB Wire.send((int)(eeaddresspage & 0xFF)); // LSB byte c; for ( c = 0; c < length; c++) Wire.send(data[c]); Wire.endTransmission(); } byte i2c_eeprom_read_byte( int deviceaddress, unsigned int eeaddress ) { byte rdata = 0xFF; Wire.beginTransmission(deviceaddress); Wire.send((int)(eeaddress >> 8)); // MSB Wire.send((int)(eeaddress & 0xFF)); // LSB Wire.endTransmission(); Wire.requestFrom(deviceaddress,1); if (Wire.available()) rdata = Wire.receive(); return rdata; } // maybe let's not read more than 30 or 32 bytes at a time! void i2c_eeprom_read_buffer( int deviceaddress, unsigned int eeaddress, byte *buffer, int length ) { Wire.beginTransmission(deviceaddress); Wire.send((int)(eeaddress >> 8)); // MSB Wire.send((int)(eeaddress & 0xFF)); // LSB Wire.endTransmission(); Wire.requestFrom(deviceaddress,length); int c = 0; for ( c = 0; c < length; c++ ) if (Wire.available()) buffer[c] = Wire.receive(); } void setup() { char somedata[] = "this is data from the eeprom"; // data to write Wire.begin(); // initialise the connection Serial.begin(9600); i2c_eeprom_write_page(0x50, 0, (byte *)somedata, sizeof(somedata)); // write to EEPROM delay(10); //add a small delay Serial.println("Memory written"); } void loop() { int addr=0; //first address byte b = i2c_eeprom_read_byte(0x50, 0); // access the first address from the memory while (b!=0) { Serial.print((char)b); //print content to serial port addr++; //increase address b = i2c_eeprom_read_byte(0x50, addr); //access an address from the memory } Serial.println(" "); delay(2000); }2 пример работы с памятью мк.
#include <EEPROM.h> //Needed to access the eeprom read write functions //This function will write a 2 byte integer to the eeprom at the specified address and address + 1 void EEPROMWriteInt(int p_address, int p_value) { byte lowByte = ((p_value >> 0) & 0xFF); byte highByte = ((p_value >> 8) & 0xFF); EEPROM.write(p_address, lowByte); EEPROM.write(p_address + 1, highByte); } //This function will read a 2 byte integer from the eeprom at the specified address and address + 1 unsigned int EEPROMReadInt(int p_address) { byte lowByte = EEPROM.read(p_address); byte highByte = EEPROM.read(p_address + 1); return ((lowByte << 0) & 0xFF) + ((highByte << 8) & 0xFF00); } void setup() { Serial.begin(9600); EEPROMWriteInt(0, 0xABCD); Serial.print("Read the following int at the eeprom address 0: "); Serial.println(EEPROMReadInt(0), HEX); } void loop() { }Для выполнения записи "главная" строка эта: 57 i2c_eeprom_write_page(0x50, 0, (byte *)somedata, sizeof(somedata)); // write to EEPROM.
1й аргумент так и оставляем, 2й - наша переменная с инфрмациаей, 3й - "длина" нашей переменной,
можно еще разбить нашу информацию на байты и писать при помощи этого: 05 i2c_eeprom_write_byte( int deviceaddress, unsigned int eeaddress, byte data ), но тут вроде как надо будет сдвигать адрес eeaddress в памяти, куда пишем.
2й пример - это развитие первого, просто он пишет int в два байта, как 1й пример.
С адресами нет ничего сложного, адрес 1й ячейки и адрес 2й = адрес 1 + 1. А вот превращение содержимого 2ух ячеек в int интереснее: return ((lowByte << 0) & 0xFF) + ((highByte << 8) & 0xFF00); Сдвиг превращает байт в инт, а т.к. места в байте меньше, то и храним инт в 2ух байтах, стрший и младшие разряды.
Вот что у меня получилось. Код вроде рабочий. Проверил на нескольких числах (1;243;1234). Всё работает))))
Возможно ли как то оптимизировать код?
#include <Wire.h> //I2C library void i2c_eeprom_write_page(int p_address, int p_value) { byte lowByte = ((p_value >> 0) & 0xFF); byte highByte = ((p_value >> 8) & 0xFF); Wire.beginTransmission(80); Wire.send((int)(p_address >> 8)); // MSB Wire.send((int)(p_address & 0xFF)); // LSB Wire.send(lowByte); Wire.send(highByte); Wire.endTransmission(); } unsigned int i2c_eeprom_read_buffer( int p_address ) { Wire.beginTransmission(80); Wire.send((int)(p_address >> 8)); // MSB Wire.send((int)(p_address & 0xFF)); // LSB Wire.endTransmission(); Wire.requestFrom(80,2); byte lowByte=0; byte highByte=0; if (Wire.available()) lowByte = Wire.receive(); if (Wire.available()) highByte = Wire.receive(); return ((lowByte << 0) & 0xFF) + ((highByte << 8) & 0xFF00); } void setup() { Wire.begin(); Serial.begin(9600); i2c_eeprom_write_page(0,1); delay(10); Serial.println("Memory written"); } void loop() { int b = i2c_eeprom_read_buffer(0); Serial.println(b); delay(2000); }Надо взять на заметку.
А если сравить библиотеки для работы с SD картами и eeprom, какая жирнее? Как я понял, eeprom выигрывает в скорости чтения/записи, а еще в чем сладости?
И еще: у кого, у eeprom или sd ресурс жизни (циклов записи/чтения) меньше?
Хотя, сравнивать библиотеки wire и sd - мувитон...Wire универсальна, с sd не сравнить.
так же озадачился сохранением некоторых данных в EEPROM
но ресурс встроенного где то читал всего 100000
какие варианты будут оптимальнее для хранения десятка байт?
1. внешний EEPROM
2. подключить модуль RTC (часы) и туда сохранять
3. следить за питанием и чуть что сохранять во встроенный EEPROM
4. SD флешка
EEPROM все-таки будет намного проще. Как ни крути - а именно для таких задачь он и предназначен. Смысл вам беречь его ресурс если вы использовать его не собираетесь :) ?
Или вы планируете "ну очень активно его использовать"? К тому же данных-то у вас не так уж и много планируется (насколько я понимаю про шторы речь идет). Вы же не будете ими ездить туда/сюда целыми днями. Посчитайте за сколко времени вы выюзаете ячейку.
К тому же - можно "чередовать их" (раз данных немного). Один день одну, другой - другую... и т.п.
Плюс. Можно не писать при каждом изменении. А повесить конденсатор который даст несколько милесекунд проработать ардуине при отключении питания. Которых хватит запомнить в EEPROM текущие состояние. Тогда ресурс будете расходовать только при "пропало питание". Или батарейку небольшоую присобачить. Именно для "аварийного питания на несколько мгновений".
К тому же - можно "чередовать их" (раз данных немного). Один день одну, другой - другую... и т.п.
Реализовав таким образом маленкую SD-карточку. Которая, по сути своей, та же flash/eeprom/nand/nor...-память, с примерно тем же ограничением по числу циклов записи. Так что пункт 4 у вас избыточный.
Плюс. Можно не писать при каждом изменении. А повесить конденсатор который даст несколько милесекунд проработать ардуине при отключении питания. Которых хватит запомнить в EEPROM текущие состояние. Тогда ресурс будете расходовать только при "пропало питание". Или батарейку небольшоую присобачить. Именно для "аварийного питания на несколько мгновений".
Имя такой батарейке-конденссатору - ионистор.
Достаточно просто конденсатора. Поищите - есть в нете методики слежения за питанием. В контроллере, если мне не изменяет память, есть специальное прерывание для этого. Но придется существенно выйти за рамки IDE и писать на с.
Спасибо за комментарии, ближе к делу, как детельки получу, отпишусь о результатах :)
В контроллере, если мне не изменяет память, есть специальное прерывание для этого.
К сожалению, ни в табличке для ATMega328, ни в сводной (для всего семейства AVR) такой вектор не обнаруживается.
Если только аналоговым компаратором (ANALOG_COMP_vect) пожертвовать для этой цели... Но тогда необходимо иметь эталонное напряжение отключения.
пожалуй можно сделать небольшую схемку которая будет дергать за вывод на прерывании и так оптимизировать слежение за питанием
но с учетом, что питание не от батареи его можно не экономить и постоянно измерять в цикле - хотя это не красиво получится )
Да. Перепутал с другим контроллером. В общем случае, нужно контроллировать питание до стабилизатора, или, как вариант, запитать контроллер через диод с конденсатором. Вот здесь обсуждалось:
Как записать в EEPROM перед отключением питания (ветка на Радиокоте)
вопрос снят... была ошибка.