Go Down

Topic: [SOLVED] Issues writing to DS2438 onboard EEPROM (Read 143 times) previous topic - next topic

LowlyMillipede

Aug 10, 2016, 05:48 pm Last Edit: Aug 12, 2016, 09:50 am by LowlyMillipede
Hi all,

I'm building a bunch of different types of sensors which all use the DS2438 battery monitor. I'd like to be able to write some magic value to the EEPROM of the DS2438 so that I can tell which type of sensor I'm reading.

Unfortunately, my test code doesn't seem to be working. Every time the EEPROM is dumped to Serial, it's unchanged from the last time despite an attempt to write new data. However, the data is successfully written to the scratchpad so I think the error has to do with the COPY_SCRATCHPAD part of the code.

Any help would be greatly appreciated.

Code:
Code: [Select]

#include <OneWire.h>

#define DS2438_TEMPERATURE_CONVERSION_COMMAND 0x44
#define DS2438_VOLTAGE_CONVERSION_COMMAND 0xB4
#define DS2438_WRITE_SCRATCHPAD_COMMAND 0x4E
#define DS2438_COPY_SCRATCHPAD_COMMAND 0x48
#define DS2438_READ_SCRATCHPAD_COMMAND 0xBE
#define DS2438_RECALL_MEMORY_COMMAND 0xB8
#define DS2438_PAGE_3 0x03

#define BUS_INPUT_PIN 4

const byte addr[] = {0x26, 0x88, 0x2f, 0xf5, 0x01, 0x00, 0x00, 0xe6};

OneWire ds(BUS_INPUT_PIN);

void setup() {
  Serial.begin(115200);

  delay(10);
}

void loop() {
  Serial.println("Dumping entire EEPROM:");
  dumpEeprom();

  delay(2000);

  Serial.print("\n\nWriting...");
  writeEeprom();
  Serial.println(" done.");

  delay(10000);

  Serial.println("\n\nDumping scratchpad:");
  dumpScratchpad();

  Serial.println("\n\n");

  delay(2000);
}

void writeEeprom() {
  ds.reset();
  ds.select(addr);
  
  ds.write(DS2438_WRITE_SCRATCHPAD_COMMAND, 0);
  ds.write(DS2438_PAGE_3, 0);

  for (int i = 0; i < 8; i++) {
    ds.write(random(0, 250), 0);
  }

  ds.reset();
  ds.select(addr);
  
  ds.write(DS2438_COPY_SCRATCHPAD_COMMAND, 0);
  ds.write(DS2438_PAGE_3, 0);

  delay(20);
}

void dumpEeprom() {
  for (int p = 0; p < 8; p++) {
    ds.reset();
    ds.select(addr);

    ds.write(DS2438_RECALL_MEMORY_COMMAND);
    ds.write(p); // page p

    ds.reset();
    ds.select(addr);

    ds.write(DS2438_READ_SCRATCHPAD_COMMAND);
    ds.write(p);

    byte data[9];

    Serial.print("Page ");
    Serial.print(p);
    Serial.print(": ");

    for (int i = 0; i < 9; i++) {
      data[i] = ds.read();

      if (data[i] < 16) {
        Serial.print("0");
      }

      Serial.print(data[i], HEX);
    }

    boolean valid = ds.crc8(data, 8) == data[8];

    Serial.println(valid ? " (Y)" : " (N)");
  }
}

void dumpScratchpad() {
  for (int p = 0; p < 8; p++) {
    byte data[9];

    Serial.print("Page ");
    Serial.print(p);
    Serial.print(": ");

    ds.reset();
    ds.select(addr);

    ds.write(DS2438_READ_SCRATCHPAD_COMMAND, 0);
    ds.write(p, 0);

    for (int i = 0; i < 9; i++) {
      data[i] = ds.read();

      if (data[i] < 16) {
        Serial.print("0");
      }

      Serial.print(data[i], HEX);
    }

    boolean valid = ds.crc8(data, 8) == data[8];

    Serial.println(valid ? " (Y)" : " (N)");
  }
}



Output:
Code: [Select]

Dumping entire EEPROM:
Page 0: 0F00000000000000FA (Y)
Page 1: 00000000000800FCF2 (Y)
Page 2: 000000000000000000 (Y)
Page 3: 000000000000000000 (Y)
Page 4: 000000000000000000 (Y)
Page 5: 000000000000000000 (Y)
Page 6: 000000000000000000 (Y)
Page 7: 000000000000000000 (Y)


Writing... done.


Dumping scratchpad:
Page 0: 0F00000000000000FA (Y)
Page 1: 00000000000800FCF2 (Y)
Page 2: 000000000000000000 (Y)
Page 3: B97556922BF629CEAB (Y)
Page 4: 000000000000000000 (Y)
Page 5: 000000000000000000 (Y)
Page 6: 000000000000000000 (Y)
Page 7: 000000000000000000 (Y)



Dumping entire EEPROM:
Page 0: 0F00000000000000FA (Y)
Page 1: 00000000000800FCF2 (Y)
Page 2: 000000000000000000 (Y)
Page 3: 000000000000000000 (Y)
Page 4: 000000000000000000 (Y)
Page 5: 000000000000000000 (Y)
Page 6: 000000000000000000 (Y)
Page 7: 000000000000000000 (Y)

chucktodd

Hi all,

I'm building a bunch of different types of sensors which all use the DS2438 battery monitor. I'd like to be able to write some magic value to the EEPROM of the DS2438 so that I can tell which type of sensor I'm reading.

Unfortunately, my test code doesn't seem to be working. Every time the EEPROM is dumped to Serial, it's unchanged from the last time despite an attempt to write new data. However, the data is successfully written to the scratchpad so I think the error has to do with the COPY_SCRATCHPAD part of the code.

Any help would be greatly appreciated.

Code:
Code: [Select]

#include <OneWire.h>

#define DS2438_TEMPERATURE_CONVERSION_COMMAND 0x44
#define DS2438_VOLTAGE_CONVERSION_COMMAND 0xB4
#define DS2438_WRITE_SCRATCHPAD_COMMAND 0x4E
#define DS2438_COPY_SCRATCHPAD_COMMAND 0x48
#define DS2438_READ_SCRATCHPAD_COMMAND 0xBE
#define DS2438_RECALL_MEMORY_COMMAND 0xB8
#define DS2438_PAGE_3 0x03

#define BUS_INPUT_PIN 4

const byte addr[] = {0x26, 0x88, 0x2f, 0xf5, 0x01, 0x00, 0x00, 0xe6};

OneWire ds(BUS_INPUT_PIN);

void setup() {
  Serial.begin(115200);

  delay(10);
}

void loop() {
  Serial.println("Dumping entire EEPROM:");
  dumpEeprom();

  delay(2000);

  Serial.print("\n\nWriting...");
  writeEeprom();
  Serial.println(" done.");

  delay(10000);

  Serial.println("\n\nDumping scratchpad:");
  dumpScratchpad();

  Serial.println("\n\n");

  delay(2000);
}

void writeEeprom() {
  ds.reset();
  ds.select(addr);
  
  ds.write(DS2438_WRITE_SCRATCHPAD_COMMAND, 0);
  ds.write(DS2438_PAGE_3, 0);

  for (int i = 0; i < 8; i++) {
    ds.write(random(0, 250), 0);
  }

  ds.reset();
  ds.select(addr);
  
  ds.write(DS2438_COPY_SCRATCHPAD_COMMAND, 0);
  ds.write(DS2438_PAGE_3, 0);

  delay(20);
}

void dumpEeprom() {
  for (int p = 0; p < 8; p++) {
    ds.reset();
    ds.select(addr);

    ds.write(DS2438_RECALL_MEMORY_COMMAND);
    ds.write(p); // page p

    ds.reset();
    ds.select(addr);

    ds.write(DS2438_READ_SCRATCHPAD_COMMAND);
    ds.write(p);

    byte data[9];

    Serial.print("Page ");
    Serial.print(p);
    Serial.print(": ");

    for (int i = 0; i < 9; i++) {
      data[i] = ds.read();

      if (data[i] < 16) {
        Serial.print("0");
      }

      Serial.print(data[i], HEX);
    }

    boolean valid = ds.crc8(data, 8) == data[8];

    Serial.println(valid ? " (Y)" : " (N)");
  }
}

