Friday, 16 April 2010

jMyron




Here is another application where a Black & white image caught by a web cam has been successfully sent to an 8*8 Led matrix, this time using the jMyron library. Again I hope to be able to add to this post soon when i get my board working. Currently my board will accept some sketches but none of the later ones I developed such as the scrolling text. I am getting this common error which can unfortunately refer to many things.
avrdude: stk500_recv(): programmer is not responding
SOS can anyone help!, it worked before!



http-//www.bryanchung.net/?p=177

The Arduino uses the last program. The host one has the following

LEDCtrl03.pde

import JMyron.*;
import processing.serial.*;

LED myLed;
Camera myCam;
// set up led screen display
void setup() {
  size(300,300);
  background(0);
  ellipseMode(CORNER);
  colorMode(HSB);
  smooth();
 // sets frames per sec
  frameRate(15);
// disable outline
  noStroke();
  myLed = new LED(this);
  myCam = new Camera();
 // write to console
  println(Serial.list());
}
// called by the framerate function
void draw() {
  background(0);
  myCam.refresh();
  myLed.refresh();
}

void serialEvent(Serial _p) {
}
// call method sendMsg on mouse click
void mousePressed() {
  myLed.sendMsg();
}


//This part grabs the image and reduces it to 8*8
Camera.pde
class Camera {
  final int XNUM = 8;
  final int YNUM = 8;
  JMyron cam;
  PImage img;
  int w, h;
  int xInc, yInc;
  boolean [][] cells;

  Camera() {
    cam = new JMyron();
    w = 320;
    h = 240;
    img = new PImage(h,h);
    cam.start(w,h);
    cam.findGlobs(0);
    println("Myron " + cam.version());
// Next few lines are only for windows users  
// println("Forced Dimensions: " +
    //  cam.getForcedWidth() + " " +
    //  cam.getForcedHeight());
    cells = new boolean[XNUM][YNUM];
   //240/XNUM
   //240/YNUM
    xInc = h/XNUM;
    yInc = h/YNUM;
  }

  void refresh() {
 // PImage  data type for storing images. Processing can store png, jpg, tga, gif
    PImage tmg = new PImage(w,h);
    cam.update();
    cam.imageCopy(tmg.pixels);
//updates image with data in the pixel array
    tmg.updatePixels();
    img.copy(tmg,40,0,h,h,0,0,h,h);
 // update Pixels function updates change   
    img.updatePixels();
    updateCell();
  }

  void updateCell() {
    int xOff = xInc/2;
    int yOff = yInc/2;
    for (int i=0;i
      for (int j=0;j
        int x = i*xInc+xOff;
        int y = j*yInc+yOff;
       //array for all pixels in display window
        color c = img.pixels[y*h+x];
        cells[i][j] = (brightness(c)>=128);
      }
    }
  }
 
  boolean getCol(int _x, int _y) {
    return cells[_x][_y];
  }
}

LED.pde
// This section sends data to the arduino
class LED {
/* Final    Keyword used to state that a value, class, or method can't be changed. If the final keyword is used to define a variable, the variable can't be changed within the program */
  final int XNUM = 8;
  final int YNUM = 8;
  int w, h;
  int w1, h1;
  int xOff, yOff;
  Light [][] board;
  Serial port;
  PApplet parent;
  byte [] msg = new byte[YNUM+1];

  LED(PApplet _p) {
    parent = _p;
    board = new Light[XNUM][YNUM];
    w = 30;
    h = 30;
  // Make sure this is the same port as you used to load the arduino skech to the board on
    port = new Serial(parent,"/dev/cu.usbserial-A70060ta",9600);
    init();
  }

  void init() {
    w1 = w+4;
    h1 = h+4;
    xOff = (width-w1*XNUM)/2;
    yOff = (height-h1*YNUM)/2;
    for (int x=0;x
      for (int y=0;y
        int tx = xOff+x*w1;
        int ty = yOff+y*h1;
        board[x][y] = new Light(tx, ty, w, h);
      }
    }
    msg[0] = (byte) 0x55;
  }

  void refresh() {
    for (int x=0;x
      for (int y=0;y
        board[x][y].setLight(myCam.getCol(x,y));
        board[x][y].show();
      }
    }
    sendMsg();
  }

  void sendMsg() {
    for (int y=0;y
      int result = 0;
      for (int x=0;x
        int x1 = 8-x;
        x1 %= 8;
        result = result*2+board[x1][y].getLight();
      }
      msg[y+1] = (byte) result;
    }
    port.write(msg);
  }
}

