Storing/Indexing a random row of a large array

Hello all! I have a large 2D matrix (216x4) defined in my Flash storage as four 54x4 matricies. I’m having trouble referencing it a random row within a these matrices without exceeding SRAM storage limitations. I want to select a random row from this matrix, and light up these numbers red. Here’s a sample of my code.

int x = random(0, numTargets/4); // random target row number (0-53)
int r = random(0,4); // target element number (0-3)

for (int k = 0; k < 4; k ++) {

if (r == 1){ // first column of LEDS
int matNow[4] = matrix1;

for (int j = 0; j < 4; j++) {
matNow[j] = matrix1[j];}
leds[matrix1[k]] = CRGB::Red;
FastLED.show();}

else if (r == 2){ // second column of LEDS
int matNow[4] = matrix2;
for (int j = 0; j < 4; j++) {
matNow[j] = matrix2[j];}

leds[matrix2[k]] = CRGB::Red;
FastLED.show();}

else if (r == 3){ // third column of LEDS
int matNow[4] = matrix3;
for (int j = 0; j < 4; j++) {
matNow[j] = matrix3[j];}

leds[matrix3[k]] = CRGB::Red;
FastLED.show();}

else if (r == 4){ // fourth column of LEDS
int matNow[4] = matrix4;
for (int j = 0; j < 4; j++) {
matNow[j] = matrix4[j];}

leds[matrix4[k]] = CRGB::Red;
FastLED.show();}

Is there any way to reference a random one of these rows that exists in flash storage without referencing the entire matrix?

Please read the how to use this forum sticky post, and post you code in code tags like it tells you.

Then go back to the first post and modify it so you post all your code correctly.

Yes there should be a way to do what you want but the code fragment you have posted makes little sense.

Ok… so this is where I got to with this…

First up, this code DOESN’T work, but I’ll explain…

#include <Adafruit_DotStar.h>
#include <SPI.h>
#define NUMPIXELS 150 // Number of LEDs in strip
#define DATAPIN    4
#define CLOCKPIN   5

Adafruit_DotStar strip(NUMPIXELS, DATAPIN, CLOCKPIN, DOTSTAR_BGR); // I thought this was right

// array 150 x 20
const PROGMEM uint32_t fire_animation[3000] = {0xca3729,0xca3729,0xca3729,0xca3729,0xca3729,0xca3729,0xca3729,0xca3729,0xca3729,0xca3729,0xca3729,0xca3729,0xca3729,0xca3729,0xca3729,0xca3729,0xca3729,0xca3729,0xca3729,0xca3729,0xca3729,0xca3729,0xca3729,0xca3729,0xca3729,0xca3729,0xca3729,0xca3729,0xca3729,0xca3729,0xca3729,0xca3729,0xca3729,0xca3729,0xca3729,0xca3729,0xca3729,0xca3729,0xca3729,0xca3729,0xca3729,0xca3729,0xca3729,0xca3729,0xca3729,0xca3729,0xca3729,0xca3729,0xca3729,0xca3729,0xca3729,0xca3729,0xca3729,0xca3729,0xca3729.... TRUNCATED FOR THIS CHAT BUT YOU GET THE IDEA};
int pixel_offset = 0;

void setup() {
  strip.begin(); // Initialize pins for output
  strip.setBrightness(20); // don't blind yourself
  strip.show();  // Turn all LEDs off ASAP
}

void loop() {
    delay(20);                        // Pause 20 milliseconds (~50 FPS)
    pixel_offset += 1;
    if (pixel_offset >= 20) {
      pixel_offset = 0;
    }
    for(int i=0; i<NUMPIXELS; i++) { 
      // strip.setPixelColor(pixel, color);
         strip.setPixelColor(i, fire_animation[(pixel_offset * NUMPIXELS) + i]);
    }
    strip.show(); // Send Color Code
    
}

You can see that first constant is my array

fire_animation

with 3000 items (that’s 20 frames worth of pixels for my 150 pixel strip). and the “PROGMEM” as I understands it stores it in the flash memory, not the ram.

Now if I access each of those in turn, it works just fine… For example:

strip.setPixelColor(i, fire_animation[5]);

This works just fine and sets the correct colour… However, as soon as I try to animate it using the code above using variables, the colours go all odd… It’s not reading the correct colours at all…

I have no idea what’s going wrong… If it’s an issue reading that much data that quickly or what the heck is going on…

This is how I am converting my image (PNG) to the colour array by the way… javascript:

$(function() {

    var canvas = document.getElementById('viewport'),
    context = canvas.getContext('2d');

    my_image = new Image();
    my_image.src = 'solar_flare.png';
    my_image.onload = function(){
    context.drawImage(my_image, 0, 0);

    var pixels = 150;
    var frames = 20;

    var compilation = 'const PROGMEM uint32_t fire_walk_with_me[' + (pixels * frames)  + '] = {';
    for (let hop = 0; hop < pixels; hop++) {
        for (let step = 0; step < frames; step++) {
            
            var p = context.getImageData(0, 0, 1, 1).data;
            var hex = "0x" + ("000000" + rgbToHex(p[0], p[1], p[2])).slice(-6);
            compilation += hex + ',';

        }
    }
    compilation += '};';
    $('#output').val( compilation );

    }
    
});

function rgbToHex(r, g, b) {
    if (r > 255 || g > 255 || b > 255)
        throw "Invalid color component";
    return ((r << 16) | (g << 8) | b).toString(16);
}

and you just need the corresponding canvas in the html:

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
</head>

<body>

    <canvas id="viewport" width="150px" height="253px"></canvas>
    <textarea id="output"></textarea>

		<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
    <script src="js/scripts.js"></script>
</body>
</html>

Are you the OP with a different account?

It seems to me that you are not accessing the array in program memory correctly. You need to use pgm_read_word_near to do this, as explained here https://www.arduino.cc/reference/en/language/variables/utilities/progmem/

strip.setPixelColor(i, fire_animation[5);

That will not even compile you are missing a ]

From what I remember from the fire animation in the FastLED library that involves writing back into the initial buffer and you can’t do that when it is stored in program memory.

I promise you I am not the OP with a different account.

I just was just searching through the forums looking for how to do this before I make my own post cause I'm a good person.

lardnicus: I just was just searching through the forums looking for how to do this before I make my own post cause I'm a good person.

you are a bad person hijacking anothers thread with your problem. Report your own post(s) to a moderator and kindly ask for a split off in a separate thread.