Чтение и запись в EEPROM

Мне нужно реализовать функцию чтения и записи EEPROM в моем проекте.
Последние несколько дней я учусь использовать EEPROM, однако мне трудно читать и записывать строки в EEPROM.

Отладка полученных данных:

  • Полученные данные: Полученные данные верны.
  • Данные EEPROM: Кажется, у него есть данные, но я получаю мусорные символы.

Прочитав несколько ответов, я, кажется, не понимаю причины своей неудачи.
Конечно, я мог бы "Скопировать / вставить", возможно, заставить его работать и не понимать клонированный код, но я бы ничему не научился из этого.
Поэтому публикую еще одну тему по этому вопросу (не совсем дублирующую) с просьбой о помощи и/или руководстве; ради понимания и решения моей проблемы.

Код

int ADDR_USERNAME       = 2;           // Адрес длины данных имени пользователя в EEPROM.

/* Get Username from EEPROM */
String EE_ReadUsername()
{
  int dataLength  = EEPROM.read(ADDR_USERNAME);       //Получить длину данных из позиции адреса EEPROM.
  int dataAddress = ADDR_USERNAME + 1; // Начальный адрес данных в EEPROM

  char data[dataLength]; // Назначение длины массива

  for (int i = 0; i < dataLength; i++)                // Извлекать данные (Char by Char) путем итерации по позициям адресов EEPROM.
  {
    char c = EEPROM.read(dataAddress + i);            // Добавить адрес EEPROM Char в массив
  }

  // DEBUG START
  Serial.print("VALUE: ");
  Serial.println(String(data));
  // DEBUG END

  return String(data);                                // Возвращает данные.
}

/* Сохранить имя пользователя в EEPROM */
void EE_WriteUsername(String str)
{
  byte len = str.length();                            // Получить длину строки.
  int dataAddress = ADDR_USERNAME + 1;                // Установить исходный адрес данных

  EEPROM.update(ADDR_USERNAME, len); // Сохраните длину строки в EEPROM

  for (int i = 0; i < len; i++)                       // Перебираем каждый символ в строке.
  { 
    EEPROM.update(dataAddress + i, str[i]);           // Назначьте каждый символ из полученной строки адресной позиции в EEPROM.
  }
}

Заранее спасибо.

, 👍2


2 ответа


Лучший ответ:

1

В EE_ReadUsername ()вы написали:

char c = EEPROM.read(dataAddress + i);

Эта переменная (c) установлена, но никогда не используется. Возможно, вы захотите добавить этот символ в массив символов данных.

Кроме того, массив должен завершаться нулевым байтом.

,

1

Придавая этой теме еще большую ценность, принимая во внимание помощь @Edgar Bonet (принятый ответ для этой темы); Я отвечаю на свой собственный вопрос с помощью моего полного кода класса заголовка (больше функций EEPROM) для дальнейшего использования для себя и других пользователей, которые могут учиться.


Примечание(ы):

  1. Регионы существуют для целей резервного копирования.
  2. Не стесняйтесь редактировать и улучшать ответ, а также улучшать комментарии с помощью расширенной и информативной информации.
  3. Нулевой завершающий символ НЕ добавляется в EEPROM. Нулевой завершающий символ '\n' или '\0' добавляется в массив только при чтении. Это предотвращает запись (ненужных) адресов в EEPROM.

Код

#pragma region <Includes>
#include <EEPROM.h>
#pragma endregion


#pragma region <Configuration>

#define ADDR_BRIGHTNESS   0           // LCD Brightness Data Address on EEPROM.
#define ADDR_CONTRAST     1           // LCD Contrast Data Address on EEPROM. [NOT IMPLEMENTED]
#define ADDR_USERNAME     2           // Username Data Lenght Address on EEPROM.
#define ADDR_COMPUTERNAME 14          // Computer Data Length Initial Address on EEPROM.

#pragma endregion

#pragma region <CRC>
unsigned long EEPROM_CRC(void)
{
  const unsigned long crc_table[16] = 
  {
    0x00000000, 0x1db71064, 0x3b6e20c8, 0x26d930ac,
    0x76dc4190, 0x6b6b51f4, 0x4db26158, 0x5005713c,
    0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c,
    0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c
  };

  unsigned long crc = ~0L;

  for (int index = 0 ; index < EEPROM.length()  ; ++index)
  {
    crc = crc_table[(crc ^ EEPROM[index]) & 0x0f] ^ (crc >> 4);
    crc = crc_table[(crc ^ (EEPROM[index] >> 4)) & 0x0f] ^ (crc >> 4);
    crc = ~crc;
  }

  return crc;
}

