EEPROMex "Exceeded maximum number of writes"

It looks a lot like I'm getting Exceeded writes issue after my program has reported it has written everything it needed to.
but that doesn't make sense, I would be thankful for another set of eyes on this one.

The goal is to get a serial print out of whatever random assignment is made to the layout array
however what I get is an error from the EEPROMex library that prints "Exceeded maximum number of writes" continually line after line

#include <EEPROMex.h>

//eepromextest using the uno
//builds a letter layout with randomly assigned ints

int alphaAddress = 0;

int key=12;
boolean builtLayout=false;
char theLetter;
byte Lcount=0;


#define LSIZE 26
int layout[LSIZE]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
#define ALPHA 97

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

//still figuring out these safty functions are suposed to work
//EEPROM.setMemPool(350, EEPROMSizeUno);
//EEPROM.setMaxAllowedWrites(420);
//delay(100);


if (beenHere(511,key)==false){//this prevents writing the assignment over and over, persistently
  randAssignment(0,25);//lowercase storage, addressspace=letter
  EEPROM.write(511,key);//set key so assignment only happens once/change to rewrite
  Serial.println("key wrote");
  }
else{builtLayout=true;};
Serial.print("build ");
Serial.println(builtLayout);//---------!Continuealy prints "Exceeded maximum number of writes"
//-------------------------------------------!after this point, with "built" reading true

//this finds the values and reports what letter they will corespond with
for (int theValue=1;theValue<32761;theValue++){
  theLetter=checkEX(theValue);
  if(theLetter==0){
    continue;
  }
  else{
    Serial.print(theLetter);
    Serial.print(" == ");
    Serial.println(theValue);
    Lcount++;
  };
  if(Lcount==LSIZE){
    break;
  }
}
}

void loop() 
{
}
//-----------------------------------------------functions
//-------------------------------------------------random assignement function
void randAssignment(byte startL, byte endL)
{//random assignment
  for (int makeLetter=startL;makeLetter<endL;makeLetter++){
    int data=random(1, 32760);
    layout[makeLetter]=data;
    delay(30);
  }
  EEPROM.writeBlock<int>(alphaAddress, layout, LSIZE);
  builtLayout=true;
}
//----------------------------------------------layout checking function
char checkEX(int chordvalue)
{
  EEPROM.readBlock<int>(alphaAddress, layout, LSIZE);
  for(int i=0;i<LSIZE;i++){
    if(layout[i]==chordvalue){
      return char(i+ALPHA);
    }
  }
  return 0;
}


//-----------------------------check for persistent key
boolean beenHere(int address, byte code)
{//establishes if source has been run on uploaded to unit with a key/code
  byte potentialCode=EEPROM.read(address);
  if(code==potentialCode){
    return true;
  }
  else{return false;};
}

I've taken a closer look at the library source but i'm not quite sure I understand whats going on yet
shouldn't the size of the layout in eeprom be 52 bytes?

however what I get is an error from the EEPROMex library

A link to this library would be useful.

What are you running this code on?

http://thijs.elenbaas.net/2012/07/extended-eeprom-library-for-arduino/

I'm uploading to an uno

I also should mention If your using a unix based system EEPROMex.cpp has a typo that may need to be fixed
include "EEPROMEx.h" needs to be changed to include "EEPROMex.h"
the library maintainer may have fixed that though by this point in time.

So, what you are saying, is it gets stuck repeating the same thing in the setup() function, not in loop() ??

It's hard to see how that can happen, because there is nothing in the setup() function above the place
where you say it continually prints, which can cause that to iterate.

Are you sure that it is iterating, at the place in the code where you have commented that it is ?
Think about how that could be happening.

I am not too keen on if(beenThere(i,j)==false) but that should only be a stylistic thing.

There is nothing in your code which could print "exceeded maximum number of writes".

So that text must be being generated by the EEPROM functions, which must be "assuming" that
you have a Serial monitor connected - which seems like a fairly bogus assumption, but anyhow.

I suggest you find the code of the EEPROM library and see where that message could be originating.

Now, also, one would think that an EEPROM may complain about too many writes, in a function which
writes to the EEPROM. This only happens from your setup() directly, and from randAssignment(), above the
place in the code where you are identifying the problem occuring.

And those functions you commented out, are probably important. You need to have the EEPROM object
properly initialized to deal with the EEPROM in your particular arduino processor, and if you haven't initialized it
properly, it's not surprising it doesn't work.
For example, the number of permissible writes may be set to zero, unless you tell it otherwise.

michinyon:
There is nothing in your code which could print "exceeded maximum number of writes".

So that text must be being generated by the EEPROM functions, which must be "assuming" that
you have a Serial monitor connected - which seems like a fairly bogus assumption, but anyhow.

This is true, it is in the library, believe it or not.

bool EEPROMClassEx::isWriteOk(int address)
{
#ifdef _EEPROMEX_DEBUG    
	_writeCounts++;
	if (_allowedWrites == 0 || _writeCounts > _allowedWrites ) {
		Serial.println("Exceeded maximum number of writes");
		return false;
	}

	if (address > _memSize) {
		Serial.println("Attempt to write outside of EEPROM memory");
		return false;
	} else {
		return true;
	}
#endif		
	return true;
}

I really haven't been around c++ long enough to really be able to spot the issue right of the bat, I have been looking at the code for a while now but Im having a hard time putting the pieces together

I just ran it again figuring I may have unplugged to early... goes on and on it does indeed look like something has to be causing an infinate loop to produce this, but again oddly enough, this occurs after the randAssignment function not during, which completely baffles me.. well at least for the moment.

When I looked at the library source it didn't seem like EEPROM.readBlock could produce this but based on what I'm seeing thats where im looking. maybe that notion is a red herring.

michinyon:
And those functions you commented out, are probably important. You need to have the EEPROM object
properly initialized to deal with the EEPROM in your particular arduino processor, and if you haven't initialized it
properly, it's not surprising it doesn't work.
For example, the number of permissible writes may be set to zero, unless you tell it otherwise.

I started with these included. In the example code with the library they where noted as optional safety precautions, so I figure throw safety to the wind. when I got this result the first time and commented them out and then got the same thing

I'll test again with, just in case

It is very hard to read your code, with it all jammed together and improperly indented. I suggest that you put each { on a new line, and each } on a new line (where they belong), and use Tools + Auto Format to properly indent the code. Maybe then the reason for the looping can be seen.

got rid of it... I'm not sure why though, or what happened... maybe some sort of overflow?
new setup, I changed "theValue" in the for loop around.. with that much iteration the problem would seem infinite

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

  //still figuring out these safty functions are suposed to work
  EEPROM.setMemPool(350, EEPROMSizeUno);
  EEPROM.setMaxAllowedWrites(420);
  //delay(100);

  delay(4000);
  Serial.println("delay done");
  if (beenHere(511,key)==false){//this prevents writing the assignment over and over, persistently
    randAssignment(0,25);//lowercase storage, addressspace=letter
    EEPROM.write(511,key);//set key so assignment only happens once/change to rewrite
    Serial.println("key wrote");
  }
  else{
    builtLayout=true;
  };
  Serial.print("build ");
  Serial.println(builtLayout);//---------!Continuealy prints "Exceeded maximum number of writes"
  //-------------------------------------------!after this point, with "built" reading true

  //this finds the values and reports what letter they will corespond with
  for (int theValue=0;theValue<50;theValue++){
    theLetter=checkEX(theValue);
    if(theLetter==0){
      continue;
    }
    else{
      Serial.print(theLetter);
      Serial.print(" == ");
      Serial.println(theValue);
      Lcount++;
    };
    if(Lcount==LSIZE){
      break;
    }
  }
}

result being

delay done
build 1
z == 0

I guess there is a semantic issue with my code beyond the library error being returned at strange times
z is equal to 0 would give be the impression assignments were not made

Sorry paul, forgot about the auto format, I should probably start putting my comments on new lines too..

It looks a lot as if you're using an EEPROM library which is designed to limit the number of times the EEPROM can be written to by any given incarnation of the sketch, and your sketch is exceeding the limit. Presumably this is intended to protect people from design flaws which result in excessive EEPROM updates, and either you've got that flaw in your sketch or you've set the threshold too low.

It also looks to me as if the EEPROM interface library is spontaneously printing to the hardware serial port, which is IMO not something that an EEPROM access library would reasonably be expected to do.

PeterH:
It looks a lot as if you're using an EEPROM library which is designed to limit the number of times the EEPROM can be written to by any given incarnation of the sketch, and your sketch is exceeding the limit. Presumably this is intended to protect people from design flaws which result in excessive EEPROM updates, and either you've got that flaw in your sketch or you've set the threshold too low.

This is something that I not quite sure off in respect to what counts a write and over what period of time. I need to write an array of 26 ints which I assume amounts to 52 bytes because the library "stores" the array in the sense that it compares the variable in ram or progmem and orients it self based on the first address value. The values stored could be read into a completely different variable, so long as you were asking for the same type/sized variable and gave it the proper address for example.

so I assumed that writes are counted per byte, so at first when I was testing this I put EEPROM.setMaxAllowedWrites(100) and got the error ( a test separate from this one) so then I went allot higher around 600 and got no error... now I'm figuring it must be counted by bit

regardless the response of the error, occurs based on changing range values of the for loop after the writes supposedly occur. Values which most likely are not being written at all based on the fact the the for loop expires at layout25 (converted to z) being = to 0, ie all the other values were zero too.

I fixed my code.. well a bit. I think the problem is probably more clear now.

#include <EEPROMex.h>

//eepromextest using the uno
//builds a letter layout with randomly assigned ints

int alphaAddress = 0;

byte key=24;
boolean builtLayout=false;
char theLetter;
byte Lcount=0;

#define ALPHA 97
#define LSIZE 26
int layout[LSIZE]={
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
};

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

  EEPROM.setMemPool(350, EEPROMSizeUno);
  EEPROM.setMaxAllowedWrites(420);

  delay(2000);
  //wait to bring up serial monitor
  if (beenHere(511,key)==false)
  {
    randAssignment();
    EEPROM.write(511,key);
    //set key so assignment only happens once/change to rewrite
    Serial.println("key wrote");
  }
  else
  {
    builtLayout=true;
  };
  Serial.print("build ");
  Serial.println(builtLayout);

  //this finds the values and reports what letter they will corespond with
  for (int theValue=0;theValue<456;theValue++){
    theLetter=checkEX(theValue);
    if(theLetter==0)
    {
      continue;
    }
    else
    {
      Serial.print(theLetter);
      Serial.print(" == ");
      Serial.println(theValue);
      Lcount++;
    };
    if(Lcount==LSIZE)
    {
      break;
    }
  }
}

void loop() 
{
}
//-------------------------------------------------random assignement function
void randAssignment()
{
  for (int makeLetter=0;makeLetter<LSIZE;makeLetter++)
  {
    int data=random(1, 455);
    layout[makeLetter]=data;
    Serial.print(char(makeLetter+ALPHA));
    Serial.print("==");
    Serial.println(data);
    delay(30);
  }
  EEPROM.updateBlock<int>(alphaAddress, layout, LSIZE);
  builtLayout=true;
}
//----------------------------------------------layout checking function
char checkEX(int chordvalue)
{
  EEPROM.readBlock<int>(alphaAddress, layout, LSIZE);
  for(int i=0;i<LSIZE;i++)
  {
    if(layout[i]==chordvalue)
    {
      char letteR=char(i+ALPHA);
      return letteR;
      //adds 97 and coverts to its corresponding letter
    }
  }
  return 0;
}


//-----------------------------check for persistent key
boolean beenHere(int address, byte code)
{
  //establishes if source has been run on uploaded to unit with a key/code
  byte potentialCode=EEPROM.read(address);
  if(code==potentialCode){
    return true;
  }
  else
  {
    return false;
  };
}

And this is the result..

