Teensy LC EEPROM overwrites memory on power cycle?

Status
Not open for further replies.

JeppeRas

Member
As the title says, I'm having trouble with the EEPROM on a Teensy LC.
After much browsing of this forum, I am still unable to resolve my problem.

The project is a sketch which contains a series of MIDI instruments, which can be selected via jumpers on a breakout. The data that I want to save to EEPROM is calibration data for all the instrument sensors. I have a "saveSettings()" function which can be called from the sketch to save the current calibration, and a "loadSettings()" function which runs on every setup(). My actual instrument sketch is quite big and complex, so here I have reduced it to just the EEPROM stuff, with all the "calibration" data hard coded. This sketch still produces the same problem.
"SaveSettings()" seems to be working, as far as I can tell, but when I unplug and plug back in the "loadSettings()" function outputs a completely different set of values.

Code:
#include <EEPROM.h>


// SENSORS:
int aPinMin[11] = {200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200};
int aPinCent[11] = {300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300};
int aPinMax[11] = {400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400};

int touchPinMin[11] = {500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500};
int touchPinMax[11] = {1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000};

int mux1Min[16] = {50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50};
int mux1Max[16] = {90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90};

int mux2Min[16] = {100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100};
int mux2Max[16] = {150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150};


//----------------- LOAD ALL VARIABLES FROM MEMORY ------------------ //

int address;
int tempValue;


int firstTime = 1;


void loadSettings(){
  int i;
  address = 0;

  Serial.println("Now reading settings from memory:");  
  Serial.println();
  
  Serial.println("Analog sensors:");
  // Analog pin minimum readings:
  for (i = 0; i < 11; i++) {
    EEPROM.get(address, tempValue);
    Serial.print(address);
    Serial.print(": ");
    Serial.println(tempValue);
    address += 2;
  }
  Serial.println();
  // Analog pin center readings:
  for (i = 0; i < 11; i++) {
    EEPROM.get(address, tempValue);
    Serial.print(address);
    Serial.print(": ");
    Serial.println(tempValue);
    address += 2;
  }
  Serial.println();
  // Analog pin maximum readings:
  for (i = 0; i < 11; i++) {
    EEPROM.get(address, tempValue);
    Serial.print(address);
    Serial.print(": ");
    Serial.println(tempValue);
    address += 2;
  }
  Serial.println();
  Serial.println();
  
  Serial.println("Touch sensors:");
  // Touch pin minimum readings:
  for (i = 0; i < 11; i++) {
    EEPROM.get(address, tempValue);
    Serial.print(address);
    Serial.print(": ");
    Serial.println(tempValue);
    address += 2;
  }
  // (No touch pin center readings)
  
  Serial.println();
  // Touch pin maximum readings:
  for (i = 0; i < 11; i++) {
    EEPROM.get(address, tempValue);
    Serial.print(address);
    Serial.print(": ");
    Serial.println(tempValue);
    address += 2;
  }
  Serial.println();
  Serial.println();
  
  Serial.println("Multiplexers:");
  
  // Multiplexer 1 minimum readings:
  for (i = 0; i < 16; i++) {
    EEPROM.get(address, tempValue);
    Serial.print(address);
    Serial.print(": ");
    Serial.println(tempValue);
    address += 2;
  }
  Serial.println();
  // Multiplexer 1 maximum readings:
  for (i = 0; i < 16; i++) {
    EEPROM.get(address, tempValue);
    Serial.print(address);
    Serial.print(": ");
    Serial.println(tempValue);
    address += 2;
  }
  Serial.println();
  // Multiplexer 2 minimum readings:
  for (i = 0; i < 16; i++) {
    EEPROM.get(address, tempValue);
    Serial.print(address);
    Serial.print(": ");
    Serial.println(tempValue);
    address += 2;
  }
  Serial.println();
  // Multiplexer 2 maximum readings:
  for (i = 0; i < 16; i++) {
    EEPROM.get(address, tempValue);
    Serial.print(address);
    Serial.print(": ");
    Serial.println(tempValue);
    address += 2;
  }
  Serial.println();
  Serial.println("Finished loading settings:");  
  Serial.println();
  Serial.println();
}



//----------------- SAVE ALL VARIABLES TO MEMORY ------------------ //

