Finally, I also spent a great deal of time writing code to allow my arduino to write to these DS2431 devices. I use the OneWire library available here: GitHub - PaulStoffregen/OneWire: Library for Dallas/Maxim 1-Wire Chips
This code will write the 128 bytes in the four 32 byte pages defined at the top. It then idles in the main loop() to prevent wearing out the re-write cycles of the memory. For reasons I don't understand, the CRC sent immediately after writing the scratchpad is correct, but the CRC sent after reading the scratchpad data is random garbage. So my program uses the first CRC, but still does a scratchpad read and prints it to the serial monitor for troubleshooting and manual data verification by visual inspection.
#include <OneWire.h>
const int EEPROM_pin = 3; // Correct pin
uint16_t last_crc = 0; //Initialize variable
// Data to be written to the EEPROM
byte page1[32] = {0x02, 0x00, 0x04, 0x1D, 0xFE, 0x39, 0x00, 0xF0, 0xA4, 0x06, 0x64, 0x00, 0x64, 0x00, 0xDC, 0x05, 0xEE, 0x02, 0xDC, 0x05, 0xEE, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7D, 0x00, 0xC1, 0x94};
byte page2[32] = {0x98, 0x9F, 0x64, 0x64, 0x64, 0x00, 0x00, 0x00, 0x01, 0x70, 0x17, 0x70, 0x17, 0x20, 0x05, 0x6E, 0x7D, 0x00, 0x01, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x33, 0x33, 0x2D, 0x31, 0x33, 0x36};
byte page3[32] = {0x2D, 0x34, 0x33, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
byte page4[32] = {0x3C, 0xB2, 0x01, 0x32, 0x32, 0x72, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x34, 0x01, 0x16, 0x00, 0x92, 0x2F, 0xA5};
void printAddress(uint8_t *address) {
for (uint8_t i = 0; i < 8; i++) {
if (address[i] < 16) Serial.print("0");
Serial.print(address[i], HEX);
Serial.print(" ");
}
}
void writePage(OneWire &myWire, uint8_t *addr, uint8_t page, byte *data) {
Serial.println("Write Page Called");
uint16_t last_crc = 0; //Initialize variable
byte TA1 = page * 8;
byte TA2 = 0;
byte ES;
byte crc_read[2];
byte crcInput[11];
crcInput[0] = 0x0F;
crcInput[1] = TA1;
crcInput[2] = TA2;
myWire.reset();
// Serial.println("reset pulse sent 1");
myWire.select(addr);
myWire.write(0x0F); // Write Scratchpad
myWire.write(TA1); // Target address LSB
//Serial.print("TA1 last 3 bits must be 0: ");
//Serial.println(TA1, BIN);
myWire.write(TA2); // Target address MSB
Serial.print("Writing data: ");
for (int i = 0; i < 8; i++) {
myWire.write(data[i]); // Write data to scratchpad
crcInput[3 + i] = data[i]; //copy the same data to crcinput
Serial.print(data[i], HEX); //Print the output data
Serial.print(" ");
}
Serial.println();
Serial.println("inverted CRC Data Read from chip after write");
byte readDataChipCRC[2];
for (int i = 0; i < 2; i++) {
readDataChipCRC[i] = myWire.read();
Serial.print(readDataChipCRC[i], HEX);
Serial.print(" ");
}
Serial.println();
//Serial.println("reset pulse not sent 2");
myWire.reset();
myWire.select(addr);
myWire.write(0xAA); // Read Scratchpad
byte readData[13];
Serial.print("Read scratchpad data: ");
for (int i = 0; i < 13; i++) {
readData[i] = myWire.read();
Serial.print(readData[i], HEX);
Serial.print(" ");
}
Serial.println();
ES = readData[2]; // Ending offset/data status byte
crc_read[0] = ~readData[11]; //LSB inverted - this is always junk data
crc_read[1] = ~readData[12]; //MSB inverted - this is always junk data
Serial.print("crc_read value:");
Serial.print(crc_read[1], HEX);
Serial.print(" ");
Serial.print(crc_read[0], HEX);
Serial.println();
uint16_t calculated_crc = ~OneWire::crc16(crcInput, 11, last_crc);
last_crc = calculated_crc;
uint16_t received_crc = (readDataChipCRC[1] << 8) | readDataChipCRC[0];
if (calculated_crc != received_crc) {
Serial.println("CRC mismatch, write aborted!");
Serial.print("Calculated CRC: ");
Serial.println(calculated_crc, HEX);
Serial.print("Received CRC: ");
Serial.println(received_crc, HEX);
Serial.print("Inverted CRCs: RX ");
Serial.println(~received_crc, HEX);
Serial.print("Inverted CRCs: Calculated ");
Serial.println(~calculated_crc, HEX);
return;
}
else{
//Serial.println("reset pulse sent 3");
myWire.reset();
myWire.select(addr);
myWire.write(0x55); // Copy Scratchpad
myWire.write(TA1); // Target address LSB
myWire.write(TA2); // Target address MSB - always 00 since memory is so small.
myWire.write(0x07); // ES - Ending offset/data status byte 0x07 if everything is correct
delay(40); // give operation time to complete
Serial.print("Page ");
Serial.print(page);
Serial.println(" written successfully.");
}
//Serial.println("End of WritePage function call");
}
void readPage(OneWire &myWire, uint8_t *addr, uint8_t page) {
byte TA1 = page * 8;
byte TA2 = 0;
myWire.reset();
myWire.select(addr);
myWire.write(0xF0); // Read Memory
myWire.write(TA1); // Target address LSB
myWire.write(TA2); // Target address MSB
Serial.print("Row ");
Serial.print(page);
Serial.println(" data:");
for (int i = 0; i < 8; i++) {
byte b = myWire.read();
Serial.print(b, HEX);
Serial.print(" ");
}
Serial.println();
}
void setup() {
Serial.begin(9600);
delay(4000); // Allow time to open Serial Monitor
Serial.println("Started");
OneWire myWire(EEPROM_pin);
uint8_t addr[8];
if (myWire.search(addr)) {
Serial.print("Found device with ROM: ");
printAddress(addr);
Serial.println();
for (uint8_t row = 0; row < 16; row++) {
Serial.print("Writing row ");
Serial.println(row);
if (row < 4){
writePage(myWire, addr, row, page1 + row * 8);
}
if ((row >= 4) && row < 8){
writePage(myWire, addr, row, page2 + (row - 4)* 8);
}
if ((row >= 8) && row < 12){
writePage(myWire, addr, row, page3 + (row - 8) * 8);
}
if ((row >= 12) && row < 16){
writePage(myWire, addr, row, page4 + (row - 12) * 8);
}
}
for (uint8_t row = 0; row < 16; row++) {
readPage(myWire, addr, row);
}
} else {
Serial.println("No devices found.");
}
}
void loop() {
while (true) {
Serial.println("Job done!");
delay(1000);
Serial.println("Work work");
delay(1000);
Serial.println("Zug Zug");
}
}