LED Sequencing and Dynamic Memory

Trying to make the Arduino play a sequence of brightness settings along to music. The music is irrelevant right now. The issue I am having is getting an array of thousands of values into the program without filling up the dynamic memory. I would like to have multiple strips which means multiple arrays of numbers, but based on how that is going, there is too much memory being eaten up.

In all, is there a different way I should go about this rather than using arrays? Or is there just no particular solution to my problem.
I imagine this issue will only be made worse If I try and do RGB LEDs as they would require a set of values for each color, etc.

Is there another board I should use rather than the MEGA? Or should I be looking for something different all together?

I have already tried PROGMEM, but the loading time to way too much and it just makes the LEDs blink rapidly or stop altogether for a while.

Any help is apricated. Thank you.

(Ignore the
"Serial.print("#S|MONKEY|[");
Serial.println("]#");".
It is irrelevant to the issue.)

Sketch_Finished.ino (8.5 KB)

You can move your data into program memory, this gives you the space to store arrays without using the SRAM.
https://www.arduino.cc/reference/en/language/variables/utilities/progmem/

Note the Arduino does not have any dynamic memory, but uses static memory. Dynamic memory needs refreshing constantly where as static memory keeps its value as long as the power is on.

@Grumpy_Mike the Arduino development software uses the term "dynamic memory":

Sketch uses 444 bytes (1%) of program storage space. Maximum is 32256 bytes.
Global variables use 9 bytes (0%) of dynamic memory, leaving 2039 bytes for local variables. Maximum is 2048 bytes.

It might do but it is not correct. I can't help it if software engineers don't know what they are talking about.

You can use external memory, FRAM will behave almost like RAM even though it is not directly addressable. It has an advantage, it will remember if you have a power failure. To my knowledge there is no direct way to add RAM to any of the Arduino microcontrollers. This memory will not show up on the compiler summary.

Is there anyway to prevent this from being so laggy? I tried to use PROGMEM but it would just stutter or turn off for a while and continue the sequence after a second, but of course badly.

Describe what your end product looks like.

-jim lee

Basically, it is just the LEDs turning up and down based on what number is pasted as the variable. So having 10, 50, 100, 150, 255 in the array would mean the LED would be getting brighter with each command. I have external tools to get these values the way I want it, but it takes up too much memory to have thousands of these values in an array. Specifically RAM storage is the issue.

Please post your code that uses PROGMEM, you are likely not reading the values from PROGMEM correctly. With a 50mS delay after the analogWrite, any additional time needed to retrieve the data from PROGMEM will be unnoticeable.

Could you possibly do it with a curve? Put in a few points and let the computer fill in the rest as you play the music? That would knock the nasty out of the memory problem.

-jim lee

How would I go about doing that? Wouldn't it be a very complex equation since there would be a lot of slopes?

I have already tried using PROGMEM. Unless there is something I am supposed to do other than adding it to the top of the program and putting PROGMEM before the brackets.

Actually it may be pretty simple. (No promises though)

How are you setting the brightness of the LED? A PWM pin? A neopixel?

How may LEDs are we talking about?

-jim lee

You need to properly tell the compiler to read the data from PROGMEM

    analogWrite(5, pgm_read_byte(&pattern[v]));

It is a PWM pin, yes. So far, it is just two LED strips that are single color and not individually addressable. It is using analogWrite("PIN", "array[]")

Well I feel real dumb right now, haha. Thank you so much. I looked all over and I guess I missed that aspect everywhere I looked. I didn't realize there was a specific way to address the array after its been moved, but that makes too much sense I suppose. Is that the only different way to address it in this situation?

That is generally how you would read a byte array from PROGMEM, at least until you get to the point of having more than 64k bytes of data, then it gets a bit more complex.
Retrieving data stored in PROGMEM tends to be a somewhat confusing process, particularly when storing text or arrays of pointers. It is best to test the code by printing out the values in PROGMEM to verify you are reading them correctly.

See if this will help..

#include <multiMap.h>
#include <timeObj.h>
     
#define FADE_PIN     9        // The fading pin. (Must be pwm out pin)
#define STEP_TIME    25       // Number of mililseconds per change in brightness.
#define MAX_MS       2000     // Just so we know when to end..

multiMap fadeMapper;                // A non-liner mapper to hold fade over time info.
timeObj  stepTimer(STEP_TIME);      // A timer for changing the fade value over time.
int      stepTime;                  // What step in the fading sequence are we in now?


void setup(void) {

   analogWrite(FADE_PIN,0);               // Shut it off for a start
   fadeMapper.addPoint(0,0);              // Starting at zero
   fadeMapper.addPoint(1000,255);         // Mid time is at full bright.
   fadeMapper.addPoint(MAX_MS,0);         // End time, back to zero.
   stepTime = 0;                          // Starting at time zero.
}


void loop() {

   int fadeVal;
   
   if (stepTimer.ding()) {                         // If the step timer has expired (->ding<-)..
      fadeVal = round(fadeMapper.map(stepTime));   // Caculate a new fade value by mapping the frame time.
      analogWrite(FADE_PIN,fadeVal);               // Round the fade value to an int and send it out to the PWM pin.
      stepTime = stepTime + STEP_TIME;             // Bump up the frame time for the next reading
      if (stepTime>MAX_MS) {                       // If the frame is beyond the last reading..
         stepTime = 0;                             // Reset it to zero.
      }
      stepTimer.stepTime();                        // Restart our frame timer for the next setting.
   }
}

What this does is let you add brightness points over time. Then it "plays" them over time ramping from one point to the next. Its set up here to calculate a brightness every 25 milliseconds. This version only has 3 points 0ms, 1000ms and 2000ms then it loops. You can add more points to create the brightness curve over time that you need.

If you want to try this, you will need to grab LC_baseTools from the library manager to compile it.

Good luck & have fun!

-jim lee

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.