void saveSettings(){
  int i;
  address = 0;
  Serial.println("Now saving settings, then loading and printing:");  
  Serial.println();
    
  Serial.println("Analog sensors:");
  // Analog pin minimum readings:
  for (i = 0; i < 11; i++) {
    EEPROM.put(address, aPinMin[i]);
    EEPROM.get(address, tempValue);
    Serial.print(address);
    Serial.print(": ");
    Serial.println(tempValue);
    address += 2;
  }
  Serial.println();
  // Analog pin center readings:
  for (i = 0; i < 11; i++) {
    EEPROM.put(address, aPinCent[i]);
    EEPROM.get(address, tempValue);
    Serial.print(address);
    Serial.print(": ");
    Serial.println(tempValue);
    address += 2;
  }
  Serial.println();
  // Analog pin maximum readings:
  for (i = 0; i < 11; i++) {
    EEPROM.put(address, aPinMax[i]);
    EEPROM.get(address, tempValue);
    Serial.print(address);
    Serial.print(": ");
    Serial.println(tempValue);
    address += 2;
  }
  Serial.println();
  Serial.println();

  Serial.println("Touch sensors:");
  // Touch pin minimum readings:
  for (i = 0; i < 11; i++) {
    EEPROM.put(address, touchPinMin[i]);
    EEPROM.get(address, tempValue);
    Serial.print(address);
    Serial.print(": ");
    Serial.println(tempValue);
    address += 2;
  }
  // (No touch pin center readings)
  Serial.println();
  // Touch pin maximum readings:
  for (i = 0; i < 11; i++) {
    EEPROM.put(address, touchPinMax[i]);
    EEPROM.get(address, tempValue);
    Serial.print(address);
    Serial.print(": ");
    Serial.println(tempValue);
    address += 2;
  }
  Serial.println();
  Serial.println();

  Serial.println("Multiplexers:");
  // Multiplexer 1 minimum readings:
  for (i = 0; i < 16; i++) {
    EEPROM.put(address, mux1Min[i]);
    EEPROM.get(address, tempValue);
    Serial.print(address);
    Serial.print(": ");
    Serial.println(tempValue);
    address += 2;
  }
  Serial.println();
  // Multiplexer 1 maximum readings:
  for (i = 0; i < 16; i++) {
    EEPROM.put(address, mux1Max[i]);
    EEPROM.get(address, tempValue);
    Serial.print(address);
    Serial.print(": ");
    Serial.println(tempValue);
    address += 2;
  }
  Serial.println();
  // Multiplexer 2 minimum readings:
  for (i = 0; i < 16; i++) {
    EEPROM.put(address, mux2Min[i]);
    EEPROM.get(address, tempValue);
    Serial.print(address);
    Serial.print(": ");
    Serial.println(tempValue);
    address += 2;
  }
  Serial.println();
  // Multiplexer 2 maximum readings:
  for (i = 0; i < 16; i++) {
    EEPROM.put(address, mux2Max[i]);
    EEPROM.get(address, tempValue);
    Serial.print(address);
    Serial.print(": ");
    Serial.println(tempValue);
    address += 2;
  }
}

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

  delay(1000);
  loadSettings();
  
}

void loop() {
  if(firstTime == 1){
    saveSettings();
    firstTime = 0;
  }
}

Here's the Serial output from the "saveSettings()" function:
Code:
Now saving settings, then loading and printing:

Analog sensors:
0: 200
2: 200
4: 200
6: 200
8: 200
10: 200
12: 200
14: 200
16: 200
18: 200
20: 200

22: 300
24: 300
26: 300
28: 300
30: 300
32: 300
34: 300
36: 300
38: 300
40: 300
42: 300

44: 400
46: 400
48: 400
50: 400
52: 400
54: 400
56: 400
58: 400
60: 400
62: 400
64: 400


Touch sensors:
66: 500
68: 500
70: 500
72: 500
74: 500
76: 500
78: 500
80: 500
82: 500
84: 500
86: 500

88: 1000
90: 1000
92: 1000
94: 1000
96: 1000
98: 1000
100: 1000
102: 1000
104: 1000
106: 1000
108: 1000


Multiplexers:
110: 50
112: 50
114: 50
116: 50
118: 50
120: 50
122: 50
124: 50
126: 50
128: 50
130: 50
132: 50
134: 50
136: 50
138: 50
140: 50

142: 90
144: 90
146: 90
148: 90
150: 90
152: 90
154: 90
156: 90
158: 90
160: 90
162: 90
164: 90
166: 90
168: 90
170: 90
172: 90

174: 100
176: 100
178: 100
180: 100
182: 100
184: 100
186: 100
188: 100
190: 100
192: 100
194: 100
196: 100
198: 100
200: 100
202: 100
204: 100

