запись во внешнею EEPROM

rjbinaa
Offline
Зарегистрирован: 26.04.2011

КАК записать данные во внешний 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")

 

leshak
Offline
Зарегистрирован: 29.09.2011

 Ну , во первых  если бы вставили нормально, без мусорной нумерации строк легче было-бы читать.

Во вторых, по вашей сылке этого сприпта нет. Так что брали вы его "откуда-то еще" (скорее всего из более ранних статей).

В третьих. Это именно скрипт, а не скетч. Судя по всяму на VBScript. Так что нигде кроме на на большом комьютере вы его запустите. Да и то - только под виндой.

К "ардуине" он имеет очень далекое отношение. Фактически вообще никакого. ОН просто берет файл quotes.txt и малыми порциями отправляет его в com-порт.

Если на этом порте будет висеть ардуина (или что-то другое), и будет что-то делать с принимаемыми данными, и что будет делать - скрипт совершенно не знает.

А вот в ссылке что вы дали (кстати ссылки лучше вставлять как ссылки), похоже и есть ардуино-скетч, который "слушает" на другом конце провода. Принимает эти данные и сохраняет в  EEPROM

rjbinaa
Offline
Зарегистрирован: 26.04.2011

timewitharduino.blogspot.com/2009/05/getting-arduino-to-write-to-or-read.html  вот правильная ссылка 

 

 

leshak
Offline
Зарегистрирован: 29.09.2011

 Ну, так а в чем вопрос-то?

По этой ссылке видим два VB скрипта. Один умеет принимать данные из ком-порта (арудины) и записывать их в файл, второй  - наоборот. Брать данные из файла и запихивать их в ком-порт.

Оба предназначены для запуска НА КОМПЬЮТЕРЕ, причем только под windows. Не на ардуино. ArduinoIDE, естественно, на попытку их компиляции будет кричать как беременный лось в теплую погоду. Потому что и "язык не тот" и "платформа не та".

Для записи с в EEROOM вам нужно смотреть, все-таки, на ссылку из вашего первого поста. Там есть скетч (то есть то, что запускается на ардуине), который принимает данный из ком-порта и сохраняет их в EEROOM.

rjbinaa
Offline
Зарегистрирован: 26.04.2011

 спасибо , буду дома попробую

rjbinaa
Offline
Зарегистрирован: 26.04.2011

 Вот , что есть:

Однако при запуске скрипта выходит ошибка , хотя порт указан верно и отключен serial mnonitor, в чём может быть проблема непонятно ?

s002.radikal.ru/i197/1203/1a/746018d60111.jpg

rjbinaa
Offline
Зарегистрирован: 26.04.2011

Вот скетч , который прописан в 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")

leshak
Offline
Зарегистрирован: 29.09.2011

 Ну саму ошибку можно перевести как "отказ в доступе к ком-порту".

У вас ардуина висит именно на 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

rjbinaa
Offline
Зарегистрирован: 26.04.2011

 leshak спасибо Вам огромное , за столь подобные разъяснения . Вообщем-то всё получилось , в EEPROM удалось записать. Правда сказать на моём ноуте это по какой-то причине сделать не получилось , а вот с стационара всё в норме. Ещё раз спасибо Вам !

leshak
Offline
Зарегистрирован: 29.09.2011

rjbinaa пишет:

 Правда сказать на моём ноуте это по какой-то причине сделать не получилось , а вот с стационара всё в норме. 

Может на ноуте порт другой юзаете? Посмотрите в Device Manager ТОЧНО на каком порту висит ардуина в данный момент. Они иногда "мигрирует по портам" (в другой USB воткнули, номер был кем-то занят и т.п.)

Ну и это опять подводит к вопросу " а не мешает ли какой-то блютус софт встроенный" (на ноутах он чаще бывает). Попробуйте выключить синезуб. Кстати при этом и ArduinoIDE при заходе в меню Tools будет меньше тормозить. Блютус софт часто создает килограмм ком-портов, и она их все, на всякий случай опрашивает.

rjbinaa
Offline
Зарегистрирован: 26.04.2011

 Сейчас заметил такую особенность Arduino Duemilanove у меня весит на com4 , так вот в неё нормально шьётся , даже на ноуте, а вот UNO весит на COM6 , вот его не видит данный скрипт. Видимо он действительно занят чем-то ещё

LEVV2006
LEVV2006 аватар
Offline
Зарегистрирован: 15.04.2011

Подниму тему. Я использую память 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()
{
}

 

.c8r
.c8r аватар
Offline
Зарегистрирован: 15.11.2011

Для выполнения записи "главная" строка эта: 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й пример.

.c8r
.c8r аватар
Offline
Зарегистрирован: 15.11.2011