/* Performs a Cyclic Redundancy Check and Prints a Report on Serial Monitor */
void EE_CRC()
{
  Serial.println(" *** Performing EEPROM Cyclic Redundancy Check...");
  Serial.print(" *** EEPROM Length: ");                                // Print Length of Data to run CRC on.
  Serial.println(EEPROM.length());

  Serial.print(" *** EEPROM CRC32 Data: 0x");                          // Print the Result of Calling EEPROM_CRC()
  Serial.println(EEPROM_CRC(), HEX);
}
#pragma endregion

/* Iterate Through Each byte of the EEPROM Storage and Set all of the bytes to 0. */
void EE_ERASE()
{
  Serial.println(" *** ERASING EEPROM MEMORY...");
  
  for (int i = 0; i < EEPROM.length(); i++) 
  { EEPROM.write(i, 0); }

  Serial.println(" *** EEPROM ERASED!");
}


#pragma region <User Name>
/* Get Username from EEPROM */
String EE_ReadUsername()
{
  int dataLength  = EEPROM.read(ADDR_USERNAME);         // Get the Data Length from EEPROM Address Position.
  int dataAddress = ADDR_USERNAME + 1;                  // Data Initial Address on EEPROM

  char data[dataLength +1];                             // Assign the Array Length (+1 to Add the Null Terminating Char).

  for (int i = 0; i < dataLength; i++)                  // Retrieve Data (Char by Char) by Iterating over EEPROM Address Positions.
  {
    data[i] = EEPROM.read(dataAddress + i);             // Add EEPROM Address Char to Array
  }

  data[dataLength] = '\0';                              // Terminate the char String (Add Null Terminating Char)

  return String(data);                                  // Return the Data.
}

/* Save Username to EEPROM */
void EE_WriteUsername(String str)
{
  byte len = str.length();                              // Get the String Length.
  int dataAddress = ADDR_USERNAME + 1;                  // Set the Initial Data Address

  EEPROM.update(ADDR_USERNAME, len);                    // Store the String Length to EEPROM

  for (int i = 0; i < len; i++)                         // Iterate over each char in String.
  { 
    EEPROM.update(dataAddress + i, str[i]);             // Assign each char from Received String to an Address Position in EEPROM.
  }
}
#pragma endregion


#pragma region <Computer Name>
/* Get Computer Name from EEPROM */
String EE_ReadComputername()
{
  int dataLength  = EEPROM.read(ADDR_COMPUTERNAME);     // Get the Data Length from EEPROM Address Position.
  int dataAddress = ADDR_COMPUTERNAME + 1;              // Data Initial Address on EEPROM

  char data[dataLength +1];                             // Assign the Array Length (+1 to Add the Null Terminating Char).

  for (int i = 0; i < dataLength; i++)                  // Retrieve Data (Char by Char) by Iterating over EEPROM Address Positions.
  {
    data[i] = EEPROM.read(dataAddress + i);             // Add EEPROM Address Char to Array
  }

  data[dataLength] = '\0';                              // Terminate the char String (Add Null Terminating Char)

  return String(data);                                  // Return the Data.
}

/* Save Computer Name to EEPROM */
void EE_WriteComputername(String str)
{
  byte len = str.length();                              // Get the String Length.
  int dataAddress = ADDR_COMPUTERNAME + 1;              // Set the Initial Data Address

  EEPROM.update(ADDR_COMPUTERNAME, len);                // Store the String Length to EEPROM
  
  for (int i = 0 ; i < len; i++)                        // Iterate over each char in String.
  {
    EEPROM.update(dataAddress + i, str[i]);             // Assign each char from Received String to an Address Position in EEPROM.
  }
}
#pragma endregion


#pragma region <Brightness>
int EE_ReadBrightness()
{
  return EEPROM.read(ADDR_BRIGHTNESS);
}

void EE_WriteBrightness(int val)
{  
  EEPROM.update(ADDR_BRIGHTNESS, val);
}
#pragma endregion
,