Store/Retrieve Radio Presets in EEPROM (Trying)

Greetings, Forum! Newbie Willie here, again. :)

I've done a LOT of searching the Forum, reading the EEPROM tutorials, etc, and I'm struggling to find anything I can USE to implement a very simple system of storing/retrieving, say, eight "presets" for a radio project I'm working on.

The idea would be an array to store 8 AM and 8 FM frequencies as unsigned 16 bit integers.

I've looked at and tried examples from the EEPROMex.h library, and can only find bytes, bits, long, and double... but not Integer. Working with the EEPROM shouldn't be so confusing!

I also want to have the radio "remember" the last station it was tuned to so that when powered-up, it comes back to it. (That would be array position 0.)

It's working perfectly as a manually-tuned radio right now, with a nice LCD display and three buttons to control it. (Tune up, Tune down, and AM/FM mode) It powers-up to a hard-coded FM station.

9000 character limit, so I can't post the code! :( Also, WHY does the 5 minute limit hinder EDITING POSTS with the EDIT link? Can that be fixed by the Forum moderators? PLEASE? :)

You don’t need to post the whole project for this. Easier to just try to make a test sketch just for the EEPROM part would do.

So you want to store 16 int’s and a last selected freqency? With put() and get() you can save every varaible type you want in EEPROM. So an int isn’t a problem. But you need to do that for each array element.

const byte EepromLastFreqency = 0;  //location of last used frequency in EEPROM. A int uses two bytes!
const byte EepromFreqencies = 2;     //location of start array of frequencies. start @ 2 because an int uses two bytes

unsigned int lastFreqency = 1234;
unsigned int presetFreqencies[16];


//to store
EEPROM.put(EepromLastFreqency, lastFreqency);
//loop over every preset
for(byte i = 0; i < sizeof(presetFreqencies)/sizeof(presetFreqencies[0]); i++){
  //and store each starting at EepromFreqencies 
  //and increment by the number of bytes a singe preset takes (sizeof(presetFreqencies[0]), here 2 because of int
  EEPROM.put(EepromFreqencies + i * sizeof(presetFreqencies[0]), presetFreqencies[i]);
}

//and to retrieve, just do the opposite with get()
EEPROM.get(EepromLastFreqency, lastFreqency);
//loop over every preset
for(byte i = 0; i < sizeof(presetFreqencies)/sizeof(presetFreqencies[0]); i++){
  //and store each starting at EepromFreqencies 
  //and increment by the number of bytes a singe preset takes (sizeof(presetFreqencies[0]), here 2 because of int
  EEPROM.get(EepromFreqencies + i * sizeof(presetFreqencies[0]), presetFreqencies[i]);
}

Can that be done-away with by the Forum moderators? PLEASE?

No, certainly not - we fought hard to get the brake put in place.

I've looked at and tried examples from the EEPROMex.h library, and can only find bytes, bits, long,

I'm a little surprised to find "bits" in that list, but the others are, of course, integer datatypes, so I'm struggling to see the problem here.

Willie—:
Greetings, Forum! Newbie Willie here, again. :slight_smile:

I’ve done a LOT of searching the Forum, reading the EEPROM tutorials, etc, and I’m struggling to find anything I can USE to implement a very simple system of storing/retrieving, say, eight “presets” for a radio project I’m working on.

The idea would be an array to store 8 AM and 8 FM frequencies as unsigned 16 bit integers.

Look at this example:

#include <avr/eeprom.h>

// FM channel storage slots
static const uint16_t fm_channels[] EEMEM = {
    0, 0, 0, 0, 0, 0, 0, 0
};

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

    char buffer [64]; // buffer is just for printing
    uint8_t idx;
    uint8_t array_len;
    uint16_t channel;

    array_len = (sizeof (fm_channels) / sizeof (*fm_channels)); // get # of entries in array

    // write some values to the EEPROM
    eeprom_write_word ((uint16_t *)(fm_channels) + 0, 1041); // stored 104.1 as uint16_t
    eeprom_write_word ((uint16_t *)(fm_channels) + 3, 1033); // stored 103.3 as uint16_t
    eeprom_write_word ((uint16_t *)(fm_channels) + 5,  989); // stored  98.9 as uint16_t

    // display all (non-updated show as zero of course)
    for (idx = 0; idx < array_len; idx++) {
        channel = eeprom_read_word (fm_channels + idx);
        sprintf (buffer, "Entry #%u in the eeprom is %u\r\n", idx, channel);
        Serial.print (buffer);
    }
}

