display Sprites on a 8x64 led matrix?

Hi -

I have wired up 8 MAX7221's to 8 8x8 led matrices and I am able to address the 8 matrices separately using the tomek ness code. However, I find it difficult to address the leds the way I'd like (e.g. as 8 64 led columns) because of how that code works. I have made some progress but it is a little messy.

I prefer the simplicity of the Sprite Animation example that comes in the Matrix library, just build 8 bit masks (B01010101) and load them in. How could I modify the code below to make it possible to address 8 matrices stacked on top of each other as one 8 x 64 sprite? Or as 8 1x64 sprites? Ideally I would like to just load 64 B11111111's instead of the 8 as in the example below. I'm pretty sure I have to modify the Sprite or Matrix library to handle this but I'm not sure where to start. Any help appreciated. Actually what would be really cool would be able to load in a 64 character string that represents the ons and offs of a single column.

// Sprite Animation
// by Nicholas Zambetti <http://www.zambetti.com>

// Demonstrates the use of the Matrix & Sprite libraries
// Displays animated waveform graphic on screen

// Created 29 March 2006

/* create a new Matrix instance
   pin 0: data  (din)
   pin 1: load  (load)
   pin 2: clock (clk)
*/
Matrix myMatrix = Matrix(0, 2, 1);

/* create a new Sprite instance
   8 pixels wide, 8 pixels tall
*/
Sprite wave = Sprite(
  8, 8,
  B00011000,
  B00100100,
  B01000010,
  B10000001,
  B00011000,
  B00100100,
  B01000010,
  B10000001
);

void setup()
{ 
}

int x = 0;

void loop()
{
  myMatrix.write(x, 2, wave);     // place sprite on screen
  myMatrix.write(x - 8, 2, wave); // place sprite again, elsewhere on screen
  delay(75);                      // wait a little bit
  myMatrix.clear();               // clear the screen for next animation frame
  if(x == 8)                      // if reached end of animation sequence
  {
    x = 0;                        // start from beginning
  }
  x++;                            // advance x coordinate to the right
}

I actually have 16 columns total but they are wired together in banks of 8, so I will control those with 3 other pins and their own matrix.

I havent looked at the Sprite stuff yet but my own project will be dealing with 8x8x3 so I'll need something similar.

I'm confusing myself with the datasheet for the MAX7219 so I'll look at it again tomorrow.

You'll be using a lot of memory however.
I think the minimum you'll get is 64 bytes per frame for a display with 512 pixels (did I do my maths correctly?).

Well I have been managing to get the tomek code to work on my 8x64 display but it is frustrating. The issue is that I want to be able to have each 64-led high column change independently of the next, but since each adjacent 8-led segment is part of the same 8x8 matrix, turning on an led turns off all the other leds in that row. So I have been writing logic that works around this by doing pseudo bit math on the rows, but it is rather torturous. In short, to change one pixel on one row, I have to re-draw the entire affected row. I think I need an array to track the current values (like the Sprite code probably does) of all the rows, and then update each row only as needed. But how do I keep track of it all? I am looking at the Matrix and Sprite libraries but this is right at the limit of my programming abilities. I kinda get it, but implementing it is proving difficult.

Can anyone suggest a reference that might help me learn more? Or step me through the Matrix/Sprite code a bit so I can modify it for my purposes? One approach would be to make one big 8x64 sprite, and have it cascade onto all 8 grids instead of just one. But then I have to refresh the whole matrix every time. I I can figure out how to send a sprite to a specific matrix/7221 then this would be more efficient...

So what I really need to understand is the bit that makes the tomek code address different 7221's, then I can adapt the Sprite code to do this, too.

Can I create multi-dimensional arrays in arduino/wiring? If so is it the same syntax as C? e.g.

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

Or maybe I instead create an array of character strings, like:

char string1[ ] = "01010101010101010101";
char string2[ ] = "101010 etc.

where each string represents the state of each 16 led row. Then I can scan the array for differences before each refresh and be strategic about updates.

Please let me know if I'm on the right track, or re-inventing the wheel.

PS regarding memory I actually just upgraded to a Wiring board so now I have 128K to work with, right?

Or step me through the Matrix/Sprite code a bit so I can modify it for my purposes?

Its basically exactly what you are thinking of except it uses a one dimensional 'array' (it technically is just a memory block) instead of a two dimensional array.
All those bit shifts are converting it in to a human understandable format.

Internally from the memory's point of view, its just a long string of bits where 1 = on and 0 = off.
Pixel 1x1 is first, 1x2 is second, etc... and it wraps around for the rows.

Your going to have to either use a similar concept (which becomes interesting with more than 8 wide) or use a 2d array.
I'm not entirely sure what the downside of the array is. Probably less efficient.

Oops sorry I was adding to that post above while you were replying.

Or maybe I instead create an array of character strings, like:

char string1[ ] = "01010101010101010101";
char string2[ ] = "101010 etc.

where each string represents the state of each 16 led row. Then I can scan the array for differences before each refresh and be strategic about updates.

I'd probably use a 8x8x8 array (or something similar - I can think of more compact methods), identical to the physical layout of your board.
Then I'd have a array with 8 entries for keeping track of what needs updating.
If you update block 4 for example, you change it's entry in the array from 0 to 1.

That way you can quickly determine what needs updating.

PS regarding memory I actually just upgraded to a Wiring board so now I have 128K to work with, right?

Thats flash, not ram. I'm not sure how well it would swap necessary data in and out of ram.

Well if thats made any sense to you then great.
If not, I'll read it in the morning and correct myself. Getting tired. :slight_smile:

It's still morning here so my mind is ticking along. Thanks, that is kind of what I was thinking: a second 2x8 array to track which matrices need updating.

Now I need to learn up on how to say "point to this 7221".

Update in the afternoon:

So I can express an entire 8x8 matrix as 8 values, aka a Sprite, and save these as a long comma-delimited string [252,188,28,29,29,27,25,17] where each number represents a row's pattern. Save these into a character array that is the "meta" matrix. The location in the meta-matrix correlates to the physical layout of the matrices. Each string represents the current state of that matrix. Read them out again to refresh the display. I guess I'll have to iterate through each string parsing out the values - seems like it might be slow. Guess I'll try it and see. But I'm sure there's some more elegant way to do this - bigger array?

Oh and I realize I might be confusing things by talking about a 16-wide led array - actually the device has got a total of 16 7221's controlling 16 columns but it's wired as two groups of eight, so I can address the left and the right halves independently. I only have bought 8 of the total 16 7221's so far so I can only play with half the display right now.

I guess I'll have to iterate through each string parsing out the values - seems like it might be slow. Guess I'll try it and see. But I'm sure there's some more elegant way to do this - bigger array?

You should make the computer do the hard work preferably and make it send the raw binary.
Instead of sending the numbers as ASCII, just convert them to bytes. That means less manual parsing.

Yes this is the approach the monome uses - 2 bytes serial encoded and then a software bitstream to OSC/MIDI app. I would like my controller eventually to send OSC and MIDI natively - but will use Max or a similar app to do this for now. I might need some more horsepower to send OSC, not sure. Maybe send my control voltages to a CV synth, too if I can get my hands on something.

Monome uses lots of bitwise math in their firmware and software which I am just getting the hang-of; it is very elegant but hard to grasp intuitively. Drawing lots of little grids has helped.

And now I see why they use it - it's a no-brainer for signal-intensive hardware where you need to optimize everything.