EEPROM to Long?

Go To Last Post
12 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hey,

My project requires that I save a long variable to EEPROM; reading is easy. I just read out to integers (most significant first) and shift this into the tempoary long variable. I optimised this to work with just one long variable:

long TempLong;
TempLong = eeprom_read_word(Addr);
Templong<<= 16;
TempLong |= eeprom_read_word(Addr + 2);

...At least I HOPE thats how it should work. The problem i'm having is with writing; how do I do this? I can shift the long 16 right and typecast it to an int to get the most significant int into EEPROM, but how do I do the lower int? I assume you just mask it off, like "TempLong & 0xFFFF".

Any ideas?
- Dean :twisted:[/code]

Make Atmel Studio better with my free extensions. Open source and feedback welcome!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

See the eeprom_read_block() and eeprom_write_block() functions.

For example:

eeprom_read_block((void *)&TempLong, Addr, sizeof(TempLong));
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Awww, I like making my own functions! At any rate, is read_block smaller than making my own long reding subs?

- Dean :twisted:

Make Atmel Studio better with my free extensions. Open source and feedback welcome!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You will be able to use read_block() in several other places. Reading in your liquid name strings comes to mind -- they're all fixed-length strings, right? Well, then, you can get rid of a bunch of for(){read_byte()} loops etc.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Oh, goodie. I just hope the read block function isn't too big on ROM space...

Kudos to all,
- Dean :twisted:

Make Atmel Studio better with my free extensions. Open source and feedback welcome!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

BTW, will the read_block command correctly read numbers into longs, AND read chars into strings without modification or extra commands?

- Dean :twisted:

Make Atmel Studio better with my free extensions. Open source and feedback welcome!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Yes. eeprom_read)block() just reads an ordered sequence of bytes, starting at the address you specify, and continuing for the number of bytes requested.

The address returned by (&MyLongNumber) is the address of the first byte used to store the number -- subseqent bytes will be in higher-valued addresses. Any variable is, when you boil it all down, nothing more than a block of one or more bytes.

- Luke

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thats what I like soooo much about C. You can copy a byte to an integer, a float, a double, an array, or just any 'ole location you want. In VB if you have a variable declared as a byte and want to access it like an integer, you have to jump through about 4 type casting hoops in the correct order.... yet if you have a string "143' in a text box you can access it either as a string or an integer, and probably a float too. But if you ever have to convert a byte to a character, just give it up and start over.... I REALLY need to learn Visual C. I was going to ..... I'm way off topic, I'm gonna shut up now.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

But will it read into an array? How you it differenciate between an integer and a string and write the data accordingly?

- Dean :twisted:

Make Atmel Studio better with my free extensions. Open source and feedback welcome!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

If you define a structure, you can load/save all your variables from/to EEPROM with a single block read/write, and you can have mutiple versions in EEPROM, and load a whole "profile" from a selection. Sounds just what you might need for your different fluids or whatever.

Four legs good, two legs bad, three legs stable.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

abcminiuser wrote:
But will it read into an array? How you it differenciate between an integer and a string and write the data accordingly?

- Dean :twisted:


I'm afraid I don't quite understand what you mean by this.
Say you have an array of longs:

long MyEEPROMLongArray[11] EEPROM;
long MyRamLong;
long MyRamLongArrayCopy[11];

// Read item 3 from MyEEPROMLongArray into MyRamLong.
eeprom_read_block(&MyRamLong, &MyEEPROMLongArray[3], sizeof(long));

// Read the entire EEPROM Long array into the RAM Long array copy.
eeprom_read_block(MyRamLongArrayCopy, MyEEPROMLongArray, 11 * sizeof(long));

Say you have an array of fixed-length strings:

char LiquidNames[11][10] EEPROM; // 11 strings, each 10 chars long.
char ActiveLiquidName[10]; // RAM copy of selected liquid name.

// Copy liquid number 3's name into ActiveLiquidName.
eeprom_read_block(&LiquidNames[3][0], ActiveLiquidName, 10 * sizeof(char));
// sizeof(char) == 1, so you should be able to leave this out.  But, you 
//never know when you might work on a machine that uses 2-byte chars.  
//Just to be paranoid, leave it in.

As John said, you may do well to group all the data regarding a single liquid into a structure:

struct Liq_Dat
{
   long mlspersecond;
   char name[10];
};

struct Liq_Dat Liquids[11] EEPROM; // EEPROM storage for each liquid
struct Liq_Dat CurrentlyActiveLiquid; // RAM copy of data for selected liquid

// Make liuid number 5 active.
eeprom_read_block(&CurrentlyActiveLiquid, &Liquids[5], sizeof(struct Liq_Dat));

// Modify liquid number 3's discharge rate
long NewMlsPerSecond = 123456;
eeprom_write_block(&(Liquids[3].mlspersecond), &NewMlsPerSecond, sizeof(long));

Hope I understood your question correctly.

- Luke

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hehe, never mind, I accidentally skipped the part regarding writing block data to an array from the eeprom_read _block statement. Thinking about this last night, I (as usual) figured out the answer before getting you guy's replies and after I've already posted the problem. I suppose I should spend a day thinking before posting, as this would resuce forum noise and prevent me from wasting the time of others when I can figure it out myself...eventually ;).

I realised that everything in C IS just byte memory locations, and an array is identical to a long in RAM terms - it is just handled differently by the program. As for writing the whole liquid data as a struct, this would actually add complexity rather than reduce it for many reasons which I am too tired to go into right now. I will change over the eeprom FOR loops into the read_block command to reduce code size, and also add long data capability.

When I tried to add the new code last night - before I fully understood how the function worked - I was dismayed to find that my LCD had stopped working. Going over the code and even downloading old and working code had no effect. The problem; a loose wire. This brings me to my conclusion; when it is a toss up between hardware and software faults, the problem always is in the hardware. Feel free to quote me on that after you spend 3 hours trying to "fix" your code like me.

Incidenatally, I havn't used VB for ages - i've been caught up in microcontrollers for a good year now. Going back over my code after a guy asked me about it, I am amased at how clunky and underpowered the language is, this rings true for my BASCOM as well. Looks like i'll be learning C or C++ for computers as well soon. Kudos to all, and to all a good night.

- Dean :twisted:

Make Atmel Studio better with my free extensions. Open source and feedback welcome!