Help using ENUM and PROGMEM to save RAM [solved]

Right, lately I posted code on Arduino Forum where I use a bunch of Strings and was looking to reduce RAM usage.
dc42 suggested

If you are worried about running out of RAM, then you need to:

  1. Stop using the String class and use char arrays instead;

  2. Where possible, put string literals and any constant arrays you may be using in PROGMEM.

I don't see why you need to use strings at all to name the buttons. Why not use an enumeration to name the buttons instead? Like this

Well, I was looking around to learn about these but didn't find a satisfying explanation anywhere. What I was able to get so far is:
ENUM sets up a kind of array where each variable has a string name and a value assigned to it depending on its order

enum week { Mon=1, Tue, Wed, Thu, Fri Sat, Sun} days;
or
enum escapes { BELL = '\a', BACKSPACE = '\b', HTAB = '\t',
RETURN = '\r', NEWLINE = '\n', VTAB = '\v' };

or
enum boolean { FALSE = 0, TRUE };

(from: The enum statement)

PROGMEM has to be written after the variable name when I want to store it in program memory and free RAM. I need strange different methods to write and retrieve data from there(is it slower, I suppose so). (from: PROGMEM - Arduino Reference)

Well, was wondering whether or not I got anything right and if there is anything worth adding and/or clarifying (I'm sure)

**Note:**I also searched the forum and found nothing very helpful. With this title I hope we solve that :slight_smile:

PROGMEM is not "slower" (than what, after all ? ). It's where the program is read during execution.

To put string literals in PROGMEM you just have to surround them with F().

Example:

Serial.println("HALLO WORLD");

becomes:

Serial.println(F("HALLO WORLD"));

I'm struggling with enums now and I get the following error:

int buttonNames[3];
enum buttonNames = {numButton, functButton, menuButton};
void setup() {}
void loop() {}

use of enum 'buttonNames' without previous declaration

Look at the declarations for enums in your first post. See any equal signs before the { ? I don't.

Look at the declarations for enums in your first post. See any equal signs before the { ? I don't.

XD

PROGMEM is not “slower” (than what, after all ? ).

Than having variables in RAM

I got enum to work so far but what is the name for??:

enum >>name<< {cnnumButtons, cnfunctButtons, cnmenuButtons};

I seem to be fine just calling cnnumButton (for example).

Here name is the name of the type. The cnnumButtons and so on are the values that type can take.

I called it buttonNames and it compiles: (You mean Data Type I suppose)

enum buttonNames {cnnumButtons, cnfunctButtons, cnmenuButtons};

Should it be something like: (Following doesn't compile)

enum byte {cnnumButtons, cnfunctButtons, cnmenuButtons};

You can't call it 'byte' because that is already the name of a type. You are defining a new type and you need to give it a unique name.

You are defining a new type and you need to give it a unique name.

Thanks

Is there a special way to access data in a variable array in PROGMEM or will it work properly treating it as a normal variable. (My case: a huge array containing dynamic data that is constantly modified by program(This is why I was wondering if it would take much longer to access)(every 10min in a year)

You can't modify data in PROGMEM.

Sorry, this confused me:
**From:**http://arduino.cc/en/Reference/PROGMEM

The following code fragments illustrate how to read and write unsigned chars (bytes) and ints (2 bytes) to PROGMEM.
#include <avr/pgmspace.h>


// save some unsigned ints
PROGMEM  prog_uint16_t charSet[]  = { 65000, 32796, 16843, 10, 11234};

// save some chars
prog_uchar signMessage[] PROGMEM  = {"I AM PREDATOR,  UNSEEN COMBATANT. CREATED BY THE UNITED STATES DEPART"};

unsigned int displayInt;
int k;    // counter variable
char myChar;  

// read back a 2-byte int
 displayInt = pgm_read_word_near(charSet + k)

// read back a char 
myChar =  pgm_read_byte_near(signMessage + k);

So according to this:

There are three kinds of memory:

The PROGMEM is read-only, as far as your sketch is concerned. You can’t change it. Only the “Upload sketch from PC to Arduino” feature on your computer can do that. Variables with PROGMEM are stored in this read-only memory, which saves RAM but can’t be changed.

The RAM is read/write, and is where all your variables are stored while your sketch runs. Variable values are lost when power goes out, and your sketch re-initializes them when it starts at the beginning again.

The EEPROM is read/write, and won’t disappear when you turn off the power. But the only way to use it is by having your code use the EEPROM.write() and you read it back later with EEPROM.read().

Arduino has EEPROM and since I want to store a schedule-like huge array of bytes (every 10 mins in a year, every 10mins maybe contains 3 bytes) I was wondering: would it fit (I’m using a MEGA 2560)? Is there any was of compressing it? How much EEPROM can I use? Maybe a month would fit?

Could anyone clarify: is there an easy way of read/writing EEPROM or must it be byte by byte(as in tutorial)?? (I’m referring to something like declaring a boolean in EEPROM or an array)

Thanks for reading!! :slight_smile:

RonaldPoFo:
Arduino has EEPROM and since I want to store a schedule-like huge array of bytes (every 10 mins in a year, every 10mins maybe contains 3 bytes) I was wondering: would it fit (I'm using a MEGA 2560)? Is there any was of compressing it? How much EEPROM can I use? Maybe a month would fit?

3 Bytes * 6 10 minute intervals an hour * 24 Hours = 432 Bytes per day. The Mega has 4069 bytes of EEPROM.

Simple arithmetic.

Oh, right. :roll_eyes: Maybe I could only store common repetitions etc… in EEPROM and use that to recompose it a bit if battery died (to not start from zero). Or I think I can add EEPROM by connecting a EEPROM chip, right?

So could anyone clarify: is there an easy way of read/writing EEPROM or must it be byte by byte(as in tutorial)?? (I’m referring to something like declaring a boolean or an array in EEPROM without having to separate the info)

A question about RAM too: When I declare this huge array, will it always be sitting around in RAM or can it be put away to PROGMEM when not in use (the arduino itself would do this, not my code)?

So could anyone clarify: is there an easy way of read/writing EEPROM or must it be byte by byte(as in tutorial)?? (I'm referring to something like declaring a boolean or an array in EEPROM without having to separate the info)

Look for EEPROM_readAnthing and EEPROM_writeAnything. In the end, it's byte by byte.

RonaldPoFo:
Could anyone clarify: is there an easy way of read/writing EEPROM or must it be byte by byte(as in tutorial)?? (I’m referring to something like declaring a boolean in EEPROM or an array)

As PaulS says:

http://playground.arduino.cc/Code/EEPROMWriteAnything

You can add an I2C (or SPI) EEPROM chip, for example:

http://www.gammon.com.au/forum/?id=10896&reply=2#reply2

Look for EEPROM_readAnthing and EEPROM_writeAnything. In the end, it's byte by byte.

You can add an I2C (or SPI) EEPROM chip, for example:

Gammon Forum : Electronics : Microprocessors : I2C - Two-Wire Peripheral Interface - for Arduino

Thanks both, very helpful. Think I'll modify the program sofort so it's not worse later.
Well, that solves that. :smiley: