RGB Panel Jumbotron

Pages
Contributors: b_e_n
Favorited Favorite 7

Processing Code

Below is the Processing code in its entirety - BUT - there are a few lines you will most likely need to change, so hold your horsies for a minute.

This line, where we choose our serial port:

serialPort = new Serial(this, Serial.list()[5], 500000);

will need to reflect the actual serial port your Teensy 3.1 is connected to. So you'll want to replace the '5' in brackets with the number reflective of the array index belonging to your port, which is to say: running this code will cause Processing to print out a list of serial ports, and you need to pick the place in this list that your Teensy is connected to, starting from zero (because it's an array).

Here's a screenshot from my computer - the Teensy is on /dev/tty/usbmodem40671 - so I count from zero from the upper left and get 5, which is why there's a 5 in my code. Make sense? Yeah, me neither.

alt text

We need to go through a similar process with picking the port our USB webcam is connected to.

cam = new Capture(this, cameras[3]);

In this case, you would want to replace the '3' above with the place you find something like 'USB 2.0 Camera, size=320x240, fps=30' - in my case it was the fourth one down, and since we count from zero, I put in a '3'.

alt text

We're using the 320x240 resolution because it makes the math a little easier since we have 32 rows of LEDs. Feel free to experiment with the other settings to see what happens.

language:java
/* Live video to 32x32 RBG panel by Ben Leduc-Mills
Adapted from Benjamin Poilvé www.theelectrisquid.fr 
based on the work of Markus Lipp and by Alex Medeiros
*/

import processing.serial.*;
import processing.video.*;

Capture cam;
Serial serialPort;      
PImage img;
byte[] matrixbuff = new byte[4096];

void setup(){
println(Serial.list());

// Open the port you are using at the rate you want:
serialPort = new Serial(this, Serial.list()[5], 500000);
String[] cameras = Capture.list();

if (cameras.length == 0) {
  println("There are no cameras available for capture.");
  exit();
} else {
  println("Available cameras:");
for (int i = 0; i < cameras.length; i++) {
  println(cameras[i]);
}

// The camera can be initialized directly using an 
// element from the array returned by list():
cam = new Capture(this, cameras[3]);
cam.start();     
  }      
}

void draw(){
  if (cam.available() == true) {
   cam.read();
  }
  img=cam.get(0,0,320,240);
  img.resize(32,24);
  image(img,0,0);
  update();
}

void update(){
  if (serialPort != null ) {

      serialPort.write((byte)(192)); //00001000 
      serialPort.write((byte)(192)); //00100001

      int pIdx = 0;
      for (int y = 0; y < 32; y++) {
        for (int x = 0; x < 32; x++) {

          float ga = 4f;

          color c = img.get(x, y);
          int r = int(red(c));
          int g = int(green(c));
          int b = int(blue(c));

          r = (byte)(Math.pow(((float)r)/255.0,ga)*255.0);
          g = (byte)(Math.pow(((float)g)/255.0,ga)*255.0);
          b = (byte)(Math.pow(((float)b)/255.0,ga)*255.0);

          matrixbuff=drawPixel888(x,y,(byte)r,(byte)g,(byte)b,matrixbuff);
          pIdx++;
        }}

    serialPort.write(matrixbuff);
    //println(matrixbuff);
  }
}


byte[] drawPixel888(int x, int y, byte r, byte g, byte b, byte target[]) {    
int rowLength = 32*8; 

int targetRow =getTargetRow(y);      
boolean targetHigh =  getTargetHigh(y);

int baseAddr = targetRow*rowLength;
for (int i=0; i<8; i++)
{
  int baseAddrCol = baseAddr+getTargetCol(x,i);
  int bit = 1<<i;      

  target[baseAddrCol]&= targetHigh?7:56; //zero target bits

  if ((r & bit) != 0)
    target[baseAddrCol]|=targetHigh?8:1;
  if ((g & bit) != 0)
    target[baseAddrCol]|=targetHigh?16:2;
  if ((b & bit) != 0)
    target[baseAddrCol]|=targetHigh?32:4;
    }
  return target;
}

int getTargetRow(int y)
{
  return y%16;
}

int getTargetCol(int x, int bit)
{
  return x+bit*32;
}

boolean getTargetHigh(int y)
{
  return y>=16;
}