View Full Version : Savings a Mixture of variable Types In Eeprom (i.e LONGS & BYTES)

11-25-2010, 03:39 AM

I have code for saving VARIABLE's back in the eeprom, this works perfectly and I have been using this routine for ages.

In My "VAR" Block, I so far have defined all of my variables as LONG's

A section of these variables are saved, so at the start of the variables that need to be saved I have a variable called VarMemStart

Then I have all my Long variables defined

and then at the end of these, I have another Variable called "VarMemEnd"


VAR ' My variable Block

LONG MyVariable1, MyVariable2

LONG VarMemStart
LONG MySaveableVariable1, MySaveableVariable2
LONG VarMemEnd

When I need to save these variables, I call my save routine like so..

EepromSave (@VarMemStart, @VarMemEnd)

I need to define the start and end variables as LONGS as these are Address pointers used in my save routine.

What I understand is that when SPIN get compiled, it will RE-ORDER all the variables in the following order..

LONGS, WORDS then BYTEs ( and I think DAT's as well after that)

Q1) How do I save the BYTES? ( This is my main question )

I need to have some STRINGS saved as well as my other longs, But If I declare a BYTE like..

LONG VarMemStartBytes
BYTE MySavableByteVariable[17] ' This will be a 16 BYTE STRING , with one extra byte for the termination.
LONG VarMemEndBytes

When this gets compiled , my LONG variable Pointers will get "Grouped" together with the other LONGS, So I wont be able to point to the start and end of my variables.

And Before you ask, Why don't I just save ALL VARIABLES?

I have half the eeprom/ram taken up with big arrays of LONGS which stores data ONLY While the device is ON, So I don't need to save all of these, AND, If I were to save them, it would add considerable time , that the USER would notice.

My Main reason for saving SMALLER sets of variables, is to SAVE SYSTEM PARAMETERS (User Preferences) which is invoked every time the user changes one of these settings.

If i were to create MULTIPLE VAR BLOCKS , would the COMPILER keep these separate? , but even if this happened, then I still have the issue of the LONG ADDRESS Pointers being grouped together!

Q2) Is it possible to save a STRING as a series of LONGS, where 1 Long can be used for 4 BYTES?, That way it would not be mixed up, i.e consecutive.

Q3) Would the use of a DAT Block be a better option? Can I save just a DAT Block?

Any Ideas?


Dave M

Mike Green
11-25-2010, 04:11 AM
You can certainly use an array of longs to hold strings. You can access the individual bytes by using MySavableByteVariable.byte[ x ] where x is a byte subscript.

You can also use variables in a DAT section and their order will be maintained by the compiler. The compiler will properly align the storage sizes and add padding where necessary.

If you're going to have a mix of long and byte values, you could keep two areas, one of longs and one of bytes, and save them separately to EEPROM.

11-25-2010, 04:52 AM
Hi Mike,

If I keep 2 areas, one for byte the other for longs, then I can't put LONG's for my variables pointers! That was the point I was trying to make.

But having said that I think I have an answer!

I will use a DAT Block and Save the WHOLE DAT Block , This DAT BLOCK will be my USER PARAMETER Variables.


Another thought I just had, Is that I could change my routine to save just one variable, and not use any pointers, I would have the START & END Pointers which the eeprom save routine needs GENERATED from the ADDRESS of the single variable, If this is in a DAT BLOCK , It will make it easier

What do You think?

If I get This working I will find some time and post an object so everyone can benefit!


Dave M

11-25-2010, 06:44 AM
I use the dat method. Heres a couple of files that show the way I did it.

11-25-2010, 07:44 AM
Hi Tim,

Sorry mate, but I cant figure out anything in those files!

Are you saying you use a DAT BLOCK and you can WRITE the variables back to the Eeprom DAT BLOCK area? ( i.e Change them)

I thought the dat block was READ ONLY!


Dave M

11-25-2010, 10:18 AM
OK, OK , OK!

I was wrong!!

Before anyone notices, I ASSUMED something that was NOT THE CASE,

I assumed that the Start or End pointers had to be the same variable type as the variable type it was "Surounding", this is not so.

All my save routine needs is the pointer variable name, it will refer to that pointer as an address which is ALWAYS a LONG , even though the pointer name was declared as something different.

So I just made a change and tested this and it NOW WORKS!!!!

example code.. ( Note I have used descriptive variable names!)


LONG MyLongVariable1, MyLongVariable2 'These variables are NOT saved

LONG LongStartPointer
LONG MyLongVariable3, MyLongVariable4 'These variables ARE saved
LONG LongEndPointer

BYTE MyByteVariable5, MyByteVariable6 'These variables are NOT Saved

BYTE ByteStartPointer
BYTE MyByteStringVariable7 [17], MyByteVariable8 'These variables ARE saved
BYTE MyByteVariable9
BYTE ByteEndPointer

Make sure that all the variables are kept in LONG, WORD and BYTE ORDER , then when SPIN Compiles, it will keep all the variables in the same order as typed.

Now to save the variables add an extra line for the BYTES to be saved. I create a method called SAVE, which makes reading the code easier.

PUB Save
EepromSave (@LongStartPointer, @LongEndPointer) ' This will save all the LONGS
EepromSave (@ByteStartPointer, @ByteEndPointer) ' This will save all the BYTES

By the way When I say POINTER, that means Address Pointer. And this should work with words as well Just have to add an extra line in the save routine.


Dave M

11-25-2010, 04:44 PM
DAT variables are re-write, they are just space in the RAM, they are initialized from the program eeprom but are not readonly.

The way I use it is

Define DAT variables for the stuff you want to config, set them to some default values. The program just accesses the variables in the DAT section without worrying about the stored config values.

These values are used unless there is an updated config in eeprom. The eeprom version is stored at 32K i.e. not where the normal program is so doesn't affect the default values.

The program starts and loads the default variables. It calls LoadConfig which checks if there is an updated config stored. If no it does nothing and you continue with the default set. If there is an updated config then it reads and overwrites the default values in RAM.
At this point your program continues with the updated configuration

You can change the dat values but not store them to eeprom, next time you restart you have the previous values back
You can call SaveConfig which will save the latest DAT values to eeprom, so next time you restart you have the saved DAT values

You can also call ResetConfig, this deletes the stored config values so when you restart you run with the original default values.