orgua / OneWireHub

OneWire slave device emulator
GNU General Public License v3.0
343 stars 86 forks source link

Non-Volatile Memory / Save Page Data to EPROM #117

Open eychei opened 1 year ago

eychei commented 1 year ago

Hi everyone,

Because this library is limit in regards to saving the Page data to a Board EPROM I had to try myself. For example, if you have a DS2431 which is written by an external source with some DATA (e.g. Last Usage Date) this will be lost when powering of the device. So I used the EPROM library to store the data there. When SETUP is called the data is restored to the 1W Device Memory.

Code looks like this:

/*
*    Example-Code that emulates a DS2431 1024 bits EEPROM
*
*   Tested with
*    - DS9490R-Master, atmega328@16MHz and teensy3.2@96MHz as Slave
*    - tested on buspirate and two different real 1-wire masters (DS9490 and a PIC18-Device)
*/

#include "OneWireHub.h"
#include "DS2431.h"
#include <EEPROM.h>

constexpr uint8_t pin_onewire   { 8 };

auto hub = OneWireHub(pin_onewire);
auto ds2431 = DS2431(DS2431::family_code, 0x00, 0x00, 0x31, 0x24, 0xDA, 0x00);

int i;

void printHex(uint8_t num) {
  char hexCar[2];

  sprintf(hexCar, "%02X", num);
  Serial.print(hexCar);
}

uint8_t Page_0[32];
uint8_t new_Page_0[32];
uint8_t Page_1[32];
uint8_t new_Page_1[32];
int address_P1 = sizeof(Page_0);

void copyArray(uint8_t* src, uint8_t* dst, int len) {
    memcpy(dst, src, sizeof(src[0])*len);
}

void setup() {
    Serial.begin(115200);
    Serial.println("OneWire-Hub DS2431");

    for(i=0; i<sizeof(ds2431.ID); i++){
      printHex(ds2431.ID[i]);
    }
    Serial.println();

    // Setup OneWire
    hub.attach(ds2431);

    EEPROM.get(0, Page_0);
    ds2431.writeMemory(Page_0, sizeof(Page_0), 0x00);
    ds2431.readMemory(new_Page_0, 32, 0x00);

    EEPROM.get(address_P1, Page_1);
    ds2431.writeMemory(Page_1, sizeof(Page_1), address_P1);
    ds2431.readMemory(new_Page_1, 32, address_P1);

    //ds2431.clearMemory(); // begin fresh after doing some work

    Serial.println("config done");

    Serial.println();

}

void loop() {
    // following function must be called periodically
    unsigned long starttime = millis();
    unsigned long endtime = starttime;
    while ((endtime - starttime) <=2000) // do this loop for up to 1000mS
    {
    // code here
    hub.poll();
    /*loopcount = loopcount+1;*/
    endtime = millis();
    }

    for(i=0; i<sizeof(Page_0); i++){
      if( new_Page_0[i] != Page_0[i] ){
        Serial.println("not equal");
        EEPROM.put(0, new_Page_0);
        Serial.print("EPROM Write Page_0!");
      }
    }
    copyArray(new_Page_0, Page_0, sizeof(new_Page_0));

    ds2431.readMemory(new_Page_0, 32, 0x00);
    // Serial.println("NewMemRead Done"); 
    // for(i=0; i<sizeof(new_Page_0); i++){
    //   if (new_Page_0[i] < 16) Serial.write('0');
    //     Serial.print(new_Page_0[i], HEX);
    //     Serial.print(" ");
    // }
    // Serial.println(); 

    for(i=0; i<sizeof(Page_1); i++){
      if( new_Page_1[i] != Page_1[i] ){
        Serial.println("not equal");
        EEPROM.put(address_P1, new_Page_1);
        Serial.print("EPROM Write Page_1!");
      }
    }
    copyArray(new_Page_1, Page_1, sizeof(new_Page_1));

    ds2431.readMemory(new_Page_1, 32, address_P1);
    // Serial.println("NewMemRead Done"); 
    // for(i=0; i<sizeof(new_Page_1); i++){
    //   if (new_Page_1[i] < 16) Serial.write('0');
    //     Serial.print(new_Page_1[i], HEX);
    //     Serial.print(" ");
    // }
    // Serial.println(); 

} 

The main issue here is that this will loop through the reedMemory over and over and thus interrupt with the normal functions of the emulator. I did implement a timer into the loop so it does readMemory and write EPROM only every 2 seconds but this is not ideal. Maybe some other gifted coder can help out to optimize this code.

P.S. It is only storing Page 0 and Page 1 in EPROM