Close

Processing on the Pi – Live Drawing

A project log for Networked Low Resolution DMD Projectors

WiFi networked electro-mechanical 7x7 pixel flip-dot displays as giant DMDs (Digital Micromirror Devices) for low resolution projection

michael-shaubMichael Shaub 02/24/2016 at 04:020 Comments

Date: 2/19/2016

I wanted to try something more interesting than test patterns on the flip dot display. I'd played a little bit with high speed to see how quickly the dots could respond which got me thinking about making something that ran in real-time. I wrote a program that showed a preview of the flip-dot display, allowed a mouse left-click to "draw" a white dot and a right-click to "erase" it back to black. I added a highlight around each dot location like a "mouse over" event to make it easier to see the mouse location.

Below is the code for the Live Drawing processing sketch:

// Live Draw sketch
// For LinkSprite V3 and AlfaZeta flip-dot display
// by Michael Shaub 2016

import processing.serial.*;

// The serial port:
Serial myPort;       


PImage pix = createImage(7, 7, RGB);

int frameDelay = 50; //pause 400 ms between frames being sent to the board
float dotSize = 0;

void setup() {
  // List all the available serial ports:
  printArray(Serial.list());
  
  // Open the port you are using at the rate you want:
  myPort = new Serial(this, Serial.list()[0], 57600);

  size(500,500);
  dotSize = height/7.0;
  pix.loadPixels();
  for (int i = 0; i < pix.pixels.length; i++) {
    pix.pixels[i] = color(0); 
  }
  pix.updatePixels();
  noStroke();
  ellipseMode(CORNER);
}

void draw(){
  background(0);
  boolean dot = false;
  
  pix.loadPixels();
  //bitshift values from array
  int row1 = 0;
  int row2 = 0;
  int row3 = 0;
  int row4 = 0;
  int row5 = 0;
  int row6 = 0;
  int row7 = 0;
  
  for (int y = 0; y < pix.height; y++) {
    for (int x = 0; x < pix.width; x++) {
      stroke(64);
      strokeWeight(1);
      noFill();
      ellipse(x*dotSize,y*dotSize,dotSize,dotSize);
      noStroke();
      if( pix.pixels[x+y*pix.width] == color(255) ){
        //draw on screen
        fill(255);
        ellipse(x*dotSize,y*dotSize,dotSize,dotSize);
      }
      if(round(mouseX/dotSize-.5)==x && round(mouseY/dotSize-.5)==y){
          stroke(128);
          strokeWeight(4);
          noFill();
          ellipse(x*dotSize,y*dotSize,dotSize,dotSize);
          noStroke();
         if (mousePressed && (mouseButton == LEFT)) {
            pix.pixels[x+y*pix.width] = color(255);
         }
         if (mousePressed && (mouseButton == RIGHT)) {
            pix.pixels[x+y*pix.width] = color(0);
         }
      }
    }
  }
  pix.updatePixels();
  
  pix.loadPixels();
  
  for (int y = 0; y < pix.height; y++) {
    for (int x = 0; x < pix.width; x++) {
      if( pix.pixels[x+y*pix.width] == color(255) ){

        //prep for fipDot message
        int b = 1 << x; //bitshift the value the number of positions equal to the digit
        switch(y+1){
        case 1:
          row1 = row1 | b; //bitwise OR addition of the "b" value to the existing "row3" value
          break;
        case 2:
          row2 = row2 | b; //bitwise OR addition of the "b" value to the existing "row3" value
          break;
        case 3:
          row3 = row3 | b; //bitwise OR addition of the "b" value to the existing "row3" value
          break;
        case 4:
          row4 = row4 | b; //bitwise OR addition of the "b" value to the existing "row3" value
          break;
        case 5:
          row5 = row5 | b; //bitwise OR addition of the "b" value to the existing "row3" value
          break;
        case 6:
          row6 = row6 | b; //bitwise OR addition of the "b" value to the existing "row3" value
          break;
        case 7:
          row7 = row7 | b; //bitwise OR addition of the "b" value to the existing "row3" value
          break;
        }
      }
    }
  }
  pix.updatePixels();
  
  int test_2[]= {0x80, 0x87, 0xFF, row1, row2, row3, row4, row5, row6, row7, 0x8F};
  
  for(int i=0; i<test_2.length; i++){
    myPort.write(test_2[i]); 
  }
  
  delay (frameDelay);
}


Discussions