Light.pde

// This part controls the onscreen representation
class Light {
  boolean on;
  int w, h;
  int x, y;
 
  Light(int _x, int _y, int _w, int _h) {
    x = _x;
    y = _y;
    w = _w;
    h = _h;
  }
 
  void show() {
    if (on) {
      fill(240,255,255);
    } else {
      fill(0,0,50);
    }
    ellipse(x+2,y+2,w,h);
  }
 
  void toggle() {
    on = !on;
  }
    //Bytes are a convenient datatype for sending information to and from the serial port
  byte getLight() {
    byte state = 0;
    if (on) {
      state = 1;
    }
    return state;
  }
 
  void setLight(boolean _o) {
    on = _o;
  }
}

Arduino



int CLOCK = 12;
int LATCH = 13;
int DATA  = 11;
// byte stores an unsigned number from 0 to 255
byte matrix[8];
byte head;
// two byte value -32000> 32000
int state = 0;

void setup() {
  /*When a pin is configured to OUTPUT with pinMode, and set to LOW with digitalWrite, the pin is at 0 volts. In this state it can sink current, e.g. light an LED that is connected through a series resistor to, +5 volts, or to another pin configured as an output, and set to HIGH.
 Digital pins can be used either as INPUT or OUTPUT. Changing a pin from INPUT TO OUTPUT with pinMode() drastically changes the electrical behavior of the pin. */
  pinMode(CLOCK, OUTPUT);
  pinMode(LATCH, OUTPUT);
  pinMode(DATA,  OUTPUT);
  digitalWrite(CLOCK, LOW);
  digitalWrite(LATCH, LOW);
  digitalWrite(DATA,  LOW);
  initLED();
  clearLED();
  //Begin. Sets the data rate in bits per second (baud) for serial data transmission.
  Serial.begin(9600);
  head = (byte) 0x55;
}

void loop() {
   /*available. Get the number of bytes (characters) available for reading from the serial port. This is data that's already arrived and stored in the serial receive buffer (which holds 128 bytes). */
  if (Serial.available()>0) {
    int input = Serial.read();
   /*Like if statements, switch...case controls the flow of programs by allowing programmers to specify different code that should be executed in various conditions. In particular, a switch statement compares the value of a variable to the values specified in case statements. When a case statement is found whose value matches that of the variable, the code in that case statement is run.
   The break keyword exits the switch statement, and is typically used at the end of each case.*/
    switch (state) {
    case 0:
      if (input==head) {
        state = 1;
      }
      break;
    case 1:
    case 2:
    case 3:
    case 4:
    case 5:
    case 6:
    case 7:
      matrix[state-1] = (byte) input;
      state++;
      break;
    case 8:
      matrix[state-1] = (byte) input;
      state = 0;
      refreshLED();
      break;
    }
  }
}

void ledOut(int n) {
  digitalWrite(LATCH, LOW);
 /*Shifts out a byte of data one bit at a time. Starts from either the most (i.e. the leftmost) or least (rightmost) significant bit. Each bit is written in turn to a data pin, after which a clock pin is toggled to indicate that the bit is available.
 This is known as synchronous serial protocol and is a common way that microcontrollers communicate with sensors, and with other microcontrollers. */
 //MSBFIRST. most significant bit first
  shiftOut(DATA, CLOCK, MSBFIRST, (n>>8));
  shiftOut(DATA, CLOCK, MSBFIRST, (n));
  digitalWrite(LATCH, HIGH);
  delay(1);
  digitalWrite(LATCH, LOW);
}

void initLED() {
  ledOut(0x0B07);
  ledOut(0x0A0C);
  ledOut(0x0900);
  ledOut(0x0C01);
}

void clearLED() {
  for (int i=0;i<8;i++) {
    matrix[i] = 0x00;
  }
  refreshLED();
}

void refreshLED() {
  int n1, n2, n3;
  for (int i=0;i<8;i++) {
    n1 = i+1;
    n2 = matrix[i];
    n3 = (n1<<8)+n2;
    ledOut(n3);
  }
}

void updateLED(int i, int j, boolean b) {
  // = assignment   == equal to
  int t = 1;
  int n = 0;
  int m = 0;
  if (j==0) {
    m = 7;
  }
  else {
    m = j-1;
  }
  n = t<
  if (b) {
    matrix[i] = n | matrix[i];
  }
  else {
    n = ~n;
    matrix[i] = n & matrix[i];
  }
}

No comments:

Post a Comment