void loop (void)
{
    // nothing
}

This should be enough to get you going (and doing it the way it was intended to be done - not using that “EEPROM.h” abomination).

You don’t need to remember how many bytes a uint16_t takes, nor do you need to remember what eeprom address stuff is stored in.

“fm_channels + slot_number” is all you need to access the saved data.

See?

(edit to add): Some versions of the bootloader (Optiboot in the UNO, for example), do not write eeprom data to the Arduino even though you define it and a “.eep” file is generated. In this case, eeprom values will initially read back as 0xFFFF (or 65535 decimal) but you can still write to them as shown in the example above.

First, THANK YOU to those who have replied! (Septillion & Krupski) Interesting ideas, and I will begin experimenting with each one.

Reply to “AWOL” about “the brake”… why does it kick in when using the EDIT link, though? I understand slowing down a SPAMMER posting in rapid-fire, and I’m all for that… but when I post, then notice an error, and try to fix it, I have to wait 5 minutes? That’s what I was talking about fixing. :slight_smile:

Reply to “Krupski” - Why is EEPROM.h an abomination? What about EEPROMex.h? (That is the library I’m actually trying to use.) Everything I’m researching here on this excellent forum, refers to either of those two libraries… so if they are so awful, perhaps some new articles should be written/posted, and those removed (or deprecated) so that noobs like me won’t stumble into this mess. :wink:

Reply to “Septillion” - I presume you have included either the EEPROM.h library (or the EEPROMex.h) in order to use “get()” and “put()”?

To all: I also want to have the functionality that prevents re-writing “same data” into the memory cells, which EEPROMex.h is supposed to support with the “update” command… but I couldn’t seem to make that work. :frowning:

So change "eeprom_write_word" from Krupski's sample into "eeprom_update_word". The avr/eeprom library already has that functionality.

Also of interest to you may be this Application Note from Atmel that explains how to use a “ring buffer” to extend the life of your EEPROM by using more of it. If you are not using the full space of the EEPROM, you can spread your writes over it by alternating which location you use.

It’s one of my favorite App Notes because it’s so short but also well written and useful.

AVR101 - High Endurance EEPROM Storage.pdf (47.3 KB)

Quick note to "Krupski" - I just started by testing the compile, using avr/eeprom.h instead of EEPROMex.h and noticed it compiles about 800 bytes smaller! That's interesting! Obviously, this is a more efficient library! (I haven't started on the actual code yet.) Thanks just for that, alone. :)

Ah, and thanks also to "Jiggy-Ninja" for pointing out that the update function is supported in this library. :) Yes, the "ring buffer" also sounds interesting... and when I get the foundation working, I'll look into adding that as well. Remember, I'm still a Noob at this. :) I'm only into it up to my ankles at this point... I've learned enough C++ to do a few simple things, but I know there's still a LONG way yet to go. ;)

To those who celebrate, HAPPY THANKSGIVING! :)

OK, a little tweaking has occurred. :slight_smile: Looks like the read/write to EEPROM has been successful.

Krupski, I’ve modded your code as follows, because I also want to store 8 AM frequencies. (Did I do this right? It compiles and runs as written here.)

I’ve also renamed the variables:

// Testing radio preset EEPROM code, V0.1

#include <avr/eeprom.h> //Extended EEPROM library 

// FM channel storage slots (Valid stations. Blanks=87.9)
static const uint16_t FMPreset[] EEMEM = {
    967, 1049, 1069, 1073, 879, 879, 879, 879 };
// AM channel storage slots (All valid stations)
static const uint16_t AMPreset[] EEMEM = {
    57, 60, 66, 77, 88, 130, 150, 167 };

void setup (void)
{
    Serial.begin (9600); // 9600 is plenty for this.

    char buffer [64]; // buffer is just for printing
    uint8_t idx;
    uint8_t array_len;
    uint16_t channel;

    array_len = (sizeof (FMPreset) / sizeof (*FMPreset)); // get # of entries in array

    // write some values to the EEPROM
    eeprom_update_word ((uint16_t *)(FMPreset) + 0, 1049); // stored 104.9 as uint16_t (Valid station #1)
    eeprom_update_word ((uint16_t *)(FMPreset) + 3, 1069); // stored 106.9 as uint16_t (Valid station #2)
    eeprom_update_word ((uint16_t *)(FMPreset) + 5, 1073); // stored 107.3 as uint16_t (Valid station #3)

    // display all (non-updated show as 65535)
    for (idx = 0; idx < array_len; idx++) {
        channel = eeprom_read_word (FMPreset + idx);
        sprintf (buffer, "Entry #%u in the eeprom is %u\r\n", idx, channel);
        Serial.print (buffer);
    }
}

void loop() {
  // put your main code here, to run repeatedly:

}

Here is what the terminal shows, which is as expected.

Entry #0 in the eeprom is 1049
Entry #1 in the eeprom is 65535
Entry #2 in the eeprom is 65535
Entry #3 in the eeprom is 1069
Entry #4 in the eeprom is 65535
Entry #5 in the eeprom is 1073
Entry #6 in the eeprom is 65535
Entry #7 in the eeprom is 65535

What I’d like for this to do, is access/store each memory slot only upon command. (Think of how a car radio works… you set a station, then press and hold the button to “lock it in”.) In this case, I would select a memory slot, then store the currently tuned station into it, using “slots” 1 through 8 for each band.

The special exception would be the two zero slots, one for AM one for FM. That frequency would “auto-store” after about one second of the tune buttons being released. These “slots” would then be read at power-up. (If invalid, then default to 87.9 and 540)

Jiggy-Ninja: So change "eeprom_write_word" from Krupski's sample into "eeprom_update_word". The avr/eeprom library already has that functionality.

That's a good idea. I should have used that option in my demo. Thanks for pointing it out.

In order to program an EEPROM byte, it first has to be erased to all 1's (i.e. 0xFF). But, if the NEW data to be placed in an EEPROM byte merely consists of more 0 bits, then those can be programmed WITHOUT the need to first erase the location which slightly reduces the wear on the EEPROM cells (look up "Fowler-Nordheim Electron Tunneling" to understand how and why EEPROM (and FLASH) memory has a limited number of erase and/or write cycles).

Willie---: Krupski, I've modded your code as follows, because I also want to store 8 AM frequencies. (Did I do this right? It compiles and runs as written here.)

The code I posted was merely an example. Of course you can modify it as you wish. You can also add another array to store AM radio channels, and (as you did) also pre-define channels (rather than starting out with 0).

The reason I showed how to update a default table (rather than pre-defining values) was that the Arduino UNO bootloader does not support EEPROM writes (so your pre-defined values would not be programmed in).

Also, certain older bootloaders for the MEGA2560 board have a bug in the EEPROM write code that puts data in the wrong addresses, so pre-defined values would not read back correctly.

I didn't know which board you were using, so I decided to leave out pre-defined values (imagine if you tried the example and it didn't work... how would you know what went wrong?).

Willie---: Here is what the terminal shows, which is as expected.

Entry #0 in the eeprom is 1049
Entry #1 in the eeprom is 65535
Entry #2 in the eeprom is 65535
Entry #3 in the eeprom is 1069
Entry #4 in the eeprom is 65535
Entry #5 in the eeprom is 1073
Entry #6 in the eeprom is 65535
Entry #7 in the eeprom is 65535

You EXPECTED that to happen? Notice that you pre-defined all 8 slots, yet only the ones you write programmatically showed up. The rest are 65535 (which is 0xFFFF - in other words erased EEPROM).

From what I see, you are using an UNO (or at least a board with the Optiboot bootloader) because your pre-defined values DID NOT get sent to the EEPROM!

What you should have EXPECTED is for all 8 slots to have valid values (the ones you pre-defined, as updated by the ones you programmatically wrote).

No problem though... you can simply have your code check for the array to have 65535 (0xFFFF) values and if so, assume they are "new" and program them within your sketch with default values.

The next time you power up the board, the default values will be there and your sketch won't re-define them. If you re-upload a new version of the sketch, the locations will once again be "new" (that is, 65535) and you can set them to the default values again programmatically.

Got it?

Jiggy-Ninja: Also of interest to you may be this Application Note from Atmel that explains how to use a "ring buffer" to extend the life of your EEPROM by using more of it. If you are not using the full space of the EEPROM, you can spread your writes over it by alternating which location you use.

It's one of my favorite App Notes because it's so short but also well written and useful.

Thanks for posting this link Jiggy! I've been ... going around in circles myself, tying to come up with a scheme to distribute the EEPROM writes so my devices will last longer. This is just the document (and explanation) I needed!

