Another array and a variable name for loop question

Currently working on using an 8x8 LED matrix driven by a MAX7219.

The hook-up (display is mounted 90 degrees counterclockwise, but it doesn't flop around)


What I am doing now is using a WPF app I made to quickly draw the images I want the LED to display and copying/pasting them into my Arduino sketch.

Basically it works.

Here is the code

/*This sketch is partially based on the pdf file that
came with my MAX7219 8x8 LED display which was included
in my 16Hertz brand starter kit off of Amazon.  It included
a sketch which demonstrated the display cycling through
numbers 0-9 and letters A-Z without needing a library. Author is unknown
*/


const int CLKpin = 10;
const int CSpin = 9;
const int DINpin = 8;

//int pin1 = A0; //Used with stopPin to stop between frames until button pressed. Currently disabled

const int fps = 175; //The time in ms each frame is displayed

const int numberOfFrames = 40;  //***MUST BE SET EQUAL to NUMBER of FRAMES PASTED and MAKE SURE FILM[] HAS SAME NUMBER***

//Here is where to paste info from my C# hexMapper program

unsigned char frame1[] = {0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81};
unsigned char frame2[] = {0x40, 0x01, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02};

unsigned char frame40[] = {0x7E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7E};

// This is where I am wanting to dynamically create the film array size based on numberOfFrames
// and use a for loop to fill the film array with the frames I paste into the sketch before uploading.
// Currently manually adding and deleting frames in the film array as
// numberOfFrames changes, which is tedious

unsigned char *film[] = {frame1, frame2, frame3, frame4, frame5, frame6, frame7, frame8, frame9,
                         frame10, frame11, frame12, frame13, frame14, frame15, frame16, frame17, frame18, frame19, frame20,
                         frame21, frame22, frame23, frame24, frame25, frame26, frame27, frame28, frame29, frame30, frame31,
                         frame32, frame33, frame34, frame35, frame36, frame37, frame38, frame39, frame40
                        };

void setup() {
  pinMode(CLKpin, OUTPUT);
  pinMode(CSpin, OUTPUT);
  pinMode(DINpin, OUTPUT);
  //pinMode(pin1, INPUT); disabled since not attached
  //Serial.begin(9600); disabled since not sending data to serial monitor
  MatrixStartUp();
}

void loop() {


  for (int filmloop = 0; filmloop < numberOfFrames; filmloop++) {
    delay(fps);

    // while (analogRead(pin1) < 100 ) { } //Button press advances frame
    // delay(250);//Comment out these two lines for continous frames or if switch and pins for this are not attached


    for (int cell = 1; cell < 9; cell++) {
      Matrix(cell, film[filmloop][cell - 1]);

    }
  }
}
void MatrixData(unsigned char DATA) {
  digitalWrite(CSpin, LOW); //Set pin low so data is read
  for (int count = 8; count >= 1; count--) {
    digitalWrite(CLKpin, LOW); //Set pin low to put into buffer
    digitalWrite(DINpin, DATA & 0x80);
    DATA = DATA << 1;
    digitalWrite(CLKpin, HIGH); //Lock buffer

  }
}
void Matrix(unsigned char row, unsigned char column) {
  MatrixData(row);
  MatrixData(column);
  digitalWrite(CSpin, HIGH); //Set pin high to stop data read
}

//On initial power-up, all control registers are reset,
//the display is blanked, and the display is in shutdown mode
//So must set everything needed.

void MatrixStartUp(void) {
  Matrix(0x09, 0x00); //disables the internal max7219 decoder so values 0-7(data being sent)can be read
  Matrix(0x0A, 0x03); //sets display intensity 1-31
  Matrix(0x0B, 0x07); //tells chip the display is 8x8
  Matrix(0x0C, 0x01); //sets chip to operating mode
  Matrix(0x0F, 0x01); //tests display by lighting all LEDs....oddly this works without VCC and battery GND attached
  delay(1000); //Holds test output for one second
  Matrix(0x0F, 0x00); //Takes display out of testmode
}

The issue that pops up and what I would like to fix is when I create an animation that is a different frame amount of my previous animation.

What I would like to be able to do is paste in my frames(however many) then change my numOfFrames variable to match and be done.

The problem with that lies here

unsigned char *film[] = {frame1, frame2, frame3, frame4, frame5, frame6, frame7, frame8, frame9,
                         frame10, frame11, frame12, frame13, frame14, frame15, frame16, frame17, frame18, frame19, frame20,
                         frame21, frame22, frame23, frame24, frame25, frame26, frame27, frame28, frame29, frame30, frame31,
                         frame32, frame33, frame34, frame35, frame36, frame37, frame38, frame39, frame40
                        };

Right now I have to either add or delete members of the film[] as my number of frames changes.

What I would like to do is something like this

unsigned char *film[] = new unsigned char[numOfFrames];

for (int frameToFilm = 0; frameToFilm < numOfFrames; frameToFilm++){
  film[frameToFilm] = frame[frameToFilm + 1];
}

But there is lots wrong with that, and I don't know how to fix it.

First I am establishing the array incorrectly.

Second am trying to create a specific variable name (like frame1, frame2 etc) by attaching the current frameToFilm value to the end of frame and I can't seem to make the complier see frame1 == frame[a variable equal to 1]. Just get variable frame is not declared. So how would I attach the for loop value of frameToFilm to end up with frame1, frame2 etc being used?

And since I am here asking stuff anyway....
Anyone know of a way to clear the buffer inside the MAX7219?
Right now I have to write

unsigned char blank[] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0};

to the display to blank the screen.
I tried the sleepmode on it but it still remembers the previous frame it displayed when it wakes up.

1 Like

Looks to me you can just fix it with a multi dimensional array.

unsigned char film[][8];

and past all frames into into it.

film[0] = {0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81};
film[1] = {0x40, 0x01, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02};

numberOfFrames can be replaced by a define

#define numberOfFrames sizeof(film)/sizeof(film[0])

septillion:
Looks to me you can just fix it with a multi dimensional array.

unsigned char film[][8];

and past all frames into into it.

film[0] = {0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81};
film[1] = {0x40, 0x01, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02};

numberOfFrames can be replaced by a define

#define numberOfFrames sizeof(film)/sizeof(film[0])

Well first I tried this...just to see what it would do in an empty sketch

#define numberOfFrames sizeof(film)/sizeof(film[0])


unsigned char film[][8];

film[0] = {0x50, 0x81, 0x24, 0x1A, 0xA5, 0x00, 0x38, 0x00};
film[1] = {0x81, 0x42, 0x24, 0x00, 0x24, 0x42, 0x81, 0x00};
film[2] = {0x81, 0x18, 0x24, 0x00, 0x24, 0x18, 0x81, 0x00};
film[3] = {0x00, 0x81, 0x24, 0x18, 0xA5, 0x00, 0x18, 0x00};
film[4] = {0x50, 0x81, 0x24, 0x1A, 0xA5, 0x00, 0x38, 0x00};




void setup() {
  Serial.begin(9600);



}

void loop() {
  Serial.println = numberOfFrames;
  Serial.println = sizeof(film);
  Serial.println = sizeof(film[0]);

}

It resulted in the following error messages...

Arduino: 1.6.4 (Windows 8.1), Board: "Arduino Uno"

testingAdvice:4: error: storage size of 'film' isn't known
testingAdvice:6: error: 'film' does not name a type
testingAdvice:7: error: 'film' does not name a type
testingAdvice:8: error: 'film' does not name a type
testingAdvice:9: error: 'film' does not name a type
testingAdvice:10: error: 'film' does not name a type
storage size of 'film' isn't known

  This report would have more information with
  "Show verbose output during compilation"
  enabled in File > Preferences.

The one set of errors I kinda had an idea about so I tried this....

#define numberOfFrames sizeof(film)/sizeof(film[0])


unsigned char film[][8];

unsigned char film[0] = {0x50, 0x81, 0x24, 0x1A, 0xA5, 0x00, 0x38, 0x00};
unsigned char film[1] = {0x81, 0x42, 0x24, 0x00, 0x24, 0x42, 0x81, 0x00};
unsigned char film[2] = {0x81, 0x18, 0x24, 0x00, 0x24, 0x18, 0x81, 0x00};
unsigned char film[3] = {0x00, 0x81, 0x24, 0x18, 0xA5, 0x00, 0x18, 0x00};
unsigned char film[4] = {0x50, 0x81, 0x24, 0x1A, 0xA5, 0x00, 0x38, 0x00};



void setup() {
  Serial.begin(9600);



}

