Чтение и запись в 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 ответа
Лучший ответ:
В EE_ReadUsername ()
вы написали:
char c = EEPROM.read(dataAddress + i);
Эта переменная (c
) установлена, но никогда не используется. Возможно, вы захотите добавить этот
символ в массив символов данных.
Кроме того, массив должен завершаться нулевым байтом.
Придавая этой теме еще большую ценность, принимая во внимание помощь @Edgar Bonet (принятый ответ для этой темы); Я отвечаю на свой собственный вопрос с помощью моего полного кода класса заголовка (больше функций EEPROM) для дальнейшего использования для себя и других пользователей, которые могут учиться.
Примечание(ы):
- Регионы существуют для целей резервного копирования.
- Не стесняйтесь редактировать и улучшать ответ, а также улучшать комментарии с помощью расширенной и информативной информации.
- Нулевой завершающий символ НЕ добавляется в 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
- Еще один простой и глупый вопрос о строках C++
- Занимают ли комментарии место в скомпилированном скетче C++? Ардуино / узел микроконтроллера
- deserializeJson() не удалось: NoMemory при отправке последовательного json с использованием ArduinoJson
- C++ против языка Arduino?
- avrdude ser_open() can't set com-state
- Как читать и записывать EEPROM в ESP8266
- ошибка: ожидаемое первичное выражение перед токеном ','
- Ввести идентификатор чипа ESP32 в строковую переменную (новичок в Arduino/C++)