void dumpScratchpad() {
  for (int p = 0; p < 8; p++) {
    byte data[9];

    Serial.print("Page ");
    Serial.print(p);
    Serial.print(": ");

    ds.reset();
    ds.select(addr);

    ds.write(DS2438_READ_SCRATCHPAD_COMMAND, 0);
    ds.write(p, 0);

    for (int i = 0; i < 9; i++) {
      data[i] = ds.read();

      if (data[i] < 16) {
        Serial.print("0");
      }

      Serial.print(data[i], HEX);
    }

    boolean valid = ds.crc8(data, 8) == data[8];

    Serial.println(valid ? " (Y)" : " (N)");
  }
}



Output:
Code: [Select]

Dumping entire EEPROM:
Page 0: 0F00000000000000FA (Y)
Page 1: 00000000000800FCF2 (Y)
Page 2: 000000000000000000 (Y)
Page 3: 000000000000000000 (Y)
Page 4: 000000000000000000 (Y)
Page 5: 000000000000000000 (Y)
Page 6: 000000000000000000 (Y)
Page 7: 000000000000000000 (Y)


Writing... done.


Dumping scratchpad:
Page 0: 0F00000000000000FA (Y)
Page 1: 00000000000800FCF2 (Y)
Page 2: 000000000000000000 (Y)
Page 3: B97556922BF629CEAB (Y)
Page 4: 000000000000000000 (Y)
Page 5: 000000000000000000 (Y)
Page 6: 000000000000000000 (Y)
Page 7: 000000000000000000 (Y)



Dumping entire EEPROM:
Page 0: 0F00000000000000FA (Y)
Page 1: 00000000000800FCF2 (Y)
Page 2: 000000000000000000 (Y)
Page 3: 000000000000000000 (Y)
Page 4: 000000000000000000 (Y)
Page 5: 000000000000000000 (Y)
Page 6: 000000000000000000 (Y)
Page 7: 000000000000000000 (Y)

Is your DS2438 parasitically powered? all of your calls set the power bit to 0, the Eprom Write takes energy.


    // Write a byte. If 'power' is one then the wire is held high at
    // the end for parasitically powered devices. You are responsible
    // for eventually depowering it by calling depower() or doing
    // another read or write.


Change your code like this
Code: [Select]

 ds.reset();
  ds.select(addr);
  
  ds.write(DS2438_COPY_SCRATCHPAD_COMMAND, 1);
  ds.write(DS2438_PAGE_3, 1);

  delay(20);


Chuck.

LowlyMillipede

#2
Aug 11, 2016, 09:52 am Last Edit: Aug 11, 2016, 11:09 am by LowlyMillipede
Thank you for your reply.

The DS2438 is not parasitically powered. It is being powered by the 5V pin of the Arduino.

In case it is helpful, here is a schematic of the test circuit I am using:

chucktodd

Thank you for your reply.

The DS2438 is not parasitically powered. It is being powered by the 5V pin of the Arduino.

In case it is helpful, here is a schematic of the test circuit I am using:

Is this an Accurate picture of your circuit?  If so,  I am amazed it works.

You have power going into the General purpose A/D pin, and the VDD pin is not connected to anything?



I suspect this is why the circuit is not writing to the EEPROM, It is effectively parasitically powered.

Since you do not have Vdd connected to anything, the only power it gets is from the DQ pin.

And since you power it down as soon as you send it the WriteEEprom cmd, it fails.

Either leave the power on, or connect Vdd

Chuck.

LowlyMillipede

It looks like I misread the datasheet. Seems like a stupid thing to have wasted so much time on.

Thank you very much for your help.

Go Up
 


Please enter a valid email to subscribe

Confirm your email address

We need to confirm your email address.
To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

Arduino
via Egeo 16
Torino, 10131
Italy