С адресами нет ничего сложного, адрес 1й ячейки и адрес 2й = адрес 1 + 1. А вот превращение содержимого 2ух ячеек в int интереснее: return ((lowByte << 0) & 0xFF) + ((highByte << 8) & 0xFF00); Сдвиг превращает байт в инт, а т.к. места в байте меньше, то и храним инт в 2ух байтах, стрший и младшие разряды.

LEVV2006
LEVV2006 аватар
Offline
Зарегистрирован: 15.04.2011

Вот что у меня получилось. Код вроде рабочий. Проверил на нескольких числах (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);

}

 

.c8r
.c8r аватар
Offline
Зарегистрирован: 15.11.2011

Надо взять на заметку.

А если сравить библиотеки для работы с SD картами и eeprom, какая жирнее? Как я понял, eeprom выигрывает в скорости чтения/записи, а еще в чем сладости?

И еще: у кого, у eeprom или sd ресурс жизни (циклов записи/чтения) меньше?

.c8r
.c8r аватар
Offline
Зарегистрирован: 15.11.2011

Хотя, сравнивать библиотеки wire и sd - мувитон...Wire универсальна, с sd не сравнить.

IceHardy
Offline
Зарегистрирован: 01.10.2012

 так же озадачился сохранением некоторых данных в EEPROM

но ресурс встроенного где то читал всего 100000

какие варианты будут оптимальнее для хранения десятка байт?

1. внешний EEPROM

2. подключить модуль RTC (часы) и туда сохранять

3. следить за питанием и чуть что сохранять во встроенный EEPROM

4. SD флешка

leshak
Offline
Зарегистрирован: 29.09.2011

 EEPROM все-таки будет намного проще. Как ни крути - а именно для таких задачь он и предназначен. Смысл вам беречь его ресурс если вы использовать его не собираетесь :) ?

Или вы планируете "ну очень активно его использовать"? К тому же данных-то у вас не так уж и много планируется (насколько я понимаю про шторы речь идет). Вы же не будете ими ездить туда/сюда целыми днями. Посчитайте за сколко времени вы выюзаете ячейку.

К тому же - можно "чередовать их" (раз данных немного). Один день одну, другой - другую... и т.п.

Плюс. Можно не писать при каждом изменении. А повесить конденсатор который даст несколько милесекунд проработать ардуине при отключении питания. Которых хватит запомнить в EEPROM текущие состояние. Тогда ресурс будете расходовать только при "пропало питание". Или батарейку небольшоую присобачить. Именно для "аварийного питания на несколько мгновений".

step962
Offline
Зарегистрирован: 23.05.2011

leshak пишет:

К тому же - можно "чередовать их" (раз данных немного). Один день одну, другой - другую... и т.п.

Реализовав таким образом маленкую SD-карточку. Которая, по сути своей, та же flash/eeprom/nand/nor...-память, с примерно тем же ограничением по числу циклов записи. Так что пункт 4 у вас избыточный.

Цитата:

Плюс. Можно не писать при каждом изменении. А повесить конденсатор который даст несколько милесекунд проработать ардуине при отключении питания. Которых хватит запомнить в EEPROM текущие состояние. Тогда ресурс будете расходовать только при "пропало питание". Или батарейку небольшоую присобачить. Именно для "аварийного питания на несколько мгновений".

Имя такой батарейке-конденссатору - ионистор.

AlexFisher
AlexFisher аватар
Offline
Зарегистрирован: 20.12.2011

Достаточно просто конденсатора. Поищите - есть в нете методики слежения за питанием. В контроллере, если мне не изменяет память, есть специальное прерывание для этого. Но придется существенно выйти за рамки IDE и писать на с.

IceHardy
Offline
Зарегистрирован: 01.10.2012

Спасибо за комментарии, ближе к делу, как детельки получу, отпишусь о результатах :)

step962
Offline
Зарегистрирован: 23.05.2011

AlexFisher пишет:

В контроллере, если мне не изменяет память, есть специальное прерывание для этого.

К сожалению, ни в табличке для ATMega328, ни в сводной (для всего семейства AVR) такой вектор не обнаруживается.

Если только аналоговым компаратором (ANALOG_COMP_vect) пожертвовать для этой цели... Но тогда необходимо иметь эталонное напряжение отключения.

IceHardy
Offline
Зарегистрирован: 01.10.2012

пожалуй можно сделать небольшую схемку которая будет дергать за вывод на прерывании и так оптимизировать слежение за питанием

но с учетом, что питание не от батареи его можно не экономить и постоянно измерять в цикле - хотя это не красиво получится )

AlexFisher
AlexFisher аватар
Offline
Зарегистрирован: 20.12.2011

Да. Перепутал с другим контроллером. В общем случае, нужно контроллировать питание до стабилизатора, или, как вариант, запитать контроллер через диод с конденсатором. Вот здесь обсуждалось:

Как записать в EEPROM перед отключением питания (ветка на Радиокоте) 

sav liana
Offline
Зарегистрирован: 28.11.2016

вопрос снят... была ошибка.