Hi, Krupski - Yes, "As expected" in that I have not yet implemented a means to write those arrays into the EEPROM. So is the EEMEM variable you used, supposed to place those values into the EEPROM, but the bootloader doesn't handle that? I may as well remove that code, then... I'm still too much of a Noob to even THINK of tinkering with the bootloader! (I don't want to risk bricking anything.)

I only used your three lines with the update instruction, thus:

 // write some values to the EEPROM
    eeprom_update_word ((uint16_t *)(FMPreset) + 0, 1049); // stored 104.9 as uint16_t (Valid station #1)
    eeprom_update_word ((uint16_t *)(FMPreset) + 3, 1069); // stored 106.9 as uint16_t (Valid station #2)
    eeprom_update_word ((uint16_t *)(FMPreset) + 5, 1073); // stored 107.3 as uint16_t (Valid station #3)

That's why I only EXPECTED to see those three values actually stored into the EEPROM. :) I understand, now, how I confused you, and I'm sorry I didn't make that clearer.

BTW, I am using a "Pro Mini" board. (Similar to UNO but not exact.) It's great, because the whole board is about the size of two postage stamps, side-by-side! The USB interface isn't built-in, but another small board has that. This way, I can buy these Pro Minis at $5 each, and use the $5 USB interface on each one until the project is complete. (No sense paying $10 for an Arduino compatible board with built-in USB, only to leave the USB completely unused once the device is "embedded".) :)

In the radio, I want to simply access and write to each location as though it were a hardware register. (Not write them all out, in a loop.) So, for example, if I want to save a station to memory preset 4, I just select that location and store it.

I'm thinking that changing memory presets on a radio isn't exactly going to wear out the EEPROM in a normal lifetime, so I can assign fixed addresses for each station preset and not worry. :) If the slot reads $FFFF, then I'll just have my code handle it as "empty", as you suggested.

Willie---: Hi, Krupski - Yes, "As expected" in that I have not yet implemented a means to write those arrays into the EEPROM. So is the EEMEM variable you used, supposed to place those values into the EEPROM, but the bootloader doesn't handle that? I may as well remove that code, then... I'm still too much of a Noob to even THINK of tinkering with the bootloader! (I don't want to risk bricking anything.)

Yes - correct.

You should not remove the code that defines the eeprom locations (i.e. this):

static const uint16_t fm_stations[] = {
    0, 0, 0, 0, 0, 0, 0, 0,
};

However, there's no point in placing ACTUAL values in them since they will not be programmed by Optiboot and will show up as erased 0xFFFF (or 65535 decimal).

You SHOULD, however, have a piece of code that looks for "empty" slots (i.e. 65535) and places the desired default into it.

Once the defaults are programmed, your "default setup" code will no longer write to any slot since it won't find any 65535 entries at next bootup.

Lastly, don't worry about ridiculous, complicated ideas to "level out eeprom wear", since you won't be writing to any particular eeprom location more than probably a few hundred times in the life of your project. You're not building a flash disk... you don't need wear leveling.

Hey, Krupski! Thanks for clarifying that.

OK, I’ve tweaked the TEST code a bit, as you’ve shown me.
(Note that I am not storing anything in this sketch.)

// Testing EEPROM code, V0.2

#include <avr/eeprom.h> //Extended EEPROM library 

// FM channel storage slots. The first is "last channel" to recall at power-up
static const uint16_t FMPreset[] { 0, 0, 0, 0, 0, 0, 0, 0, 0 }; //Total of 9
// AM channel storage slots. The first is "last channel" to recall at power-up
static const uint16_t AMPreset[] { 0, 0, 0, 0, 0, 0, 0, 0, 0 }; //Total of 9

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

    char buffer [64]; // buffer is just for printing
    uint8_t idx;
    uint8_t array_len;
    uint16_t FMchannel;
    uint16_t AMchannel;

    array_len = (18); // Total # of entries in array

 
    // display all (non-updated show as 65535)
    for (idx = 0; idx < 9; idx++) {
        FMchannel = eeprom_read_word (FMPreset + idx);
        sprintf (buffer, "FM entry #%u in the eeprom is %u\r\n", idx, FMchannel);
        Serial.print (buffer);
    }

    for (idx = 9; idx < 19; idx++) {
        AMchannel = eeprom_read_word (AMPreset + idx);
        sprintf (buffer, "AM entry #%u in the eeprom is %u\r\n", idx, AMchannel);
        Serial.print (buffer);
    }

    
}