a==10
b==82
c==48
d==193
e==329
f==295
g==287
h==129
i==106
j==198
k==269
l==118
m==265
n==423
o==14
p==80
q==308
r==228
s==355
t==71
u==86
v==96
w==42
x==28
y==9
z==450
key wrote
build 1
y == 9
a == 10
o == 14
x == 28
w == 42
c == 48
t == 71
p == 80
b == 82
u == 86
v == 96
i == 106
l == 118
h == 129
d == 193
j == 198
r == 228
m == 265
k == 269
g == 287
f == 295
q == 308
e == 329
s == 355
Exceeded maximum number of writes
Exceeded maximum number of writes
Exceeded maximum number of writes
Exceeded maximum number of writes
Exceeded maximum number of writes
Exceeded maximum number of writes
Exceeded maximum number of writes
Exceeded maximum number of writes
Exceeded maximum number of writes
Exceeded maximum number of writes
Exceeded maximum number of writes
Exceeded maximum number of writes
Exceeded maximum number of writes
Exceeded maximum number of writes
Exceeded maximum number of writes
Exceeded maximum number of writes
Exceeded maximum number of writes
Exceeded maximum number of writes
Exceeded maximum number of writes
Exceeded maximum number of writes
Exceeded maximum number of writes
Exceeded maximum number of writes
Exceeded maximum number of writes
Exceeded maximum number of writes
Exceeded maximum number of writes
Exceeded maximum number of writes
Exceeded maximum number of writes
Exceeded maximum number of writes
Exceeded maximum number of writes
Exceeded maximum number of writes
Exceeded maximum number of writes
Exceeded maximum number of writes
Exceeded maximum number of writes
Exceeded maximum number of writes
Exceeded maximum number of writes
Exceeded maximum number of writes
Exceeded maximum number of writes
Exceeded maximum number of writes
Exceeded maximum number of writes
Exceeded maximum number of writes
Exceeded maximum number of writes
Exceeded maximum number of writes
Exceeded maximum number of writes
Exceeded maximum number of writes
Exceeded maximum number of writes
Exceeded maximum number of writes
Exceeded maximum number of writes
Exceeded maximum number of writes
Exceeded maximum number of writes
Exceeded maximum number of writes
Exceeded maximum number of writes
Exceeded maximum number of writes
Exceeded maximum number of writes
Exceeded maximum number of writes
Exceeded maximum number of writes
Exceeded maximum number of writes
Exceeded maximum number of writes
Exceeded maximum number of writes
Exceeded maximum number of writes
Exceeded maximum number of writes
Exceeded maximum number of writes
Exceeded maximum number of writes
Exceeded maximum number of writes
Exceeded maximum number of writes
Exceeded maximum number of writes
Exceeded maximum number of writes
Exceeded maximum number of writes
Exceeded maximum number of writes
n == 423
Exceeded maximum number of writes
Exceeded maximum number of writes
Exceeded maximum number of writes
Exceeded maximum number of writes
Exceeded maximum number of writes
Exceeded maximum number of writes
Exceeded maximum number of writes
Exceeded maximum number of writes
Exceeded maximum number of writes
Exceeded maximum number of writes
Exceeded maximum number of writes
Exceeded maximum number of writes
Exceeded maximum number of writes
Exceeded maximum number of writes
Exceeded maximum number of writes
Exceeded maximum number of writes
Exceeded maximum number of writes
Exceeded maximum number of writes
Exceeded maximum number of writes
Exceeded maximum number of writes
Exceeded maximum number of writes
Exceeded maximum number of writes
Exceeded maximum number of writes
Exceeded maximum number of writes
Exceeded maximum number of writes
Exceeded maximum number of writes
Exceeded maximum number of writes
z == 450

I have a feeling the library uses the same write function to read (write) the value into ram, which adds to the write count.
Which would explain the unpredictable behavior
I'm still going to give the library the benefit of the doubt though and say I'm probably wrong
Any other ideas?

In the example code with the library they where noted as optional safety precautions,

First, proper object initialization is probably not "an optional safety precaution".

And secondly, you have disabled part of the "optional safety precaution", while leaving the other part enabled.
If you really want to dispense with safety, then the " #ifdef _EEPROMEX_DEBUG " also needs to go, so that
"safety check" doesn't get executed either.

It's like taking the seat belt out of your car, and leaving the seat-belt monitoring device installed, and then
complaining when it beeps at you.

I have a feeling the library uses the same write function to read (write) the value into ram, which adds to the write count.

EEPROMs do have an actual physical limit on how many times you can reliably erase and re-write them. You can read them as often as you want. So the business of counting the write operations does have a point to it. You would not be wanting to add counting read operations to that.

michinyon:
It's like taking the seat belt out of your car, and leaving the seat-belt monitoring device installed, and then
complaining when it beeps at you.

not quite because I think that there is a default initialization of 100 writes regardless of whether the user sets it

its like the seat belt monitoring device is also measuring the rpms of the engine and I buckled my self in but its still going off and I can't figure out why.

anyhow here is some "working" code. Attention to the values, they are causing the problem.

#include <EEPROMex.h>
//eepromextest using the uno
//builds a letter layout with randomly assigned ints

int alphaAddress = 0;

byte key=48;
char theLetter;
byte Lcount=0;

#define ALPHA 97
#define LSIZE 26
int layout[LSIZE]={
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
};

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

  EEPROM.setMemPool(350, EEPROMSizeUno);
  EEPROM.setMaxAllowedWrites(32762);//nothing to see here.. move along

  delay(2000);
  //wait to bring up serial monitor
  if (beenHere(511,key)==false)
  {
    randAssignment();
    EEPROM.write(511,key);
    //set key so assignment only happens once/change to rewrite
    Serial.println("key wrote");
  }

  //this finds the values and reports what letter they will corespond with
  for (int theValue=0;theValue<32761;theValue++){
    theLetter=checkEX(theValue);
    if(theLetter==0)
    {
      continue;
    }
    else
    {
      Serial.print(theLetter);
      Serial.print(" == ");
      Serial.println(theValue);
      Lcount++;
    };
    if(Lcount==LSIZE)
    {
      break;
    }
  }
}

void loop() 
{
}
//-------------------------------------------------random assignement function
void randAssignment()
{
  for (int makeLetter=0;makeLetter<LSIZE;makeLetter++)
  {
    int data=random(1, 32760);
    layout[makeLetter]=data;
    Serial.print(char(makeLetter+ALPHA));
    Serial.print("==");
    Serial.println(data);
    delay(30);
  }
  EEPROM.updateBlock<int>(alphaAddress, layout, LSIZE);
}
//----------------------------------------------layout checking function
char checkEX(int chordvalue)
{
  EEPROM.readBlock<int>(alphaAddress, layout, LSIZE);
  for(int i=0;i<LSIZE;i++)
  {
    if(layout[i]==chordvalue)
    {
      char letteR=char(i+ALPHA);
      return letteR;
      //adds 97 and coverts to its corresponding letter
    }
  }
  return 0;
}


//-----------------------------check for persistent key
boolean beenHere(int address, byte code)
{
  //establishes if source has been run on uploaded to unit with a key/code
  byte potentialCode=EEPROM.read(address);
  if(code==potentialCode){
    return true;
  }
  else
  {
    return false;
  };
}

That will do what I want till checkEX(); is called too many times (over 33,000). Which may happen in the program that the function is intended for.
I'm not at point where I'm skilled enough to modify the library yet, do you think I should have a go at it anyway?
Should I contact the maintainer or do you think what I'm doing beyond the libraries intention?
maybe there is a more effective way to do this? Keep in mind checkEX is all I need to merge in into the main program
There will be an assignment function but it will only do one letter at a time when the user prompts so randAssignment will be depreciated

Do you know why you're using that library to access EEPROM at all?

PeterH:
Do you know why you're using that library to access EEPROM at all?

I'm willing to try others, if you have recommendations. I need persistent storage of an int array, I'm building something like a chorded keyer. The "chords" produce values that need to be assigned to letters. I tried to compress the values to with in the size of a byte to use the standard library this reduces the differences between chord values though and limits my options, so I would like to store the values as ints.

Maybe your suggesting that I implement what the library does within my program?
I'm thinking about that at this point... but I was hoping not to have to reinvent the wheel, I just started programming..
I'll do what I have to though, so what will be will be.

honestly, I would like to store a larger persistent and accessible array without needing to have it in ram at all as I'll need all the memory I can get. I can only store the values of 26 letters in the way shown and if I make the array bigger then that, things crash.

maybe I'll just convert the address values of stored ints to letters...
just seems too much like the fiasco I had with the standard library

The question is why do you need to store the data in EEPROM, instead of, say an SD card?

I can only store the values of 26 letters in the way shown and if I make the array bigger then that, things crash.

You have 2048 bytes of RAM.

I'm confused as to why you can't store 26 letters in that space.

It would be a good idea for you to describe the data you're trying to persist more clearly.

Is it all predefined and constant, or will it be modified at runtime? How much data is there? What is the structure? How is it accessed? How will it be modified?