Pages: 1 2 [3]   Go Down
Author Topic: EEPROMex "Exceeded maximum number of writes"  (Read 3472 times)
0 Members and 1 Guest are viewing this topic.
Manchester NH
Offline Offline
Full Member
***
Karma: 1
Posts: 132
Like to build typing devices, and heard unicorns
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
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:
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++)
    {
      if(letterNum==i+96)
      {
        int address=i*2-1;
        int lastValue=EEPROM.readInt(address, chordValue);
        EEPROM.writeInt(address);
        return lastValue;
      }
    }
  }
  if(letterNum>64 && letterNum<59)
  {
    address=;
  }
}
Wondering if this is possible with out the for loop, gathering the address from an equation?
Logged

UK
Offline Offline
Shannon Member
****
Karma: 223
Posts: 12630
-
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
// 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:
// 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.
Logged

I only provide help via the forum - please do not contact me for private consultancy.

Manchester NH
Offline Offline
Full Member
***
Karma: 1
Posts: 132
Like to build typing devices, and heard unicorns
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
word(byte, byte);//syntax is kind quirky for what it seems to do
//can it handle other variable types?
highByte(int);
lowByte(int);
Now I do,.. learn something new everyday smiley-grin

Thank you Peter, for taking the time to draft that out.
« Last Edit: January 31, 2013, 04:03:27 pm by Paul Beaudet » Logged

Manchester NH
Offline Offline
Full Member
***
Karma: 1
Posts: 132
Like to build typing devices, and heard unicorns
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
/*eepromtest
 *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()
{
  Serial.begin(9600);
 
  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
  {
    clearPROM(0,254);
    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(chord);
      Serial.print(F(" and its value is equal to-> "));
      Serial.println(char(letteR));
    }
    //else{Serial.print(letteR);};
  }
}

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(storedVal>0)
  {
    if (letter>96 && letter<123)
    {
      modifier=-95;
    }
    storedVal=word(EEPROM.read(letter*2+modifier), EEPROM.read(letter*2+1+modifier));
  }
  EEPROM.write(letter*2+modifier, highByte(chordValue));
  delay(5);
  EEPROM.write(letter*2+1+modifier, lowByte(chordValue));
  delay(5);
  return storedVal;
}

//Checking

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)
    {
      if(address>65)
      {
        letter=address/2;//luckly we are just dealing with even numbers
        return letter;
      }
      if(address<65)
      //synonymous chords
      {
        letter=address/2+95;
        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(data);
    Serial.print(F(" was assigned to "));
    Serial.println(makeLetterChar);
  }
  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);
  if(code==potentialCode){
    return false;
  }
  else{return true;};
}

//--------------------clear EEPROM
void clearPROM(int start, int finish)
{
  for(int i=start;i<finish;i++)
  {
    EEPROM.write(i,0);
    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
Logged

Pages: 1 2 [3]   Go Up
Jump to: