Load the Delay Value From EPROM

Hello all,

Lets Say, 2bytes are saved for delay interval and 2 bytes are saved for 12bit DATA(Ignore MSB 4 bits)In EPROM.

Read First 4 bytes in first iteration(interval+data bits),assign delay value to the delay function,
When Delay Is equal to 0,send that data bits to the port pins.

read next 4 Bytes in next iteration and so on.until Null bit occured in eprom.
Any help will be appreciated.

Thanks.

What have you tried so far ?
Can you save and load data from the EEPROM ?
Which Arduino ?
Depending on the type of Arduino are you aware of the EEPROM.put() and EEPROM.get() functions ?

Few Queries:

1. How is the mapping of the 16-bit data of two consecutive memory locations with ms? I mean:

int mapDelay = map(data16, 0, 65536, 0, 5000); // 0ms to 5000ms

2. Which two ports of the UNO (Arduino what?) will receive the 12-bit data (6+6 or 8+4)?

3. How many chunks of 4-bye data in the EEPROM?

4. Is it Null bit or Null byte that will contain all 0s or all 1s?

5. Have you tried something in the form of code? If so, please post it here.

#include <EEPROM.h>
// Absolute min and max eeprom addresses. Actual values are hardware-dependent.
// These values can be changed e.g. to protect eeprom cells outside this range.
const int EEPROM_MIN_ADDR = 0;
const int EEPROM_MAX_ADDR = 511;
char array[]={0X00,0X64,0X0F,0XE4,
              0x00,0XC8,0X2C,0xD0,
              0x01,0X2c,0X90,0X45,
              0X01,0X90,0X37,0XDE,
              0X01,0XF4,0XAB,0XFA};
// Returns true if the address is between the
// minimum and maximum allowed values, false otherwise.
//
// This function is used by the other, higher-level functions
// to prevent bugs and runtime errors due to invalid addresses.
boolean eeprom_is_addr_ok(int addr) {
return ((addr >= EEPROM_MIN_ADDR) && (addr <= EEPROM_MAX_ADDR));
}

// Writes a sequence of bytes to eeprom starting at the specified address.
// Returns true if the whole array is successfully written.
// Returns false if the start or end addresses aren't between
// the minimum and maximum allowed values.
// When returning false, nothing gets written to eeprom.
boolean eeprom_write_bytes(int startAddr, const byte* array, int numBytes) {
// counter
int i;
// both first byte and last byte addresses must fall within
// the allowed range 
if (!eeprom_is_addr_ok(startAddr) || !eeprom_is_addr_ok(startAddr + numBytes)) {
return false;
}
for (i = 0; i < numBytes; i++) {
EEPROM.write(startAddr + i, array[i]);
}
return true;
}

// Writes a string starting at the specified address.
// Returns true if the whole string is successfully written.
// Returns false if the address of one or more bytes fall outside the allowed range.
// If false is returned, nothing gets written to the eeprom.
boolean eeprom_write_string(int addr, const char* string) {

int numBytes; // actual number of bytes to be written
//write the string contents plus the string terminator byte (0x00)
numBytes = strlen(string) + 1;
return eeprom_write_bytes(addr, (const byte*)string, numBytes);
}

// Reads a string starting from the specified address.
// Returns true if at least one byte (even only the string terminator one) is read.
// Returns false if the start address falls outside the allowed range or declare buffer size is zero.
// 
// The reading might stop for several reasons:
// - no more space in the provided buffer
// - last eeprom address reached
// - string terminator byte (0x00) encountered.
boolean eeprom_read_string(int addr, char* buffer, int bufSize) {
byte ch; // byte read from eeprom
int bytesRead; // number of bytes read so far
if (!eeprom_is_addr_ok(addr)) { // check start address
return false;
}

if (bufSize == 0) { // how can we store bytes in an empty buffer ?
return false;
}
// is there is room for the string terminator only, no reason to go further
if (bufSize == 1) {
buffer[0] = 0;
return true;
}
bytesRead = 0; // initialize byte counter
ch = EEPROM.read(addr + bytesRead); // read next byte from eeprom
buffer[bytesRead] = ch; // store it into the user buffer
bytesRead++; // increment byte counter
// stop conditions:
// - the character just read is the string terminator one (0x00)
// - we have filled the user buffer
// - we have reached the last eeprom address
while ( (ch != 0x00) && (bytesRead < bufSize) && ((addr + bytesRead) <= EEPROM_MAX_ADDR) ) {
// if no stop condition is met, read the next byte from eeprom
ch = EEPROM.read(addr + bytesRead);
buffer[bytesRead] = ch; // store it into the user buffer
bytesRead++; // increment byte counter
}
// make sure the user buffer has a string terminator, (0x00) as its last byte
if ((ch != 0x00) && (bytesRead >= 1)) {
buffer[bytesRead - 1] = 0;
}
return true;
}
const int BUFSIZE = 20;
char buf[BUFSIZE];
String myString; 
char myStringChar[BUFSIZE];
void setup()
{
Serial.begin(9600);
eeprom_write_string(0, array);
Serial.print("Reading string from address 0: "); 
eeprom_read_string(0, buf, BUFSIZE);
Serial.println(buf,HEX);

}