void loop() {
  Serial.println = numberOfFrames;
  Serial.println = sizeof(film);
  Serial.println = sizeof(film[0]);

}

Which left me with

Arduino: 1.6.4 (Windows 8.1), Board: "Arduino Uno"

testingAdvice:4: error: storage size of 'film' isn't known
storage size of 'film' isn't known

But as a member of the already type defined film array I should not need to redefine the type each time I write in a value. So I assume it is throwing the errors on the first code example about undefined type because it is basically ignoring the unsigned char film[][8]; once it gets an error about the unknown size and moving on to the next line.

So what am I messing up here?

unsigned char *film[] = new unsigned char[numOfFrames];

This looks wrong to me.

a char string can be considered as either an array or a pointer, but you don't define it as both.

michinyon:

unsigned char *film[] = new unsigned char[numOfFrames];

This looks wrong to me.

a char string can be considered as either an array or a pointer, but you don't define it as both.

I said it was wrong, so yes it should look wrong :wink:

It was an example of the thinking behind what I am trying to get done...an array where the size is the value of a variable. It doesn't work without the little pointer symbol either.

I am trying to figure out if what I want to do is possible in C++ and giving examples of what I have tried already since often I see on other posts replies like "What have you tried so far?"

Delta_G:

unsigned char film[][8];

This line won't work. If you want to declare the array and then fill it, then you have to tell the compiler how many elements it should have. If you want to leave the number out of the brackets and let the compiler figure it out, then you have to fill the array on the same line so the compiler will know what number to pick.

Eg:

int myArray[] = {1, 2, 3, 4, 5};   // Works because the compiler can see it should be five elements

int another[5];    // This all works because the compiler knows that there are to be 5 elements
another[0] = 1;  // And you can set them up later
another[1] = 2;
another[2] = 3;
another[3] = 4;
another[4] = 5;

int badIdea[];  // Doesn't work.  The compiler has no way to know how big to make badIdea.

Can you please show me an example using a multidimensional array like what I am using in my code?
I am not trying to place a single int value in an array. I am placing arrays into an array.
Using your example what I want to know how to do is...

unsigned char badIdea[int variable declared elsewhere][8];

Delta_G:
First of all, to do this the variable used to size the array MUST be constant. You can't have an array whose size is subject to change.

Second of all, instead of me writing out all the ways to define a 2D array, why don't you ask google? There are literally thousands of C++ tutorials on the subject.

The obvious way is to do this:

int my2Darray[][4] = { {1,2,3,4}, {5,6,7,8}, {9,10,11,12} };

and that will create an array of 3 arrays with 4 elements each.

There are plenty of other ways to do it, but I'm not about to try to list them all because I'm not where I can test any code and I don't want to mess up syntax somewhere. Probably the better idea for your code is to define your different 1D arrays and then make another 1D array of pointers to those arrays. Again, google will have tons of tutorials that will show the right syntax to do that.

Did you read and look at the working code in my first post?
Specifically where I pointed out the 1D array of pointers to different 1D arrays that I am trying to make easier to modify?

This thingy here..

unsigned char *film[] = {frame1, frame2, frame3, frame4, frame5, frame6, frame7, frame8, frame9,
                         frame10, frame11, frame12, frame13, frame14, frame15, frame16, frame17, frame18, frame19, frame20,
                         frame21, frame22, frame23, frame24, frame25, frame26, frame27, frame28, frame29, frame30, frame31,
                         frame32, frame33, frame34, frame35, frame36, frame37, frame38, frame39, frame40
                        };

Unless I am misunderstanding you (which is very possible) you are basically suggesting the way to write my code is the way it is already written in the working example. Is this true?

If so it seems my only alternatives are to either:

A. Keep doing it the way I am currently which is manually adding or deleting frames in the code snippet above. So if my next animation is only 30 frames I have to manually delete frame30-frame40. Or if my next animation is 60 frames I have to manually type in frame41, frame42, frame43.....frame60 to the code snippet above.

B. Determine the absolute maximum frames I will ever want to do and create that many in the pointer array but with values for a blank screen
frame100[] = {0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0}
and just don't loop through the extra unneeded frames. Which would break when I made a smaller animation after a larger one unless I manually refilled the blank frames.

Both those alternatives seem very inefficient.

Would think there has to be a better way to accomplish this.