void loop() {
  // Nothing yet

}

When I ran it, ALL of the values came back empty. (The previous code had written those three presets.) Does uploading a new sketch erase the EEPROM? I have to assume that it does. Here’s the serial monitor output:

FM entry #0 in the eeprom is 65535
FM entry #1 in the eeprom is 65535
FM entry #2 in the eeprom is 65535
FM entry #3 in the eeprom is 65535
FM entry #4 in the eeprom is 65535
FM entry #5 in the eeprom is 65535
FM entry #6 in the eeprom is 65535
FM entry #7 in the eeprom is 65535
FM entry #8 in the eeprom is 65535
AM entry #9 in the eeprom is 65535
AM entry #10 in the eeprom is 65535
AM entry #11 in the eeprom is 65535
AM entry #12 in the eeprom is 65535
AM entry #13 in the eeprom is 65535
AM entry #14 in the eeprom is 65535
AM entry #15 in the eeprom is 65535
AM entry #16 in the eeprom is 65535
AM entry #17 in the eeprom is 65535
AM entry #18 in the eeprom is 65535

I’m thinking that in the actual radio, the AM Memory Channel will simply be the array value - 9 for display purposes. (Essentially numbering them 0-9 to the user.)

I’m searching around the Forum for a decent and SIMPLE menu library (or sketch) that I can use to store these presets with the press of a button, then scrolling through them, and storing the new frequency into the desired slot. So far, all I’ve found were some that are far more complex than I need. I’m still a Noob, but I’m learning a little at a time. Sometimes, it seems overwhelming! I miss my old GWBASIC! :wink:

I like your word picture… you’re right, I’m NOT creating a flash drive! LOL! :smiley:

Willie…

Willie—:
Hey, Krupski! Thanks for clarifying that.

OK, I’ve tweaked the TEST code a bit, as you’ve shown me.
(Note that I am not storing anything in this sketch.)

    array_len = (18); // Total # of entries in array

// display all (non-updated show as 65535)
   for (idx = 0; idx < 9; idx++) {
       FMchannel = eeprom_read_word (FMPreset + idx);
       sprintf (buffer, “FM entry #%u in the eeprom is %u\r\n”, idx, FMchannel);
       Serial.print (buffer);
   }

for (idx = 9; idx < 19; idx++) {
       AMchannel = eeprom_read_word (AMPreset + idx);
       sprintf (buffer, “AM entry #%u in the eeprom is %u\r\n”, idx, AMchannel);
       Serial.print (buffer);
   }

Big mistake here… you cannot assume that the AM channels and FM channels arrays will be sequential and right next to each other in EEPROM. They MAY be, but there’s no guarantee.

Do not access them as “0 thru 9” and “10 thru 19”, but rather as “index 0 thru 9 in the AM array” and “index 0 thru 9 in the FM array”.
Also, you don’t need to hard code the element count in the array. Simply do this:

[b]array_elements = sizeof (array) / sizeof (*array);[/b]

In your case, “sizeof (array)” will be 18 (because there are 18 bytes in a 9 entry UINT16_T array) and since there are two bytes per UINT16_T, the math will be “array_elements = 18 / 2” which yields the proper result… 9.

Now, imagine for some reason you needed to change the array to use UINT32_T. Your hard coded count would now be wrong, but by using the code example above, you would end up with:

“array_elements = 36 / 4” which again equals 9.

Note the “*” in the second “sizeof”. Translated, the whole line read as:

“array_elements = sizeof (the whole array) / sizeof (the first element)”.

Make sense?

Willie—:
I miss my old GWBASIC! :wink:

I hear you. I used to use GWBASIC a lot when I was running Windows.

Now I use Linux and I have an excellent version of Basic written by Michael Haardt LINK.

It’s in source format and has to be compiled. I also added some features to it (most importantly a last line recall, handling of ANSI keyboard codes, auto-save of not-backed-up programs and several other features).

It’s 100% compatible with GWBASIC (plus does a LOT more). I couldn’t program without it’s help.

If you run Linux or use a MAC, let me know and I’ll send you the source of the original, my “improved” version and a compiled executable.

Attached is a ZIP file of the man page for it… see what it supports!

basic_manpage.zip (16.4 KB)

OK, I'm confused... forgive me.

Why wouldn't they be in the same, sequential places in the EEPROM, if I specifically want to PUT them there? I mentioned earlier, that I basically want to treat the EEPROM like hardware registers... just store each preset into a specific address, and recall them the same way. As you said, it's not a flash drive. :)

They will always be stored as 16 bit values... and once the code is stable, it will never be changed again. The Arduino board will be housed inside the radio cabinet, as a permanent part of the radio.

Many of these presets, once set, will not be changed. (Other than during testing.) During development & debugging I'll use an offset to move the whole block to a different area of EEPROM, then when the code is done, remove the offset, putting them into their permanent slots... but even with testing/debugging, I doubt I'll burn out any EEPROM addresses, unless I end up with some wild loop that repeatedly writes new values into them every millisecond. ;)

The only slot that may be changed the most, will be position "zero", the "last tuned frequency" to be recalled at power-up. Using the "update" function means that as long as the station wasn't changed, then no WRITE occurs.

Oh! A new rabbit trail! ;) YES! That BASIC you modified! Just send me the compiled executable! I'm planning to make a transition to LINUX in the future, (Windows 10 WILL NEVER HAPPEN HERE!!) and something like that would be AWESOME!! :) I have written a number of very useful programs in GWBASIC for the radio station where I work. Two programs on one computer are handling getting "Now Playing" data onto our Internet stream. Another, on a different computer, is logging an old RS232 system's telemetry data to a Windows HD. It took some doing to make THAT work (a special DOS emulator in Windows and a whole lotta tweaks) plus other tricks, to get the clocks on all 3 to stay in sync... but it's all working. :)

OK, I just changed the TEST code again.

I’m just going to treat the array as ONE block of storage. The first 9 will be FM, the last 9 will be AM. I made it write some presets into certain slots, and it works. :slight_smile:

// Testing EEPROM code, V0.3

#include <avr/eeprom.h> //Extended EEPROM library 

// Mem channel storage slots. The "last channel" will recall at power-up 
// (Idx 0 and 9)

static const uint16_t Preset[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };

//Total of 18, 9 AM and 9 FM (Including "last channel" for FM and for AM)


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

    char buffer [64]; // buffer is just for printing
    uint8_t idx;
    uint8_t array_len;
    uint16_t FMchannel;
    uint16_t AMchannel;

    array_len = (sizeof (Preset) / sizeof (*Preset)); // get # of entries in array
    
// write some values to the EEPROM
    eeprom_update_word ((uint16_t*)(Preset) + 0, 1049); // stored 104.9 as uint16_t (Valid station #1)
    eeprom_update_word ((uint16_t*)(Preset) + 3, 1069); // stored 106.9 as uint16_t (Valid station #2)
    eeprom_update_word ((uint16_t*)(Preset) + 6, 1073); // stored 107.3 as uint16_t (Valid station #3)
    eeprom_update_word ((uint16_t*)(Preset) + 10, 150); // stored 1500 as uint16_t (Valid station #4)

     
    // display all (non-updated show as 65535)
    for (idx = 0; idx < 9; idx++) {
        FMchannel = eeprom_read_word (Preset + idx);
        sprintf (buffer, "FM entry #%u in the eeprom is %u\r\n", idx, FMchannel);
        Serial.print (buffer);
    }

    for (idx = 9; idx < 19; idx++) {
        AMchannel = eeprom_read_word (Preset + idx);
        sprintf (buffer, "AM entry #%u in the eeprom is %u\r\n", idx, AMchannel);
        Serial.print (buffer);
    }

    
}

void loop() {
  // Nothing yet

}

Here is the serial monitor’s output, which is showing me that it’s working so far…

FM entry #0 in the eeprom is 1049
FM entry #1 in the eeprom is 65535
FM entry #2 in the eeprom is 65535
FM entry #3 in the eeprom is 1069
FM entry #4 in the eeprom is 65535
FM entry #5 in the eeprom is 65535
FM entry #6 in the eeprom is 1073
FM entry #7 in the eeprom is 65535
FM entry #8 in the eeprom is 65535
AM entry #9 in the eeprom is 65535
AM entry #10 in the eeprom is 150
AM entry #11 in the eeprom is 65535
AM entry #12 in the eeprom is 65535
AM entry #13 in the eeprom is 65535
AM entry #14 in the eeprom is 65535
AM entry #15 in the eeprom is 65535
AM entry #16 in the eeprom is 65535
AM entry #17 in the eeprom is 65535
AM entry #18 in the eeprom is 65535

Better? :slight_smile: