Go Down

Topic: ShiftMatrix, Dreaming Big Video Display (Read 22656 times) previous topic - next topic


would be nice to see some pictures of the setup ^^


yeah I'd love to see a video of the color, even if you do think it's not that great yet, just to see where you are.  very impressed. This is way above my head at the moment.


Alright, video it is!

I am not sure if you will be able to make it all out as I filmed it close up with a piece of paper as a diffuser. Here is the way it looked when I first connected it up. This is using the same scaling that is in the Bad Apple video (The all red one). It is simply reading the RGB values as 0-255 and dividing by 8 to get 0-31.

As I posted before I was very disappointed with the above result. Everything was washed out and it was hard to make out what was being drawn to the matrix. I did a lot of research and changed the way it output values. It still gave me value between 0 and 31 but it weighted it differently. Its difficult to explain but simply our eyes are better at discerning the difference between PWM 1 and PWM 2. But now so good at seeing the difference between PWM 30 and PWM 31(this is using my 32 level system, this also holds true on 0-255 PWM systems). So with adjustments made the results look like this.

This looked a lot better. It should be a lot easier to make out the red for example in the video above than the one above it.

I know I haven't put up the processing code yet. I have done HEAPS of tweaking to it over the last month. Hopefully I am close to posting it soon. But here is a quick video of what I show on the screen. I allowed me to get things setup correctly even without having the Arduino and the matrix hooked up.

In the top left is the original frames playing in their native size. Beside that is the down-scaled version, in this case it is 16x16 then doubled in size so you can see it. Below those is a representation of what should be output to the RGB matrix display.

As an aside, when I post up the processing code would you prefer it for single colour or RGB, as they are a bit different? Or would you prefer to see both?

I am now ready to move out of testing and to start building the large scale matrix itself. As I said before I am planning to go 64x64 mono. But I am scared that it will be huge(I was planning to use Peg Board as a pre-drilled base board) as it is looking like it will be about 2m x 2m in size. I might chicken out a bit and bring it back to 48x48 mono.....just not sure. Pricing lots of LED's now. I don't suppose anyone knows a good source for 4500 LED's at a cheap price, for delivery to Australia. Other than Ebay that is.
So any other comments or queries?


That looks really good.  Nice work.  I am not sure about large lots of LEDs other than the usual suspect(ebay).    That's going to be a hell of a build though.  Get some friends, and make a weekend of it ;-)


For anyone who is interested I have attached a Fritzing image of how the RGB Matrix in the above posts is actually setup. I have recieved a few queries about how the shift registers are connected to the Arduino, so I hope this helps people. It shows that there are two sets of DATA, CLK and Latch that come from the Arduino.

As I have said in other posts the IC's I have used are MBI5026 (16ch, constant current, serial in Parrallel out) and the PNP transistors were rated up to 1.5amp. Capacitors are 0.1uf Ceramic type. Resistors are for IREF of the IC's (currently I am actually using a trimpot on each IC)

I have omitted the connections from the IC's to the columns of the Matrix. Also missing are the wires from the Row IC to the PNP transistors as well as the connections from the transistors to the Rows. This is simply because there would be A LOT of wire and if would acutally make it more difficult to follow what is going on and how it is setup. (about 90 connections omitted, not including the connections not shown to form the 16x16 matrix) If you are going to attempt something like this on breadboard be prepared to be sitting there wiring it up for a LONG time!


How did you wire/address the RGB groups? Did you connect them to the registers as RGBRGBRGB?


Yeah, for my own sanity I kept it the same. Essentially my Processing program sends a giant byte array down the serial line in RGB. The Arduino catches it and puts it (in the same order) directly into the array that is setup for the LED brightness values.


Wow man, this is looking quite amazing already! I'm busy the the same thing apart from the controlling, im using 8 74hc595 shift registers and arranged them like this:
Code: [Select]

[rows 1-8 v+][rows 9-16V+]
[cols red 1-8 gnd][cols red 9-16 gnd]
[cols green 1-8 gnd][cols green 9-16 gnd]
[cols blue 1-8 gnd][cols blue 9-16 gnd]

However im still not getting the code working the way i want it to but im understanding it more and more and this thread is also really helpfull as it gives you a lot of info!


