Greetings,
I have to write specific variables to an i2C EEPROM and i am only getting the last 'half' of my string written to the EEPROM.
This is what i need to write: [FzgParam] Fahrzeugadresse=123456 MontageplattenNr=9 Dummy=1
This is what my code is actually writing: 6 MontageplattenNr=9 Dummy=1
I cannot understand why I am only getting half written considering that the string is always written to the first memory location 0x00 in the EEPROM.
#include <Wire.h>
void setup() {
Wire.begin(); // Initialize I2C bus
Serial.begin(9600); // Initialize Serial communication (for debugging)
delay(1000); // Wait for devices to stabilize
// Check if the device is detected
if (isDeviceDetected(0x50)) {
Serial.println("EEPROM detected at address 0x50");
} else {
Serial.println("EEPROM not detected at address 0x50. Please check connections.");
delay(2000);
}
}
void loop() {
// Check if the device is detected
if (isDeviceDetected(0x50)) {
Serial.println("EEPROM detected at address 0x50");
} else {
Serial.println("EEPROM not detected at address 0x50. Please check connections.");
delay(2000);
}
//strings to be joined
String string1 = "[FzgParam]"; // length 10
String string2 = "Fahrzeugadresse="; // length 16
int number1 = 123456; // Variable digit length 6
String string4 = "MontageplattenNr="; //length 17
int number2 = 9; // Variable digit length 1
String string6 = "Dummy=1"; //length 7
// 10+16+6+17+1+7=57
//
// convert numbers into strings
String string3 = String(number1);
String string5 = String(number2);
// join all strings together with line feed
String message = string1 + "\n" + string2 + string3 + "\n" + string4 + string5 + "\n" + string6;
// Calculate the length of the string (including null terminator)
int messageLength = message.length() + 1;
Serial.print("messageLength=");
Serial.println(messageLength);
// Reserve memory for the string and additional bytes
byte buffer[messageLength]; //byte buffer[messageLength + 2];
// Copy the characters of the string into the buffer
message.getBytes(buffer, messageLength);
// Write the string data to the EEPROM starting at memory location 0x00
writeToEEPROM(0x50, 0x00, buffer, messageLength);
// Write additional bytes 0xAA and 0xFF to the next two memory locations
//writeToEEPROM(0x50, 0x0C, (byte)0xAA);
//writeToEEPROM(0x50, 0x0D, (byte)0xFF);
// Print the message to Serial for verification
Serial.println("Data written to EEPROM: " + message);
//TESTING ONLY: Wait for 5 seconds before writing again
delay(5000);
}
void writeToEEPROM(int deviceAddress, int memoryAddress, byte* data, int length) {
Wire.beginTransmission(deviceAddress); // Start communication with EEPROM
Wire.write((int)(memoryAddress >> 8)); // Send upper memory address byte
Wire.write((int)(memoryAddress & 0xFF)); // Send lower memory address byte
Wire.write(data, length); // Send data to be written
Wire.endTransmission(); // End transmission
delay(10); // Wait for the EEPROM to complete the write operation
}
void writeToEEPROM(int deviceAddress, int memoryAddress, byte data) {
Wire.beginTransmission(deviceAddress); // Start communication with EEPROM
Wire.write((int)(memoryAddress >> 8)); // Send upper memory address byte
Wire.write((int)(memoryAddress & 0xFF)); // Send lower memory address byte
Wire.write(data); // Send data to be written
Wire.endTransmission(); // End transmission
delay(10); // Wait for the EEPROM to complete the write operation
}
bool isDeviceDetected(int deviceAddress) {
Wire.beginTransmission(deviceAddress); // Start communication with the specified address
byte error = Wire.endTransmission(); // Check if the device responds
return (error == 0); // Return true if no error occurred, indicating device detection
}
Any help to understand and solve my issue would be great please.
On this forum we sometimes say that the problem is in the part that someone is not showing. How do you know that things are not written ? There is no code to read the data
Is the data to the Serial Monitor showing the right data ?
Which Arduino board are you using ?
You say that you need to write " Fahrzeugadresse=321456", but then in the code you use the number "123456" That is confusing, when writing code and avoiding bugs, it is important to be clear and correct
This is a bug: int number1 = 123456;
Such a bug number does not fit in a 16-bit integer.
How do you make a new line in the EEPROM ? When writing text to a file, there is often a Carriage Return and Line Feed at the end of each line (or just a Carriage Return or just a Line Feed).
You are building the text with "String" and then write everything to EEPROM. I would avoid the "String" and write each small piece of the text directly to EEPROM.
Thank you for a nice text layout I can just let my eyes go over the code to spot the problems.
Hi, thanks for the help.
I have an external tool that reads the EEPROM so that's how I know the write is incomplete.
I am using an ESP32 dev board.
You are correct and sorry for the confusion, I have changed the number so many times looking for patterns I forgot to match what I copied to my code. the only requirement for the variable is that it is limited to 6 digits only. I will change to a long.
i think my specific device needs a \n for a line feed and a 0xAA and 0xFF as an end of file terminator but i am guessing as there is no documentation. but that said the third party device that is reading the EEPROM doesn't seem to mind the current format except for the fact that it misses the first half of the string lol.
Hi Koepel,
I have just changed the code to use long data type instead of int and there is no difference to the output. I am also trying to understand how you would "write each piece of the text directly to the EEPROM" as you suggest. Can you give me an example?
#include <Wire.h>
void setup() {
Wire.begin(); // Initialize I2C bus
Serial.begin(9600); // Initialize Serial communication (for debugging)
delay(1000); // Wait for devices to stabilize
// Check if the device is detected
if (isDeviceDetected(0x50)) {
Serial.println("EEPROM detected at address 0x50");
} else {
Serial.println("EEPROM not detected at address 0x50. Please check connections.");
while (true) {} // Hang the program if the device is not detected
}
}
void loop() {
// Check if the device is detected
if (isDeviceDetected(0x50)) {
Serial.println("EEPROM detected at address 0x50");
} else {
Serial.println("EEPROM not detected at address 0x50. Please check connections.");
delay(2000);
}
//strings to be joined
String string1 = "[FzgParam]"; // length 10
String string2 = "Fahrzeugadresse="; // length 16
long number1 = 123456; // Variable digit length 6
String string4 = "MontageplattenNr="; //length 17
int number2 = 1; // Variable digit length 1
String string6 = "Dummy=1"; //length 7
// 10+16+6+17+1+7=57
//
// convert numbers into strings
String string3 = String(number1);
String string5 = String(number2);
// join all strings together with line feed
String message = string1 + "\n" + string2 + string3 + "\n" + string4 + string5 + "\n" + string6;
// Calculate the length of the string (including null terminator)
int messageLength = message.length() + 1;
Serial.print("messageLength=");
Serial.println(messageLength);
// Reserve memory for the string and additional bytes
byte buffer[messageLength]; //byte buffer[messageLength + 2];
// Copy the characters of the string into the buffer
message.getBytes(buffer, messageLength);
// Write the string data to the EEPROM starting at memory location 0x00
writeToEEPROM(0x50, 0x00, buffer, messageLength);
// Write additional bytes 0xAA and 0xFF to the next two memory locations
//writeToEEPROM(0x50, 0x0C, (byte)0xAA);
//writeToEEPROM(0x50, 0x0D, (byte)0xFF);
// Print the message to Serial for verification
Serial.println("Data written to EEPROM: " + message);
//TESTING ONLY Wait for 5 seconds before writing again
delay(5000);
}
void writeToEEPROM(int deviceAddress, int memoryAddress, byte* data, int length) {
Wire.beginTransmission(deviceAddress); // Start communication with EEPROM
Wire.write((int)(memoryAddress >> 8)); // Send upper memory address byte
Wire.write((int)(memoryAddress & 0xFF)); // Send lower memory address byte
Wire.write(data, length); // Send data to be written
Wire.endTransmission(); // End transmission
delay(10); // Wait for the EEPROM to complete the write operation
}
void writeToEEPROM(int deviceAddress, int memoryAddress, byte data) {
Wire.beginTransmission(deviceAddress); // Start communication with EEPROM
Wire.write((int)(memoryAddress >> 8)); // Send upper memory address byte
Wire.write((int)(memoryAddress & 0xFF)); // Send lower memory address byte
Wire.write(data); // Send data to be written
Wire.endTransmission(); // End transmission
delay(10); // Wait for the EEPROM to complete the write operation
}
bool isDeviceDetected(int deviceAddress) {
Wire.beginTransmission(deviceAddress); // Start communication with the specified address
byte error = Wire.endTransmission(); // Check if the device responds
return (error == 0); // Return true if no error occurred, indicating device detection
}
I am reading now but I am afraid its at the limit of my understanding and I am missing the point. I thought I was only working within the first bytes of the first page.
I just found out that you included the write functions. You missed to handle page boundaries, so that multi-byte writes wrap around on each 32 bytes page boundary.
This makes writing of a long data area, as you do, will effectively write only the last 32 bytes.
Greetings all,
I have been experimenting and indeed my issue is that I am only writing to the first page of EEPROM if I write 32 bytes (16 ascii characters ) the result is as expected. If I go over the 32byte buffer indeed the first bytes are overwritten as everyone suggests.
The issue now is that i don't understand how to write to the second page?
I thought I should be able to build a second and third string and send it to the address of the next page(s).
Seems that I am so close and should be able to build and send a second string to 0x16 (00000010) which I believe to be the address of the first byte of second page on the 24FC64?
this code doesn't work... lol
I am being a little stubborn to use another library because i don't understand the examples at all and I feel I am really close here...
#include <Wire.h>
void setup() {
Wire.begin(); // Initialize I2C bus
Serial.begin(9600); // Initialize Serial communication (for debugging)
delay(1000); // Wait for devices to stabilize
}
void loop() {
// Check if the device is detected
if (isDeviceDetected(0x50)) {
Serial.println("EEPROM detected at address 0x50");
} else {
Serial.println("EEPROM not detected at address 0x50. Please check connections.");
delay(2000);
}
//strings to be joined
String string1 = "[FzgParam]"; // length 10
String string2 = "Fahrzeugadresse="; // length 16
long number1 = 123; // Variable digit length 6
String string4 = "Montageplatten="; //length 17
int number2 = 1; // Variable digit length 1
String string6 = "Dummy=1"; //length 7
// 10+16+6+17+1+7=57
//
// convert numbers into strings
String string3 = String(number1);
String string5 = String(number2);
// join all strings together with line feed
String message = string1 + "\n" + string2+ string3 + "\n"; //
String message2 =string4 + "\n";
// Calculate the length of the string (including null terminator)
int messageLength = message.length() + 1;
Serial.print("messageLength=");
Serial.println(messageLength);
int messageLength2 = message2.length() + 1;
Serial.print("messageLength2=");
Serial.println(messageLength2);
// Reserve memory for the string and additional bytes
byte buffer[messageLength]; //byte buffer[messageLength + 2];
byte buffer2[messageLength2]; //byte buffer[messageLength + 2];
// Copy the characters of the string into the buffer
message.getBytes(buffer, messageLength);
message.getBytes(buffer2, messageLength2);
// Write the string data to the EEPROM starting at memory location 0x00
writeToEEPROM(0x50, 0x00, buffer, messageLength);
writeToEEPROM(0x50, 0x16, buffer2, messageLength2);
// Write additional bytes 0xAA and 0xFF to the next two memory locations
//writeToEEPROM(0x50, 0x0C, (byte)0xAA);
//writeToEEPROM(0x50, 0x0D, (byte)0xFF);
// Print the message to Serial for verification
Serial.println("Data written to EEPROM: " + message);
//TESTING ONLY Wait for 5 seconds before writing again
delay(5000);
}
void writeToEEPROM(int deviceAddress, int memoryAddress, byte* data, int length) {
Wire.beginTransmission(deviceAddress); // Start communication with EEPROM
Wire.write((int)(memoryAddress >> 8)); // Send upper memory address byte
Wire.write((int)(memoryAddress & 0xFF)); // Send lower memory address byte
Wire.write(data, length); // Send data to be written
Wire.endTransmission(); // End transmission
delay(10); // Wait for the EEPROM to complete the write operation
}
bool isDeviceDetected(int deviceAddress) {
Wire.beginTransmission(deviceAddress); // Start communication with the specified address
byte error = Wire.endTransmission(); // Check if the device responds
return (error == 0); // Return true if no error occurred, indicating device detection
}
The second 32 byte page starts at 0x20. The page number can be obtained from addr & 0x1E00 and page offset from addr & 0x1FF. See the 6.2 Page Write section in the data sheet.
In writeToEEPROM() you have to check for crossing a page boundary. Then split the output into the first page and as many page writes as required into further pages.
Thanks Dr,
I am reading the data sheet but didn't fully understand what it meant. I am afraid I still don't understand how to implement what you said but I am chewing it over now...
I have tried to improve the function but Im at my programming limits.
This is what I have currently for the writeToEEPROM function but it doesn't work...
void writeToEEPROM(int deviceAddress, int memoryAddress, byte* data, int length) {
int pageSize = 32; // Define the page size of the EEPROM
int currentPageAddress = memoryAddress; // Store the current page address
for (int i = 0; i < length; i += pageSize) {
int remainingLength = length - i;
int writeLength = min(remainingLength, pageSize); // Calculate the length of data to write within the current page
// Calculate the current page and page offset
int currentPage = currentPageAddress & 0x1E00;
int pageOffset = currentPageAddress & 0x1FF;
Serial.print("page: ");
Serial.println(currentPage);
Serial.print("offset: ");
Serial.println(pageOffset);
// Check if the write crosses a page boundary
if ((pageOffset + writeLength) > pageSize) {
writeLength = pageSize - pageOffset; // Adjust the write length to stay within the current page
}
Wire.beginTransmission(deviceAddress); // Start communication with EEPROM
Wire.write((int)(currentPage >> 8)); // Send upper memory address byte
Wire.write((int)(currentPage & 0xFF) | pageOffset); // Send lower memory address byte with page offset
Wire.write(data + i, writeLength); // Send data to be written
Wire.endTransmission(); // End transmission
delay(10); // Wait for the EEPROM to complete the write operation
currentPageAddress += writeLength; // Update the current page address
}
}
yes thanks, its definitely my code and not the devices.
I have a third party tool and application that work perfectly. this is how I verify my code is not working because the third party software does not read it correctly. if I write with the third party software I get what I expect.
the issue is that i need a laptop to run the third party software and I am trying to minimise everything to a calculator sized tool with 4x4 keypad and OLED display.
my prototype tool only needs to save the following to an EEPROM chip
with the variable Fahrzeugadresse 6 digits being the only thing that changes with keypad entry.