Go Down

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

PeterH


do you think I should have a go at it anyway?


Do you know why you're using that library to access EEPROM at all?
I only provide help via the forum - please do not contact me for private consultancy.

Paul Beaudet


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

PaulS

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

Nick Gammon

Quote
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.
Please post technical questions on the forum, not by personal message. Thanks!

More info:
http://www.gammon.com.au/electronics

PeterH


I need persistent storage of an int array


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?
I only provide help via the forum - please do not contact me for private consultancy.

Paul Beaudet


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


I have got the shield, and have run a couple of the example sketches. I just need to spend some more time with it. I'll likely need it for another part of the program I may or may not be able to implement. I'm a little concerned about the speeds but I'll need to do some testing to see if those concerns are valid.

If have come across detailed tutorials for using sd, I would love to see. What I breezed over in the playground left me a little blurry. Maybe I'll take a closer look latter today.


You have 2048 bytes of RAM.

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

26 is fine, maybe even 52 would be fine (adding capital letters). It is adding numbers, symbols, synonymous chord values and then combining this with the main program body where memory usage is going to get hairy. 

I should have disclaimed that the crashes I got were with arrays of 128 ints which are much bigger not just a little. I really thought with 2k of ram the arduino would have been able to even handle that, but apparently there is a bit of over head and with the bits and bobs of my example program, it choked.(what little serial debugging I was doing stopped midway and could get further depending on array size)  Could have been my code, however If things were getting hairy in an example/test program I would expect there to be issues with much more code to be added, so since then I've become conscious of memory usage.


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?


I guess the gotcha to this whole thing is that the data needs to be modified during run time. The main body of code "guesses" what letter the user is trying to type and assigns it. It needs to interpret the chord, make the "educational guess" and the assign the chord with in at least a 50ms time window to be responsive (as far as I understand, might be more or less wiggle room)

I'm fairly new to programming so structure and access are all experimental to me. An int array seems like a good middle of the road approach since using a struct is too much. As far as access goes I'm just using for loops to iterate through the data till I find what I want.
There are probably better strategies for doing this I'm just not aware yet.

Nick Gammon

If you are running out of RAM, there are techniques, such as putting string literals into PROGMEM. That can save quite a bit.
Please post technical questions on the forum, not by personal message. Thanks!

More info:
http://www.gammon.com.au/electronics

PeterH


I guess the gotcha to this whole thing is that the data needs to be modified during run time. The main body of code "guesses" what letter the user is trying to type and assigns it. It needs to interpret the chord, make the "educational guess" and the assign the chord with in at least a 50ms time window to be responsive (as far as I understand, might be more or less wiggle room)


I have no idea how you're doing that - are you using some sort of lookup table, or something?

Assume I have no idea what your sketch does - what's the structure of your data, how is it accessed and which parts of it are modified at runtime?
I only provide help via the forum - please do not contact me for private consultancy.

Paul Beaudet


I have no idea how you're doing that - are you using some sort of lookup table, or something?

Assume I have no idea what your sketch does - what's the structure of your data, how is it accessed and which parts of it are modified at runtime?


the "guess" right now, isn't vary intelligent yet. Currently just a for loop that goes through unassigned letters (i.e. chordValue==0) alphabetically, then it prints the letter and assigns the value it was tested against (the chordValue coming from the user). This is the write during run time and it need to be keep persistently unless the user deletes that letter which signals that the letter was unwanted for that assignment in which case it goes back to zero. Representing another write situation during runtime

i would post code but its really too messy for anyone to make sense of yet.

PeterH

So it sounds like you have a 'letter' identifying the chord which is assigned by choosing the first unassigned letter when the chord is first encountered, and a 'chordValue' which somehow specifies the chord. What data type is 'chordValue'?
I only provide help via the forum - please do not contact me for private consultancy.

Paul Beaudet


So it sounds like you have a 'letter' identifying the chord which is assigned by choosing the first unassigned letter when the chord is first encountered, and a 'chordValue' which somehow specifies the chord. What data type is 'chordValue'?


an int, I tried a byte which should have theoretically been sufficient but it proved difficult.
I had to divide the unique value aka chordValue that the user created to fit into a 255 value range. The removing of the fractional value along the way, made me account for slight discrepancy thus reducing the value space of a byte by around a third. 
I need to rewrite how the chordValue is derived to make the necessary action feel more consistent to the user, so what the values will be are still up in the air, but I think its safe to say at this point that its out of the range of a byte and within the range of an int.

I think ive come up with away to check the value without making an array.
Code: [Select]
char checkAlt(int chordValue, int modifier)//untested
{
  int startAddress;
  int endAddress;
  if (modifier==96)
  //lower case letters
  {
    startAddress=1;
    endAddress=27;
  }
  if (modifier==38)
  //Capital letters
  {
    startAddress=27;
    endAddress=53;
  }
  //add more modifier definitions here, for symbols
  for(int i=startAddress;i>endAddress;i++)
  {
    int address=i*2-1;
    //this should assure a unique address for an int, given values are correct
    //probably could have incremented by 2, but the same vars would still need definitions
    int tempChord=EEPROM.readInt(address);
    if(tempChord==chordValue)
    {
      lastLetter=char(i+modifier);
      return lastLetter;
    }
  }
}

Still doesn't negate the "maximum write" problem, in fact It could make it worst, but it does take care of the issue of size. I just need to write an assignment function now.


If you are running out of RAM, there are techniques, such as putting string literals into PROGMEM. That can save quite a bit.

I'm going to have to look into it more, but since I'm modifying so many of the variables during run time its hard for me to see where to use progmem yet, A quick example with some of the code I've be throwing around would be great
the only string literals i can think are the debugging messages at the moment.. am I being too narrow?

wait a sec... are the debug messages in the library being loaded into ram?... That would explain the crashes..

Nick Gammon

Debug messages are loaded into RAM, yes, which is why I suggested it.

Change:

Code: [Select]
Serial.print ("Debugging point foo");

to:

Code: [Select]
Serial.print (F("Debugging point foo"));
Please post technical questions on the forum, not by personal message. Thanks!

More info:
http://www.gammon.com.au/electronics

Paul Beaudet

#27
Jan 30, 2013, 10:28 pm Last Edit: Jan 30, 2013, 10:30 pm by Paul Beaudet Reason: 1

Code: [Select]
Serial.print (F("Debugging point foo"));


Awesome! Simple, just like me  XD

I'm assume this is necessary also right? Or is that function integrated in the main library/resources?
Code: [Select]
#include <avr/pgmspace.h>
will I be able to modify the library in the same way?

Nick Gammon

Quote
I'm assume this is necessary also right?


No.

Quote
will I be able to modify the library in the same way?


Try it and see.
Please post technical questions on the forum, not by personal message. Thanks!

More info:
http://www.gammon.com.au/electronics

PeterH

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.

If you want to associate each chord with a letter then I'd add 'a' to the chord index to get the chord letter (so 'a' becomes 0, 'b' becomes 1 and so on). I guess that when you encounter a chord you would first check against the existing known chord, and if none matched you'd allocate the next available index and store the chord value in it.

It would be easy enough to access the chord values in EEPROM by providing read and write access functions that handled the translation between the int array your application is dealing with, and the byte array that the EEPROM interface presents.
I only provide help via the forum - please do not contact me for private consultancy.

Go Up