1

I am working with Arduino UNO connected with BV4612 display. I am working on a simple code that controls several water pumps. Each pump has several modes it can run in. I store these modes in an array. The number of water pumps may vary, and I'd like to store that value in EEPROM (either arduino's or display's).

When the pump count is fixed, I use fixed value, defined by macro:

#define     PUMP_COUNT      18      //How many pumps we have

uint8_t pumpModes[PUMP_COUNT];

void setup(){...}
void loop(){...}

I'd like to get rid of fixed defined value of PUMP_COUNT, and rather load it from EEPROM, or save the new pump count into the EEPROM if needed. However, I can't declare an array if I can't read from EEPROM before setup() function like this (from address 32 for example):

uint8_t pumpModes[EEread(32)];

void setup(){...}
void loop(){...}

Is there a solution to get the value from EEPROM so I can declare global array's length with it?

Thanks.

2 Answers 2

1

You can't create variable length arrays in C. That's not how C works.

Instead you have to create an array that is big enough to store the maximum number of pumps you want to be able to deal with.

The array "size" is then just a number in a variable obtained from wherever you like (including EEPROM).

It doesn't matter if you don't use all of the array. The rest just sits there twiddling its metaphorical thumbs.

The other option, if you are only going to define the array once at startup, or very rarely change the size, is to use malloc():

uint8_t *pumps;
uint8_t nPumps = 0;

void setup() {
    nPumps = EEPROM.read(32);
    pumps = (uint8_t *)malloc(nPumps);
}

You can change the array size then with:

nPumps = 8; // for example
pumps = realloc(pumps, nPumps);

And dispose of the array with:

nPumps = 0;
free(pumps);

It's best to try not to change the array size once created, since that can make swiss cheese of your heap, and is not a friendly thing to do on a small microcontroller. If you can decide the array size once in setup and keep it the same all the time the program is running this is a safe operation. Otherwise it becomes risky.

6
  • Thanks, that's what I thought and I used exactly this as a solution so far. I was just trying to save as much RAM as possible, but this has to suffice.
    – MiragePV
    Commented Apr 14, 2018 at 10:13
  • You could use a pointer and use malloc() and free() to change the array size instead. I'll detail it in my answer.
    – Majenko
    Commented Apr 14, 2018 at 10:15
  • @MiragePV, save RAM for what? is there something that can use the extra RAM if there are less pumps?
    – Juraj
    Commented Apr 14, 2018 at 10:42
  • 1
    Trying to save ram could be a problem, as you could en up with a program that works with 14 pumps, but as soon as you add a 15th the program runs out of RAM and you program starts behaving weirdly. By allocating the maximum number pumps needed, you’ll immediately notice if you run out of memory.
    – Gerben
    Commented Apr 14, 2018 at 13:38
  • @Juraj: The less RAM used by static data (globals and heap), the more is available for the stack. Static data is assigned from the bottom of RAM upward; the stack starts at the top of RAM and builds downward during execution. What is left in the middle at any point during execution is the free RAM. If you only use malloc() and free() at most once, in setup(), then the top of static data doesn't change. The bottom of the stack changes frequently, building downward with each function call, and retreating upward again when the function returns.
    – JRobert
    Commented Apr 15, 2018 at 12:23
0

It is possible to use a dynamically allocated array, with malloc and free.

To create such an array use:

uint8_t* pumpModes;

Somewhere in setup (preferably):

pumpModes = malloc(sizeof(uint8_t) * PUMP_COUNT);

Freeing the memory is not needed if you need it throughout the entire program, otherwise you can use

free(pumpModes);

However, take in mind that if you continuously malloc and free memory in the loop() function, you can get memory 'gaps' and you run out of memory really quickly since the Uno has only a few KB of RAM memory.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.