void loop()
{

}

Using UNO.
tried write read hex string from eeprom...but cant see anything on serial monitor.12bit data would be 8+4..there will be 80 bytes in eprom so 20 chunks are there.the interval is first 2 bytes of chunk all are In msec..i have taken 100ms,200ms,300ms,400ms,500ms for testing purpose.

1. Excellent response! I am assuming 8-bit Port as <PB5, PB4, PC5 - PC0> and the 4-bit Port as <PB3 - PB0> for testing purposes.

2. EEPROM Rnage: 0x0000 - 0x03FF (1024 bytes)

3. Op's 4x20 Bytes Range: 0x0010 - 0x005F

4. Op's test locations range (4x5 Bytes) : 0x0010 - 0x0023

5. Pre-stored data for the test locations of Step-4: (lower order memory location contains lower byte data) are:

0x0010 = 0x14 (lower byte of 100ms time delay under: int mapDelay = map(data16, 0, 65536, 0, 5000)
0x0011 = 0x05 (upper byte of 100ms time delay
0x0012 = 0x01 (8-bit data for 8-bit Port (<PB5, PB4, PC5 - PC0>)).
0x0013 = 0x01 (4-bit data for 4-bit Port (<PB3 - PB0>)).

0x0014 = 0x28 for 200 ms
0x0015 = 0x0A
0x0016 = 0x02
0x0017 = 0x02

0x0018 = 0x3C for 300 ms
0x0019 = 0x0F
0x001A = 0x03
0x001B = 0x03

0x001C = 0x50 for 400 ms
0x001D = 0x14
0x001E = 0x04
0x001F = 0x04

0x0020 = 0x64 for 500 ms
0x0021 = 0x19
0x0022 = 0x05
0x0023 = 0x05

6. Let us keep the data of Step-5 into the indicated EEPROM locations. The sketch is:

#include<EEPROM.h>

byte dataArray[20] = 
{
  0x14, 0x05, 0x01, 0x01, 0x28, 0x0A, 0x02, 0x02, 0x3C, 0x0F, 0x03, 0x03,
  0x50, 0x14, 0x04, 0x04, 0x64, 0x19, 0x05, 0x05
}; //0x0010, 0x0011, ..., 0x0023

void setup() 
{
  Serial.begin(9600);
  DDRB = 0xFF;   //IO lines are outputs
  DDRC = 0xFF;  //IO lines are outputs

  EEPROM.put(0x0010, dataArray);  /data of the whole array is written
  byte x = EEPROM.read(0x0017);
  Serial.println(x, HEX);   //shows 2 (02) data is well written

}

void loop() 
{
  

}

7. Taking the sketch of Step-6 as the foundation, you may add additional codes to finish your project.

working like a charm!

stuck in Reading 4 byte block at a time..assign first two bytes to delayMs Function..when delay is elapsed,
write next two bytes to the 12 pins..at the end of that loop again read 4 bytes so next time it will take different delay value.

Problem in making state machine call and pointing to the proper address in eeprom?

akshay123:
Problem in making state machine call and pointing to the proper address in eeprom?

1. Please, add some lines of codes (whatever comes in your mind) with the foundation sketch of Post#4 in order to read data from all these EEPROM locations: 0x0010 - 0x0023 and store them in this array: byte readArray[20];.

Hints: declare the array in the global space and then execute this instruction in the setup() space: EEROM.get(0x0010, readArray);. Print a data byte from a known location of the readArray[] and check that the data byte is correct.

2. Once the job of Step-1 is done, we will address your next question.

3. In case you have serious problem in the coding, you may consult the following sketch:

#include<EEPROM.h>

byte dataArray[20] = 
{
  0x14, 0x05, 0x01, 0x01, 0x28, 0x0A, 0x02, 0x02, 0x3C, 0x0F, 0x03, 0x03,
  0x50, 0x14, 0x04, 0x04, 0x64, 0x19, 0x05, 0x05
}; //0x0010, 0x0011, ..., 0x0023

byte readArray[20];

void setup() 
{
  Serial.begin(9600);
  DDRB = 0xFF;   //IO lines are outputs
  DDRC = 0xFF;  //IO lines are outputs

  EEPROM.put(0x0010, dataArray);  //data of the whole array is written
  byte x = EEPROM.read(0x0017);
  Serial.println(x, HEX);   //shows 2 (02) data is well written
  
  //---reading all data bytes form EEPROM and save in array----
  EEPROM.get(0x0010, readArray);
  Serial.println(readArray[0], HEX); //data validity check
  
  //--extract port data and time delay information from 0x0010-0x0013-- 
  int mapDelay = map((readArray[1]<<8|readArray[0]), 0, 65536, 0, 5000);
  PORTC = readArray[2]; //
  bitWrite(PORTB, 6, bitRead(readArray[2], 6));
  bitWrite(PORTB, 7, bitRead(readArray[2], 7));
  PORTB = readArray[3];
  delay(mapDelay); //wait for 100ms
  //----------------------------------
}

void loop() 
{
  

}
#include <EEPROM.h>

//pin #s on a Mega 2560. Adjust for your device 
const int pinPattern[] = 
    { 22,24,26,28,30,32,34,36,38,40,42,44};

    
void setup() 
{
    int
        i, j;

    //set up IO pins as outputs and set them low
    for( i=0; i<12; i++ )
    {
        pinMode( pinPattern, OUTPUT );
        digitalWrite( pinPattern, LOW );
    }//for

    //serial console gives visibility into what's happening
    Serial.begin(9600);
    while(!Serial);     //block waiting for console to open

    //put something in EEPROM to verify
    j = 0x0041;
    for( i=0; i<5; i++ )
    {
        WriteToEEPROM( i*4, (i+1)*5000 );   //00, 01
        WriteToEEPROM( (i*4)+2, j );        //02, 03
        j <<= 1;
        
    }//for
    
    //null entries to stop the loop
    WriteToEEPROM( i*4, 0x0000 );
    WriteToEEPROM( (i*4)+2, 0x0000 );

}//setup

void loop() 
{
    static int
        Addr;    
    int
        nDelay,
        nPattern;

    //read the value and bit-pattern ints from the EEPROM
    Addr = 0;
    ReadEEPROM( Addr, &nDelay );
    ReadEEPROM( Addr+2, &nPattern );
    while( nDelay !=0 && nPattern !=0 )
    {
        //call the function, passing the address of these variable...
        DelayFunction( &nDelay, &nPattern );

        Addr+=4;
        ReadEEPROM( Addr, &nDelay );
        ReadEEPROM( Addr+2, &nPattern );

        delay(1000); //allow time to show pattern
        
    }//while

    Serial.println( "Saw null entries. Halting. " );
    while(1);
       
}//loop

void DelayFunction( int *Delay, int *Pattern )
{
    int
        i;
        
    //show the values for clarity
    Serial.print("Delay...." ); Serial.println( *Delay, DEC );
    Serial.print("Pattern.." ); Serial.println( *Pattern, HEX );
    Serial.println("Delaying..." );
    //apply a blocking delay specified at *Delay
    delay( *Delay );

    //
    Serial.println( "Driving outputs..." );
    for( i=0; i<12; i++ )
        digitalWrite( pinPattern[i], (Pattern[i] & (1<<i)?HIGH:LOW ));
        
}//DelayFunction

void ReadEEPROM( int Addr, int *Target )
{
    int
        val;
    byte
        hi,
        lo;
        
    //read two bytes from the value in the EEPROM 
    //combine them into an int and place in the Target variable
    hi = EEPROM.read(Addr);
    lo = EEPROM.read(Addr+1);
    val = (hi << 8) | lo;
    *Target = val;
        
}//ReadEEPROM

void WriteToEEPROM( int Addr, int Value )
{
    byte
        hi,
        lo;

    hi = (Value >> 8) & 0xff;
    lo = Value & 0xff;
    
    //Serial.println( Value, HEX );
    //Serial.println( ((Value >> 8) & 0xff), HEX );
    //Serial.println( (Value & 0xff), HEX );
    
    EEPROM.write( Addr, hi );
    EEPROM.write( Addr+1, lo );
    
}//WriteToEEPROM