Go Down

Topic: EEPROMex "Exceeded maximum number of writes" (Read 6585 times) previous topic - next topic

Paul Beaudet

So I think your data consists of an array of ints; the index into the array is the 'chord index' and the value is the chordValue associated with that index.

Right on, chord index gets converted to the letter that the chordValue is associated with.

now stay with me on this one, going to take a turn into the weeds...
Because the function,
Code: [Select]
EEPROM.readBlock<int>(address, array, size);
requires bringing the whole array into ram, I run into issues when I want a larger array,
this is why I built the checkAlt( ) function I posted recently.
You have to kinda imagine the index as the iterations that the for loop is going though.
the index values get converted to address space in eeprom, (basically skipping every other byte as an int is 2 bytes)
the "modifier" helps reduce interations by selectively searching address space

This makes things more complex but gives the needed flexibility
The assignment function was a little more of a puzzle then expected, heres a part of it.
keep in mind the letter coming in will actually be the ascii number associated with it, see here http://web.cs.mun.ca/~michael/c/ascii-table.html
Code: [Select]
int assignAlt(int chordValue, int letterNum)
//returns overwritten value... just in case
  if(letterNum>ALPHA && letterNum<123)
    int startAddress=1;
    int endAddress=27;
    int modifier=96;
    for(int i=startAddress;i<endAdress;i++)
        int address=i*2-1;
        int lastValue=EEPROM.readInt(address, chordValue);
        return lastValue;
  if(letterNum>64 && letterNum<59)

Wondering if this is possible with out the for loop, gathering the address from an equation?


I would start the problem from the bottom up. Assuming that the chords will be held in EEPROM as an array of ints starting at a known position within the EEPROM, you need to be able to read and write to the int values within that array. An API to do that could be:

Code: [Select]

// incomplete, untested
const int CHORD_BASE = 0;
const int CHORD_COUNT = 26;
const int UNDEFINED_CHORD = -1;

// read a chord from the store (returns UNDEFINED_CHORD if no value stored)
int readChord(byte chordNumber)
    // pull two bytes out of EEPROM at the appropriate position and make an int out of them
    return word(EEPROM.read(CHORD_BASE+(2*chordNumber)), EEPROM.read(CHORD_BASE+(2*chordNumber)+1));

// write a chord to the store
void writeChord(byte chordNumber, int chordValue)
    // split the int into two bytes and write them to EEPROM at the appropriate position
    EEPROM.write(CHORD_BASE+(2*chordNumber), highByte(chordValue);
    EEPROM.write(CHORD_BASE+(2*chordNumber)+1, lowByte(chordValue);

Then you would build the allocation/lookup functions on top of that:
Code: [Select]

// incomplete, untested
// return the chord number associated with this chord value, allocating it if necessary
byte getChordNumber(chordValue)
    // walk through the array of chords until a matching value is found, append to the array if no match found
    for(byte i = 0; i < CHORD_COUNT; i++)
        int val = readChord(i);
        if(val == chordValue)
            // this element holds the chord we're looking for
            return i;
        else if (val == UNDEFINED_CHORD)
            // this element is empty so store the new chord here
             writeChord(i, chordValue);
             return i;
    // we failed to identify an existing chord and also failed to find space for a new chord
    return 0; // consider returning some other value to indicate an error condition, but make sure you calling code handles it

I'd also suggest that you do the chord number to chord letter conversion at the interface, and represent them as numbers internally. All you need to do is a range check to confirm it's a character in the correct range 'a'-'z', and subtract 'a' from it.
I only provide help via the forum - please do not contact me for private consultancy.

Paul Beaudet

Jan 31, 2013, 04:43 am Last Edit: Jan 31, 2013, 10:03 pm by Paul Beaudet Reason: 1
Perfect, now I see the light at the end of the tunnel, definitely shows this can be done without the library. I'll put a proof of concept together tomorrow.

I didn't even know these functions existed
Code: [Select]

word(byte, byte);//syntax is kind quirky for what it seems to do
//can it handle other variable types?

Now I do,.. learn something new everyday :D

Thank you Peter, for taking the time to draft that out.

Paul Beaudet

Success!!  Well at least for me, anyone concerned with the issue the op stated is still SOL
The solution to me is the library is unnecessary
Though I do applude its effort and intention
Wear leveling is the only thing that I'm missing out on now, but I can afford to figure that out later

Anyhow here is the example code I came up with tested and working
feel free to try it out and do what you want with it, only requires the uno.
Code: [Select]
*test character layout building functions using eeprom
*prints actions to serial monitor

#include <EEPROM.h>

byte key=22; // change to be able to do a second write, between 1-255

void setup()
  delay(2000);//give some time to pull up the serial monitor and see the write
  if (session(512,key))//session will read false in the case the key is different
  //the session function helps reduce accidental/unnessiary writes
    randAssignment(97,123,0);//lowercase storage, addressspace=letter
    EEPROM.write(512,key);//set key so assignment only happens once/change to rewrite
  //the goes through an iteration of most of the positive int value space to check if the values stored
  for (int chord = 1; chord<32000; chord++)
    byte letteR=check(chord);
    if (letteR > 0)
      Serial.print(F(" read data equals "));
      Serial.print(F(" and its value is equal to-> "));

void loop()

int assign(int letter, int chordValue)
  int modifier=0;
  int storedVal=word(EEPROM.read(letter*2), EEPROM.read(letter*2+1));
  //allow letters to posibily have more then one value
    if (letter>96 && letter<123)
    storedVal=word(EEPROM.read(letter*2+modifier), EEPROM.read(letter*2+1+modifier));
  EEPROM.write(letter*2+modifier, highByte(chordValue));
  EEPROM.write(letter*2+1+modifier, lowByte(chordValue));
  return storedVal;


byte check(int chordValue)
  byte letter=0;
  for(int address=2;address<254;address=address+2)//full address range
    int reading=word(EEPROM.read(address), EEPROM.read(address+1));
    if(reading == chordValue)
        letter=address/2;//luckly we are just dealing with even numbers
        return letter;
      //synonymous chords
        return letter;
  return letter;

//---------------------------------------------------------make assignments
void randAssignment(byte startL, byte endL, byte modifier)
{//random assignment
   for (int makeLetter=startL;makeLetter<endL;makeLetter++)
    int data=random(1,32000);
    assign(makeLetter, data);
    //debuging info
    int modifiedL=makeLetter-modifier;
    char makeLetterChar = char(modifiedL);
    Serial.print(F(" was assigned to "));
  Serial.println(F("Assignment made"));

//-----------------------------check for persistent key
boolean session(int address, byte code)
{//establishes if source has been run by checkig is a key/code has been written
  byte potentialCode=EEPROM.read(address);
    return false;
  else{return true;};

//--------------------clear EEPROM
void clearPROM(int start, int finish)
  for(int i=start;i<finish;i++)
    delay(6);//again percautionary, not sure is this is nessisary

Keep in mind there is some extra kruft in here that is meant for the main program, regardless it proves the concept

Thanks for the help everyone


Feb 20, 2015, 10:35 pm Last Edit: Feb 21, 2015, 08:13 am by svicar
Dear all
I need a little of help.
I will simplify the problem

I use #include <EEPROMex.h>

if I put in the loop:
byte test;
test = EEPROM.readByte(0);

there is all ok

but if I want read 10 bytes and store it into AktivniAlarmi_temp array
if I put on loop:
EEPROM.readBlock<byte>(0, AktivniAlarmi_temp, 10);

on the serial monitor appear the message:
"Exceeded maximum number of writes

I am just reading from EEPROM..Why the write exceeding message???

thank you all for help


I don't understand how checkEX could, itself, lead to that error message.

I'm looking at the library, and that message comes from EEPROMEx.isWriteOK - but checkEX is only reading, not writing, and is only doing so through the normal EEPROM library, not EEPROMex. Something isn't adding up here.

That said, 33000 is very close to 32768, which is when integers roll over - if the point at which things start going wrong is there, I'll bet money that that's the cutoff when things break. But I don;t know why they would.
ATtiny core for 841+1634+828 and x4/x5/x61/x7/x8 series Board Manager:
ATtiny 841/1634/828/88/861/167 breakouts, mosfets, touch sensors and prototyping board in my store http://tindie.com/stores/DrAzzy


Feb 21, 2015, 06:10 pm Last Edit: Feb 21, 2015, 06:26 pm by svicar
Does someone understand how the EEPROMex work???

if I put to the loop

for (int i=0; i<10;i++)
    AktivniAlarmi_temp[ i ]= EEPROM.readByte(AktivniAlarmi_ADR + i);

its all ok...no message on the serial monitor

if I put the same thing

EEPROM.readBlock<byte>(AktivniAlarmi_ADR, AktivniAlarmi_temp, 10);

on the serial monitor appear the message after few seconds:
"Exceeded maximum number of writes

I am just reading from EEPROM..Why the write exceeding message???
does someone understand this??

thank you


One suggestion is to stop using EEPROMex as the OP has (whose old thread you hijacked).


I need to permanet save few variables..why not to use EPROM???

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!

via Egeo 16
Torino, 10131