Thanks Xforce. Its good to know that this information is helping others. I don't think that what I am doing is particularly hard its just very time consuming. I have a basic grasp of electronics and I try to be very thorough. (I have been planning to do this for over a year) All the heavy lifting of making this work has been done by ElcoJacobs and the ShiftPWM\ShiftMatrixPWM library's that he created. I think if it weren't for him I would still be trying to write a basic 8x8 pwm matrix routine. His library means you can just add the components and tell it what to do. This has allowed me to focus on getting the information I want streamed to the device. As long as I send it the right info, it does exactly what I want. In my case this meant grabing video frames and converting them to a serial data stream and sending it to the Arduino. And really its been as simple as that.

All I am trying to do is show others how I achieved it, hopefully with enough info to replicate it if they would like to. What I have accomplished with this project has only been possible due to the huge amount of information on these forums and in the tutorials that people have made. At some stage I will draw up a "Step by step" of how this all went together. I have my Proccessing code commented and nearly ready to share (I think :)) which should be the final piece to having the ability to make what I have made so far.

With regard to my code for processing, I have two different sketches. One for sending a RGB colour byte stream and one for sending an averaged mono byte stream. Which would you prefer to see? Or would you like both? Or should I put a switch in the code so that it could do either?

Hmmmmm it always seems like there is something else to do to the code! Haha
If there is anything else you guys are after just let me know. I will try and help if I can.


Hey man,
I'd be great if you could do the switch one so i can get an idea of your way or programming and thinking. and i think im also gonna focus more on trying to get Elco Jacob's library to work cus that would probably be easier than trying to write some routine myself ^^. I don't mind on how you'll send me the code, via pm or you post it here, you decide (which is rather logical as you're the one who made the processing sketch:P).


I'd be great if you could do the switch one so i can get an idea of your way or programming and thinking.
Yeah thats what I decided on so I spent some time reworking it so that it would work either way. I also added a switch so you could just run it onscreen and not actually output the serial, this made testing parts of the code much quicker. I have tried to comment as fully as possible, I have probably gone overboard :D. Let me know what you think. The Arduino part of the code is already up in other posts in this thread.
Code: [Select]
* ShiftMatrixPWM Serial Video Transmit for Processing
* by Richard Black
* Built-in video library replaced with gsvideo by Andres Colubri
* Get it from: http://gsvideo.sourceforge.net/
* Loads a video file and downscales the frames and sends them
* via Serial to an Arduino setup with the ShiftMatrixPWM Library.
* For the Arduino, found at: http://arduino.cc/forum/index.php/topic,66988.0.html
* This displays three images in the window. The original, the down
* scaled and the final output. This code has been setup to work with
* video's in 4:3 ratio but you could adapt it for other ratios.
* It is currently set to output 32 levels of brightness. This can be changed.

import codeanticode.gsvideo.*;
import processing.serial.*;

//currently I am building a square matrix. I left seperate height and width
//for future possible use.
boolean ColourMatrix = false; // true for colour, false for Mono
boolean OutputEnabled = false; // true for serial out, false no serial out(on screen only)
int mpHigh = 64; //Number of Rows High the Matrix is.
int mpWide = 64; //Number of Columns wide the Matrix is.
int movRate = 40; //Set the number of frames per sec to process
String comPort = "COM5"; //Set what port the Arduino is on
String movFile = "video.mp4"; //set which file to play. This needs to be in the projects data folder
int brightLevel = 32; //This is the number of levels required. On the Arduino this would be 0-31
//using this code bightLevel should be a multiple of 8 so it can be cleanly divided into 256 as further down
//SETTINGS END HERE!!!!!!!!!!!!

Serial matrixPort;
GSMovie theMovie; //Creates the GSvideo Movie object.
PImage smallFrame = new PImage(mpWide, mpHigh);
color pixelclr; //this is for color setup
int pixelbright; //this is for mono color setup
byte [] myFrame;
PFont font;
int divider = 256 / brightLevel; //This allows calculating the brightness levels in the code

void setup() {
size(1000, 400, P3D);
if (ColourMatrix==true){
  myFrame = new byte[mpWide*3*mpHigh];
} else {
  myFrame = new byte[mpWide*mpHigh];
matrixPort = new Serial(this, comPort, 250000);// Initialise com port replace with your speed
frameRate(movRate);//framerate set above in settings
theMovie = new GSMovie(this, movFile); //Initialises instance of the movie
theMovie.loop(); // I have it looping. You can comment this out if you don't want looping
//theMovie.play(); // Use this to have the movie only play once. No Repeat.
font = loadFont("DejaVuSans-24.vlw"); //Change to whatever font file you have otherwise, comment out
//comment out the next five lines if there is no font or above is commented out
fill(0, 102, 153);
text("Original", 15, theMovie.height+20); // Label
text("Down Scaled", theMovie.width+20, (smallFrame.height*2)+20);// Label
text("Output", theMovie.width+20, (height/2)-10);// Label

// Read new values from movie
void movieEvent(GSMovie m) {
  m.read();// Reads in the new Frame of the movie
  //This next line takes the movie frame and resizes it into a smaller PImage object.
  smallFrame.copy(m, m.width/8, 0, int(m.width-(m.width/4)), m.height, 0, 0, smallFrame.width, smallFrame.height);
  //This also only gets the center part of the video as the ratio is not a perfect
  //square. The left and right edges get trimed. Currently this is set for 4:3 ratio to square (ie the matrix)

// Display values from movie
void draw()  {
  image(smallFrame,theMovie.width+10,0,smallFrame.width*2,smallFrame.height*2); //Draws the small Frame
  //image(theMovie,0,0,theMovie.width/2,theMovie.height/2); //Draws the full movie Frame, half size optional
  image(theMovie,0,0);//Draws the full movie Frame
  for (int y = 0; y < smallFrame.height;y++) {
    for (int x = 0; x < smallFrame.width;x++) {
      if (ColourMatrix==false){
        pixelbright = int(brightness(smallFrame.pixels[(y*smallFrame.width)+x])/divider);
      } else {
        pixelclr = smallFrame.pixels[(y*smallFrame.width)+x];
        if (red(pixelclr)/divider < 1) {
        } else {
        if (green(pixelclr)/divider < 1) {
        } else {
        if (blue(pixelclr)/divider < 1) {
        } else {
      //The ellipse is for drawing the supposed output using the colour/brightness from the Fill above
  //println(myFrame); //used to print frame data to the output panel, good for testing
  if (OutputEnabled==true){
    matrixPort.write('~'); // start Character. If using 127 levels you will
    //need to change the start Character to some higher ascii value.
    matrixPort.write(myFrame); // the frame data
So next part for me is making it split the output into sections so I can run a modular matrix.
But this does run my 16x16 RGB matrix just as is. Hope this makes sense to people. :)


Thanks for the code and all the comments, when i've got the time (its busy again at the university ^^) ill look through it and let you know what  think but i'm quite sure ill understand how it will work, seeying the amount of comments! =).


i try to transfer my frames data same as you from processing (but the pwm process not based on the shiftmatrix library) and i have trouble to get the right data with arduino because i think my pwm interrupt process is bothering the Serial interrupt process. (have missing bytes etc.)
dont you experienced this or any kind of trouble related to the above listed issue?


Hello adamtoth,

It seems I forgot to mention that I am sending the data at a higher rate then standard. This was worked out via trial and error to find a stable rate that worked for me.

I found recieving data to be a little tricky. I would suggest trying the method I have used (earlier in the thread) that had a counter incrementing with each byte that came in.

If this doesn't help, I would recommend starting a thread and posting up some of the code you are using.


I am now ready to move out of testing and to start building the large scale matrix itself. As I said before I am planning to go 64x64 mono. But I am scared that it will be huge(I was planning to use Peg Board as a pre-drilled base board) as it is looking like it will be about 2m x 2m in size. I might chicken out a bit and bring it back to 48x48 mono.....just not sure. Pricing lots of LED's now. I don't suppose anyone knows a good source for 4500 LED's at a cheap price, for delivery to Australia. Other than Ebay that is.
So any other comments or queries?

Great thread. I'm working on quite an ambitious project myself and I will definitely be coming back to this thread for advice. Thanks for sharing and for the videos!

If you're ordering 4500 LEDs, maybe you should look into just ordering them directly from the factory in China through alibaba.com
I think the minimum order is 10,000 with most places...but something to look into.... maybe you could just sell the rest on eBay.

Go Up