Go Down

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


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