32x32 led ghetto matrix :)

Just for the sake of "I wanted to" presenting

a 32x32 dot matrix panel! ;D

this is a shoestring budget, proof of concept... mostly for code exploration and speed measurements, and again I just wanted to

The current circuit itself is rubbish, starved leds and over driven chips guaranteed for a short life time, so I dont plan on releasing much construction details, but get 2 595, and a 8x8 and multiply

But! it allows me to decide how far down this path I want / need to go, and even if the components are weak it can be beefed up easily, and the current idea is sound and works great

Running a matrix this large (1024 leds) very quickly pushed me out of shiftOut, 64 bits of data are sent to the registers using the ATmega's hardware spi feature

Instead of running the matrix 1 led at a time, were doing 1 line at a time, which reduces on time from 1:1024 to 1:32 (and is overloading each 595 by 20ma, so you can place bets on how long it will last), current requirements are increased everywhere in the display, but clocking in a line of display @ 782khz (with no real cpu load) does open up some interesting ideas, or if nothing else you know if the screen flickers its not the display code!

anyway enough yabber, here is some pictures from tonight, the first time it is displaying bitmap images (made in the gimp)

3 wire n power

and of course, I provide a easy to follow wiring diagram

Awesome, Osgeld! What if you stacked a second 595 on each of the current ones (soldering the pins together)? Provided your power supply is beefy enough to handle it, doing so should double the current capacity, right?

yes, and the idea keeps popping in my head along with I have most of a tube of 595's left, I might as well at least try it
:wink:

power supply is beefy enough, I was aiming for 20ma per row and with the chips eating some voltage up they are running ~10ma per row @ (jeez I forget the exact number) 3.7x volts

original calculations were at worst case and the whole thing opened up that I am ok but pumping some heat out of that 7805 hence the big heatsink which under a test load kept the whole thing not scalding hot with 9v in and 800ma out

OK went and tried piggybacking, at first just a friction fit test, and yes the difference is great enough to matter

the leds are running at their intended value 15ma, instead of 10, and the entire screen seems more even (not perfect but better) along with the registers sharing current load

worst case and all leds are on at once and stuck, its around 640ma, which is enough to start getting that regulator + heatsink warm with 9v input

so I went back and soldered them, kludge yes, works yes, I know it looks bad on such a thing of beauty ;D and all but ...

Glad to hear it worked! I am really surprised you didn't smoke that thing first run - it looks so great. Where did you get the panels, if I may ask?

So far I have only found Sparkfun here in the US selling them (everyone else I have checked so far only has 5x7 matrices). I am wondering if there is a cheaper supplier (although Sparkfun's are pretty cheap already).

I am more curious than anything else; its not like I am planning my own panel except in my dreams.

What do plan on doing with it (it would make a nice wall display - maybe go wireless?)...?

:slight_smile:

got them from ebay; I dont recall exactly where, but TchnclFl found them, maybe he knows, they cost like 12 bucks for 10 with in states shipping by barebones mail

they are cool as tiny 8x8 panels, they have the same dot pitch as a usual size 5x7 which is nice

As far as smoke, well ... the first time I had the entire display on at once was a good smoke test, and I stood by with expectations and a razor saw to cut a bad chip out, but no it took it, for quite a few evenings, no dobut it could take it for quite a while longer, then die, it would have died eventually

Oh also future plans are an entirely different subject for a future date, I have to clean code, optimise and start testing the next layer of ideas and repeat, then I should have a clearer idea

[edit]i have a nes controller, I should slap pong on it at least heh[/edit]

and of course, I provide a easy to follow wiring diagram

Osgeld,
Following your diagram, I successfully toasted all my 595 chips. :wink:
Seriously, though, that's a pretty awesome handbuilt matrix!

lol and thanks!

nice build, and the wiring diagram is so easy to follow ;D

you could put some heatsinks (the fancy ones for your pc memory) on the chips, would help a bit and makes it look even more crazy :wink:

Cool matrix!

In stead of stacking the 595's you can replace them with some shiftregisterss that can handle the curent like these:

Of course they are more expencive than 595's but you can find them at a little over 1$ a piece, and cheaper in quantities.

nice build, and the wiring diagram is so easy to follow Grin

thanks, and isnt it?

you could put some heatsinks (the fancy ones for your pc memory) on the chips, would help a bit and makes it look even more crazy Wink

actually they were not heating up at all

Cool matrix!

thanks!

In stead of stacking the 595's you can replace them with some shiftregisterss that can handle the curent like these:

lets say this becomes the must have arduino accessory of the decade, then yea I will probally use proper drivers in the design, this was more or less just to play with (and everything is already soldered ;))

Very cool! I was planning on doing something like this on a smaller scale (I don't have enough '595s)! ;D

TchnclFl found them, maybe he knows

Sure thing. Here's a link. They were on sale when I bought them, now they're 16 bucks. Still not a bad deal :).

EDIT: Actually, those are bicolor. I don't think they sell just the red anymore..

Futurlec has a 8 by 8 matrix with square leds for 1.80 us$

FCB electronics is a good USA ebay seller. They have inexpensive items with fast and FREE shipping. I bought the smaller version of the matrix from them so I can fit more on a breadboard. I don't have Osgeld's high precision ninja soldering skills. :slight_smile:

Scroll down a little bit on this page:
http://cgi.ebay.com/ws/eBayISAPI.dll?ViewItem&item=150386988451

I don't have Osgeld's high precision ninja soldering skills.

actually most of it is wirewrap, everything is soldered to the board, and just the power and ground to the chips are actually soldered into place

but thanks I do try my hardest on ninja soldering :slight_smile:

PS: yea those are the same matrices that I am using, but they only have the dual colors in stock as noted above

I am working on a led matrix project, and I have had no luck finding code that works for the setup that you have (595's without specialized led driver chips). I am trying to get this project done in 2 days for an event coming up, and I would appreciate it if you posted the code you used or sent it to me directly. I found sample code from Earthshine Design's tutorials, but it does not seem to work and I have quadruple checked the wiring!!!

Please post the code! Thanks. ;D

BTW I already have 20 8x8 matrices and quite a few 595's, but I just dont have the money for 20 Max 7219's!

how many led's, this screen is big enough where I had to do some voodoo to get it to refresh quick enough, where as a 8x8 or a 16x16 you can just use shift out

I will post in a bit, I have to go to the other room and fire that pc up, but its really just slapped together and I doubt it would do much except confuse you (which is fine cause then we can move onto theory lol)

I mashed it all into 1 file and added some comments

// 2k10 OSGELD

// i am scanning by row (instead of normal pixel by pixel), which overloads the 595's
// there are 2 595 per row / col piggy backed on eachother in a kludge to bring 
// it more in spec, your results may vary

// this array of bytes is used to keep track of where
// we are, X is the first 4 bytes these are columns
// combination of those 32 bits repersent what pixels 
// are lit for every row.

// Y is the last 4 bytes in the array, 
// each of the 32 bits is toggled on one at a time in order

// !be careful on your wiring!

// its still backwards on mine so i start with lsb and shift left
// instead of to the right which would have made more since
byte screenBuffer[8] = 
{
  B00000000, B00000000,
  B00000000, B00000000, 
  B00000000, B00000000, 
  B00000000, B00000000};
  
void setup() 
{
  // setup pins for screen (595's)
  // enable the atmega 328s hardware spi port
  screenInit(); // delay 10
}

void loop() 
{
  // update the screen as fast as it can
  bitmapUpdate();
}
///////////////////////////////////
// enable the atmega 328s hardware spi port
// this can be found on the fourm
void screenInit()
{
  DDRB = DDRB | B00001101; 
  // screen must be on pins
  // 10 latch
  // 11 data
  // 13 clock
  
  // setup hardware spi
  byte clr;
  SPCR |= ( (1<<SPE) | (1<<MSTR) ); // enable SPI as master
  SPCR &= ~( (1<<SPR1) | (1<<SPR0) ); // clear prescaler bits
  clr = SPSR; // clear SPI status reg
  clr = SPDR; // clear SPI data reg
  SPSR |= (1<<SPI2X); // set prescaler bits
  delay(10);
}

// what you use to send data to the screen
void screenFlip()
{
  screenOn(false); // turn off latch
    //x
    screenOut(screenBuffer[3]);
    screenOut(screenBuffer[2]); 
    screenOut(screenBuffer[1]); 
    screenOut(screenBuffer[0]);
    //y    
    screenOut(screenBuffer[7]); 
    screenOut(screenBuffer[6]); 
    screenOut(screenBuffer[5]); 
    screenOut(screenBuffer[4]);
  screenOn(true); // tun on latch, showing screen
}

void screenOn(boolean ON) // toggle the latch
{
  if(ON) bitSet(PORTB, 2); // HIGH
  else bitClear(PORTB, 2); // LOW
}

// hardware send data to screen
// stripped down version of what you would
// find on the hardware spi fourm topics
void screenOut(byte data)
{
  SPDR = data;                    
  while (!(SPSR & (1<<SPIF))){}   
}
///////////////////////////////////
// bitmap data, original file pbm image format saved in ascii
// as text 1's and 0's from the gimp, arduino formatted with 
// a little hand magic in notepad ++
byte mac[32][4]  =
{
  {B00000000, B00000000, B00000000, B00000000},
  {B00111111, B11111111, B11111111, B10000000},
  {B01100000, B00000000, B00000000, B11000000},
  {B01000000, B00000000, B00000000, B01000000},
  {B01000111, B11111111, B11111100, B01000000},
  {B01001000, B00000000, B00000010, B01000000},
  {B01001000, B00000000, B00000010, B01000100}, 
  {B01001000, B00000000, B00000010, B01000010}, 
  {B01001000, B01000100, B01000010, B01001000},
  {B01001000, B01000100, B01000010, B01001010},
  {B01001000, B00000100, B00000010, B01010010},
  {B01001000, B00000100, B00000010, B01001001},
  {B01001000, B00001100, B00000010, B01010110},
  {B01001000, B00000000, B00000010, B01001010},
  {B01001000, B00100001, B00000010, B01010101},
  {B01001000, B00011110, B00000010, B01011011},
  {B01001000, B00000000, B00000010, B01001101},
  {B01001000, B00000000, B00000010, B01010110},
  {B01000111, B11111111, B11111100, B01011011},
  {B01000000, B00000000, B00000000, B01011101},
  {B01000000, B00000000, B00000000, B01010111},
  {B01000000, B00000000, B00000000, B01011011},
  {B01000000, B00000000, B00000000, B01011101},
  {B01000110, B00000000, B01111110, B01011111},
  {B01000000, B00000000, B00000000, B01010111},
  {B01000000, B00000000, B00000000, B01011101},
  {B01000000, B00000000, B00000000, B01011111},
  {B01111111, B11111111, B11111111, B11011111},
  {B00100000, B00000000, B00000000, B10011011},
  {B00100000, B00000000, B00000000, B10011111},
  {B00111111, B11111111, B11111111, B10011111},
  {B00000000, B00000000, B00000000, B00011111}};

void bitmapUpdate()
{
  int x; // col counter
  int y; // row counter
  for(y = 0; y < 32; y++) // for 32 rows do...
  { // 32 rows + each row is comprised of 4 bytes of X on off data so...
    for(x = 0; x < 4; x++) 
    {
      screenBuffer[x] = mac[y][x];
      // read the current row X data into into the screen buffers 0-3
    }

    // after the X data for the row is in the buffer
    // we need to format the row position data for the 595's,
    // only 1 line at a time means we have to shuffle a
    // single bit though 32 bits(over the last 4 bytes of the buffer array)
    switch(y / 8)
    {
      case 0: // ie 3 / 8 = integer 0
        if(screenBuffer[4] == 0) // see if the first 8 rows is turned off
        { // if so
          screenBuffer[7] = B00000000; // turn off the last 8 rows
          screenBuffer[4] = B00000001; // set the first bit to one, mines backwards
        }
        else // if not
        {
          screenBuffer[4] = screenBuffer[4] << 1; // shift the bit one space, or to the next row
        }
      break;
      // repeat 7 more times 
      case 1:
        if(screenBuffer[5] == 0)
        {
          screenBuffer[4] = B00000000;
          screenBuffer[5] = B00000001;
        }
        else
        {
          screenBuffer[5] = screenBuffer[5] << 1; 
        }
      break;
      
      case 2:
        if(screenBuffer[6] == 0)
        {
          screenBuffer[5] = B00000000;
          screenBuffer[6] = B00000001;
        }
        else
        {
          screenBuffer[6] = screenBuffer[6] << 1; 
        }
      break;
      
      case 3:
        if(screenBuffer[7] == 0)
        {
          screenBuffer[6] = B00000000;
          screenBuffer[7] = B00000001;
        }
        else
        {
          screenBuffer[7] = screenBuffer[7] << 1; 
        }
      break;
    } // end switch  
    screenFlip(); // show screen
  } // end y for loop   
} // end function

// wait for next call

Thanks so much! I'm trying to make a Daft Punk helmet replica (the gold one) and I am planning on having 5 8x8s tall by 4 8x8s wide for a total of 20 8x8xs with 40 pixels tall by 32 wide. I'm gonna go look through that code (Im horrible at code but decent with circuits) and figure out how to manipulate to the size I need. Im thinking Im gonna have to a a transistor for each row, but we'll see. ;D I know this is really complicated for a first foray into Arduino, but I bought all the parts so Im kinda committed.... :stuck_out_tongue:

Actually, I think im gonna shrink it to the same size as yours so I dont have to modify anything!!!!! (4 8x8s by 4 8x8s)