206: 150
208: 150
210: 150
212: 150
214: 150
216: 150
218: 150
220: 150
222: 150
224: 150
226: 150
228: 150
230: 150
232: 150
234: 150
236: 150
This function saves the values, and then reads each of them again from memory using the same approach as the "loadSettings()" part. Still, it seems to work fine.

But then here is the output from the actual "loadSettings()" on restart:
Code:
Now reading settings from memory:

Analog sensors:
0: 13107200
2: 9437384
4: 13107344
6: 200
8: 13107200
10: 13107400
12: 13107400
14: 9437384
16: 13107344
18: 9437384
20: 19660944

22: 9437484
24: 19660944
26: 19661100
28: 19661100
30: 2359596
32: 19660836
34: 2359596
36: 19660836
38: 19661100
40: 19661100
42: 26214700

44: 26214800
46: 26214800
48: 26214800
50: 26214800
52: 26214800
54: 26214800
56: 26214800
58: 26214800
60: 26214800
62: 9699728
64: 32768148


Touch sensors:
66: 500
68: 32768000
70: 9699828
72: 32768148
74: 32768500
76: 32768500
78: 32768500
80: 32768500
82: 32768500
84: 32768500
86: 65536500

88: 65537000
90: 65537000
92: 65537000
94: 65537000
96: 65537000
98: 65537000
100: 65537000
102: 65537000
104: 65537000
106: 65537000
108: 3277800


Multiplexers:
110: 3276850
112: 3276850
114: 3276850
116: 3276850
118: 3276850
120: 3276850
122: 3276850
124: 3276850
126: 3276850
128: 3276850
130: 3276850
132: 3276850
134: 3276850
136: 3276850
138: 3276850
140: 5898290

142: 5898330
144: 5898330
146: 5898330
148: 5898330
150: 5898330
152: 5898330
154: 5898330
156: 5898330
158: 5898330
160: 5898330
162: 5898330
164: 5898330
166: 5898330
168: 5898330
170: 5898330
172: 6553690

174: 6553700
176: 6553700
178: 6553700
180: 6553700
182: 6553700
184: 6553700
186: 6553700
188: 6553700
190: 6553700
192: 6553700
194: 6553700
196: 6553700
198: 6553700
200: 6553700
202: 6553700
204: 9830500

206: 9830550
208: 9830550
210: 9830550
212: 9830550
214: 9830550
216: 9830550
218: 9830550
220: 9830550
222: 9830550
224: 9830550
226: 9830550
228: 9830550
230: 9830550
232: 9830550
234: 9830550
236: 150

Finished loading settings:


All the values are ints, so my address management consists in just counting up by 2 after each value is saved. As I need about 240 bytes of memory for this project, I have edited "eeprom.h" as recommended by Paul Stoffregen here: https://forum.pjrc.com/threads/34537-Teensy-LC-Increase-EEPROM-Size/page2 , so that means changing the "0X7F" for "0xFE". If you want to test it, you'll probably have to do the same.
This is what I mean:
Code:
#if defined(__MK20DX128__) || defined(__MK20DX256__)
  #define E2END 0x7FF
#elif defined(__MK64FX512__) || defined(__MK66FX1M0__)
  #define E2END 0xFFF
#elif defined(__MKL26Z64__)
  #define E2END 0xFE
#else
  #define E2END 0
#endif

As usual, I have a sneaking suspicion that I'm just making some stupid obvious mistake, but I've been banging my head against this for days, so I really hope someone can help. Please let me know if you need any further info.
Thanks!
 
Last edited:
A couple of things I would check:
a) make sure you are not overusing memory... In particular, the internal function eeprom_write_byte has a stack variable:
uint8_t buf[EEPROM_SIZE];
So doubling the size how much EEPROM will update how much stack space is needed.
@Paul - Side note: wonder about:
Code:
	uint16_t do_flash_cmd[] = {
		0x2380, 0x7003, 0x7803, 0xb25b, 0x2b00, 0xdafb, 0x4770};
Maybe these should be static const....

b) You are reading and writing things using 2 bytes, so I assume 16 bit integers... Yet you are reading them into and writing from the generic integer type (int), which is likely in this case to be 32 bits.

What happens if you change your code to use: int16_t if you need signed or uint16_t for unsigned?
 
b) You are reading and writing things using 2 bytes, so I assume 16 bit integers... Yet you are reading them into and writing from the generic integer type (int), which is likely in this case to be 32 bits.

What happens if you change your code to use: int16_t if you need signed or uint16_t for unsigned?

Yes! That was it.
That confirms my suspicion that I was indeed being quite stupid.
Thank you so much @KurtE, you made my day!
 
Status
Not open for further replies.
Back
Top