vrijdag 12 december 2014

Ledmatrix - Serial data send

OK, my first real Arduino project

Started Arduino about a month ago, first of course some simple led examples but having some programming experience (basic),  I was triggered for something more exciting.
Please note that English is not my native language so language errors WILL occur!

I wanted to make a led-matrix that could be easily configured by GUI (and I made it!)



first of all lets start with the matrix:
- 25 standard led's and resistors (220 Ohm)
- soldered the matrix, lots of schemes can be found on the net, the main idea is that rows and colums are created with the anode/ cathode of the led's (for example here!)
- then the software; I created the sketches in steps, started easy with showing constant variables and moving them along the matrix, then Serial input via console window and at last the processing application.


Arduino sketch:

byte matrix[]={B00100, B01010, B00100, B00000, B00000};
byte temp[]={B00000, B00000, B00000, B00000, B00000};

const int led_row[] = {2, 3, 4, 5, 6};
const int led_col[] = {11, 10, 9, 8, 7};
const int led_array = 5;

const int duration = 2000; //2sec
byte row0Byte;
byte row1Byte;
byte row2Byte;
byte row3Byte;
byte row4Byte;


void setup(){
  Serial.begin(9600);
  for (int i = 0; i < led_array; i++){
    pinMode(led_row[i], OUTPUT);
    digitalWrite(led_row[i], HIGH);
    pinMode(led_col[i], OUTPUT);
    digitalWrite(led_col[i], LOW);
  }
}

void loop(){
  if (Serial.available() > 0) {
    matrix[0] = Serial.read();
    matrix[1] = Serial.read();
    matrix[2] = Serial.read();
    matrix[3] = Serial.read();
    matrix[4] = Serial.read();
  }
  wnd_showmatrix(matrix);
}

void wnd_showmatrix(byte * matrix){
  unsigned long start = millis(); // begin timing the animation
  while (start + duration > millis()){ // loop until the duration period has passed
    for (int i = 0; i < led_array; i++){
      digitalWrite(led_row[i], LOW);
        for (int j = 0; j < led_array; j++){
        boolean pixel = bitRead(matrix[i],j);
        if (pixel == 1){
          digitalWrite(led_col[j], HIGH);
          delayMicroseconds(400);
          digitalWrite(led_col[j], LOW);        
        }
      }
    digitalWrite(led_row[i], HIGH);
    }
  }
}

Processing sketch:

import processing.serial.*;

Serial myPort;  // Create object from Serial class
int val;

color ledOff = color(22,49,0);
color ledOn = color(114,255,0);
color buttonOff = color(100);
color buttonOn = color(200);

PShape buttonSend;
int buttonSendX, buttonSendY;
boolean buttonSendOver = false;
boolean buttonSendState = false;

PShape buttonReset;
int buttonResetX, buttonResetY;
boolean buttonResetOver = false;
boolean buttonResetState = false;

PShape[][] led = new PShape[5][5];
int ledArray = 5;
int ledSize = 20;
int [][] ledX = new int[5][5];
int [][] ledY = new int[5][5];
boolean [][] ledOver = new boolean[5][5];
boolean [][] ledState = new boolean[5][5];
boolean overLed = false;
int [] rowByte = new int[5];

void setup() {
  size(200, 270, P2D);
  background(0, 0, 0);

  myPort = new Serial(this, Serial.list()[0], 9600);

  for (int i = 0; i < ledArray; i++){
    for (int j = 0; j < ledArray; j++){
      ledOver[i][j] = false;
      ledState[i][j] = false;
    }
  }

  for (int i = 0; i < ledArray; i++){
    int posX = 30 + (i*30);
    for (int j = 0; j < ledArray; j++){
      int posY = 30 + (j*30);
      led[i][j] = createShape(ELLIPSE, posX, posY, ledSize, ledSize);
      led[i][j].setFill(ledOff);
      led[i][j].setStroke(false);
      ledX[i][j] = posX;
      ledY[i][j] = posY;
      shape(led[i][j]);
    }
  }
  buttonSend = createShape(RECT, 25, 205, 20, 20);
  buttonSend.setFill(buttonOff);
  buttonSend.setStroke(false);
  buttonSendX = 25;
  buttonSendY = 205;
  shape(buttonSend);
  text("Press square to send", 50, 220);

  buttonReset = createShape(RECT, 25, 235, 20, 20);
  buttonReset.setFill(buttonOff);
  buttonReset.setStroke(false);
  buttonResetX = 25;
  buttonResetY = 235;
  shape(buttonReset);
  text("Press square to reset", 50, 250);
}

void draw(){
  update(mouseX, mouseY);
}

void mousePressed(){
  clear();
    for (int i = 0; i < ledArray; i++){
      for (int j = 0; j < ledArray; j++){
        if (ledOver[i][j]){
          rowCountByte (i, j, ledState[i][j]);
          if (ledState[i][j]){
            led[i][j].setFill(ledOff);
            ledState[i][j] = false;
          } else {
          led[i][j].setFill(ledOn);
          ledState[i][j] = true;
          }
        } else if (buttonSendOver && i == 4 && j == 4) {
          for (int k = 0; k < ledArray; k++){
            myPort.write(rowByte[k]);
          }
          if (buttonSendState){
            buttonSend.setFill(buttonOff);
            buttonSendState = false;
          } else {
            buttonSend.setFill(buttonOn);
            buttonSendState = true;
          }
        } else if (buttonResetOver) {
          ledOver[i][j] = false;
          ledState[i][j] = false;
          led[i][j].setFill(ledOff);
          rowByte[i] = 0;
          if (i == 4){ //send data only once, at the end
            myPort.write(rowByte[j]);
          }
          if (buttonResetState){
            buttonReset.setFill(buttonOff);
            buttonResetState = false;
          } else {
            buttonReset.setFill(buttonOn);
            buttonResetState = true;
          }
        }
        shape(led[i][j]);
      }
   }
   shape(buttonSend);
   text("Press square to send", 50, 220);
   shape(buttonReset);
   text("Press square to reset", 50, 250);
}

//Position mouse decides wich button is pressed
void update(int x, int y){
  if (overbuttonSend(buttonSendX, buttonSendY, ledSize, ledSize)){
    for (int i = 0; i < ledArray; i++){
      for (int j = 0; j < ledArray; j++){
        ledOver[i][j] = false;
      }
      buttonResetOver = false;
      buttonSendOver = true;
    }
  } else if (overbuttonReset(buttonResetX, buttonResetY, ledSize, ledSize)){
    for (int i = 0; i < ledArray; i++){
      for (int j = 0; j < ledArray; j++){
        ledOver[i][j] = false;    
        ledState[i][j] = false;
        shape(led[i][j]);
      }
    }
    buttonResetOver = true;
    buttonSendOver = false;
  } else {
    for (int i = 0; i < ledArray; i++){
      for (int j = 0; j < ledArray; j++){    
      overled(ledX[i][j], ledY[i][j], ledSize, ledSize);
      if (overLed){
        ledOver[i][j] = true;
      } else
        ledOver[i][j] = false;
        buttonSendOver = false;
        buttonResetOver = false;
      }
    }
  }
}

void overled(int x, int y, int width, int height){
  if (mouseX >= x && mouseX <= x+width &&
                mouseY >= y && mouseY <= y+height){
    overLed = true;
  } else {
    overLed = false;
  }
}

boolean overbuttonSend(int x, int y, int width, int height){
  if (mouseX >= x && mouseX <= x+width &&
      mouseY >= y && mouseY <= y+height){
    return true;
  } else {
    return false;
  }
}

boolean overbuttonReset(int x, int y, int width, int height){
  if (mouseX >= x && mouseX <= x+width &&
      mouseY >= y && mouseY <= y+height){
    return true;
  } else {
    return false;
  }
}

void rowCountByte(int j, int i, boolean state){
  if (state){
    if (j == 0){
      rowByte[i] = rowByte[i] - 1;
    } else if (j == 1){
      rowByte[i] = rowByte[i] - 2;
    } else if (j == 2){
      rowByte[i] = rowByte[i] - 4;
    } else if (j == 3){
      rowByte[i] = rowByte[i] - 8;
    } else if (j == 4){
      rowByte[i] = rowByte[i] - 16;
    }
  } else {
    if (j == 0){
      rowByte[i] = rowByte[i] + 1;
    } else if (j == 1){
      rowByte[i] = rowByte[i] + 2;
    } else if (j == 2){
      rowByte[i] = rowByte[i] + 4;
    } else if (j == 3){
      rowByte[i] = rowByte[i] + 8;
    } else if (j == 4){
      rowByte[i] = rowByte[i] + 16;
    }
  }

}

Processing sketch (simple array):
note: this code can be 'simplified' to an 2D array, but lacking experience, a simple array will do the job just right! See above for 2D array version

import processing.serial.*;

Serial myPort;  // Create object from Serial class
int val;

color ledOff = color(22,49,0);
color ledOn = color(114,255,0);
color buttonSendOff = color(100);
color buttonSendOn = color(200);

PShape buttonSend;
int buttonSendX, buttonSendY;
boolean buttonSendOver = false;
boolean buttonSendState = false;

byte[] led = new byte[5]; //leds in row 
byte[] row = new byte[5];   //rows of ledmatrix

int ledArray = 5;
int ledSize = 20;
PShape[] led0 = new PShape[5]; // led shapes row[0]
PShape[] led1 = new PShape[5]; // led shapes row[1]
PShape[] led2 = new PShape[5]; // led shapes row[2]
PShape[] led3 = new PShape[5]; // led shapes row[3]
PShape[] led4 = new PShape[5]; // led shapes row[4]

int[] led0X = new int[5];
int[] led1X = new int[5];
int[] led2X = new int[5];
int[] led3X = new int[5];
int[] led4X = new int[5];

int[] led0Y = new int[5];
int[] led1Y = new int[5];
int[] led2Y = new int[5];
int[] led3Y = new int[5];
int[] led4Y = new int[5];

boolean[] led0Over = new boolean[5];
boolean[] led1Over = new boolean[5];
boolean[] led2Over = new boolean[5];
boolean[] led3Over = new boolean[5];
boolean[] led4Over = new boolean[5];

boolean[] led0State = new boolean[5];
boolean[] led1State = new boolean[5];
boolean[] led2State = new boolean[5];
boolean[] led3State = new boolean[5];
boolean[] led4State = new boolean[5];

boolean[] overLed0 = new boolean[5];
boolean[] overLed1 = new boolean[5];
boolean[] overLed2 = new boolean[5];
boolean[] overLed3 = new boolean[5];
boolean[] overLed4 = new boolean[5];

int row0Byte = 0;
int row1Byte = 0;
int row2Byte = 0;
int row3Byte = 0;
int row4Byte = 0;


void setup() {
  size(200, 250, P2D);
  background(0, 0, 0);
  // List all the available serial ports:
  println(Serial.list());
  // Open the port you are using at the rate you want:
  myPort = new Serial(this, Serial.list()[0], 9600);
  
  for (int i = 0; i < ledArray; i++){
    led0Over[i] = false;
    led1Over[i] = false;
    led2Over[i] = false;
    led3Over[i] = false;
    led4Over[i] = false;
    led0State[i] = false;
    led1State[i] = false;
    led2State[i] = false;
    led3State[i] = false;
    led4State[i] = false;
  }
  
  for (int i = 0; i < ledArray; i++){
    int posX = 30 + (i*30);
    led0[i] = createShape(ELLIPSE, posX, 30, ledSize, ledSize);
    led0[i].setFill(ledOff);
    led0[i].setStroke(false);
    led0X[i] = posX;
    led0Y[i] = 30;
    shape(led0[i]);
    
    led1[i] = createShape(ELLIPSE, posX, 60, ledSize, ledSize);
    led1[i].setFill(ledOff);
    led1[i].setStroke(false);
    led1X[i] = posX;
    led1Y[i] = 60;
    shape(led1[i]);
    
    led2[i] = createShape(ELLIPSE, posX, 90, ledSize, ledSize);
    led2[i].setFill(ledOff);
    led2[i].setStroke(false);
    led2X[i] = posX;
    led2Y[i] = 90;
    shape(led2[i]);
    
    led3[i] = createShape(ELLIPSE, posX, 120, ledSize, ledSize);
    led3[i].setFill(ledOff);
    led3[i].setStroke(false);
    led3X[i] = posX;
    led3Y[i] = 120;
    shape(led3[i]);
    
    led4[i] = createShape(ELLIPSE, posX, 150, ledSize, ledSize);
    led4[i].setFill(ledOff);
    led4[i].setStroke(false);
    led4X[i] = posX;
    led4Y[i] = 150;
    shape(led4[i]);
  }
  buttonSend = createShape(RECT, 90, 210, 20, 20);
  buttonSend.setFill(buttonSendOff);
  buttonSend.setStroke(false);
  buttonSendX = 90;
  buttonSendY = 210;
  shape(buttonSend);
  text("Press square to send", 40, 200);
}

void draw(){
  update(mouseX, mouseY);
}

void mousePressed(){
  clear();
    for (int i = 0; i < ledArray; i++){
      if (led0Over[i]){
        row0CountByte (i, led0State[i]);
        if (led0State[i]){
          led0[i].setFill(ledOff);
          led0State[i] = false;
        } else {
          led0[i].setFill(ledOn);
          led0State[i] = true;
        }
      } else if (led1Over[i]){
        row1CountByte (i, led1State[i]);
        if (led1State[i]){
          led1[i].setFill(ledOff);
          led1State[i] = false;
        } else {
          led1[i].setFill(ledOn);
          led1State[i] = true;
        }
      } else if (led2Over[i]){
        row2CountByte (i, led2State[i]);
        if (led2State[i]){
          led2[i].setFill(ledOff);
          led2State[i] = false;
        } else {
          led2[i].setFill(ledOn);
          led2State[i] = true;
        }
      } else if (led3Over[i]){
        row3CountByte (i, led3State[i]);
        if (led3State[i]){
          led3[i].setFill(ledOff);
          led3State[i] = false;
        } else {
          led3[i].setFill(ledOn);
          led3State[i] = true;
        }  
      } else if (led4Over[i]){
        row4CountByte (i, led4State[i]);
        if (led4State[i]){
          led4[i].setFill(ledOff);
          led4State[i] = false;
        } else {
          led4[i].setFill(ledOn);
          led4State[i] = true;  
        }  
      } else if (buttonSendOver) {
        if (i == 4){
          println("Row0Byte: "+ row0Byte);
          println("Row1Byte: "+ row1Byte);
          println("Row2Byte: "+ row2Byte);
          println("Row3Byte: "+ row3Byte);
          println("Row4Byte: "+ row4Byte);
          println("********************");
          myPort.write(row0Byte);
          myPort.write(row1Byte);
          myPort.write(row2Byte);
          myPort.write(row3Byte);
          myPort.write(row4Byte);
        }
        if (buttonSendState){
          buttonSend.setFill(buttonSendOff);
          buttonSendState = false;
        } else {
          buttonSend.setFill(buttonSendOn);
          buttonSendState = true;
        }
      }
    shape(led0[i]);
    shape(led1[i]);
    shape(led2[i]);
    shape(led3[i]);
    shape(led4[i]);
    shape(buttonSend);
    text("Press square to send", 40, 200);
  }
}

//Position mouse decides wich button is pressed
void update(int x, int y){
  if (overbuttonSend(buttonSendX, buttonSendY, ledSize, ledSize)){
    for (int i = 0; i < ledArray; i++){
      led0Over[i] = false;
      led1Over[i] = false;
      led2Over[i] = false;
      led3Over[i] = false;
      led4Over[i] = false;
    }
    buttonSendOver = true;
  } else {
    for (int i = 0; i < ledArray; i++){
      
      overled0(led0X[i], led0Y[i], ledSize, ledSize);
      overled1(led1X[i], led1Y[i], ledSize, ledSize);
      overled2(led2X[i], led2Y[i], ledSize, ledSize);
      overled3(led3X[i], led3Y[i], ledSize, ledSize);
      overled4(led4X[i], led4Y[i], ledSize, ledSize);
      
      if (overLed0[i]){
        led0Over[i] = true;
        led1Over[i] = false;
        led2Over[i] = false;
        led3Over[i] = false;
        led4Over[i] = false;
        buttonSendOver = false;
      } else if (overLed1[i]){
        led0Over[i] = false;
        led1Over[i] = true;
        led2Over[i] = false;
        led3Over[i] = false;
        led4Over[i] = false;       
      } else if (overLed2[i]){
        led0Over[i] = false;
        led1Over[i] = false;
        led2Over[i] = true;
        led3Over[i] = false;
        led4Over[i] = false;
        buttonSendOver = false;
      } else if (overLed3[i]){
        led0Over[i] = false;
        led1Over[i] = false;
        led2Over[i] = false;
        led3Over[i] = true;
        led4Over[i] = false;
        buttonSendOver = false;
      } else if (overLed4[i]){
        led0Over[i] = false;
        led1Over[i] = false;
        led2Over[i] = false;
        led3Over[i] = false;
        led4Over[i] = true;
        buttonSendOver = false;
      } else {
        led0Over[i] = false;
        led1Over[i] = false;
        led2Over[i] = false;
        led3Over[i] = false;
        led4Over[i] = false;
        buttonSendOver = false;
      }
    }
  }
}

void overled0(int x, int y, int width, int height){
  for (int i = 0; i < ledArray; i++){
    if (mouseX >= x && mouseX <= x+width &&
        mouseY >= y && mouseY <= y+height){
      overLed0[i] = true;
    } else {
      overLed0[i] = false;
    }
  }
}
void overled1(int x, int y, int width, int height){
  for (int i = 0; i < ledArray; i++){
    if (mouseX >= x && mouseX <= x+width &&
        mouseY >= y && mouseY <= y+height){
      overLed1[i] = true;
    } else {
      overLed1[i] = false;
    }
  }
}
void overled2(int x, int y, int width, int height){
  for (int i = 0; i < ledArray; i++){
    if (mouseX >= x && mouseX <= x+width &&
        mouseY >= y && mouseY <= y+height){
      overLed2[i] = true;
    } else {
      overLed2[i] = false;
    }
  }
}
void overled3(int x, int y, int width, int height){
  for (int i = 0; i < ledArray; i++){
    if (mouseX >= x && mouseX <= x+width &&
        mouseY >= y && mouseY <= y+height){
      overLed3[i] = true;
    } else {
      overLed3[i] = false;
    }
  }
}
void overled4(int x, int y, int width, int height){
  for (int i = 0; i < ledArray; i++){
    if (mouseX >= x && mouseX <= x+width &&
        mouseY >= y && mouseY <= y+height){
      overLed4[i] = true;
    } else {
      overLed4[i] = false;
    }
  }
}

boolean overbuttonSend(int x, int y, int width, int height){
  if (mouseX >= x && mouseX <= x+width &&
      mouseY >= y && mouseY <= y+height){
    return true;
  } else {
    return false;
  }
}

void row0CountByte(int i, boolean state){
  if (state){
    if (i == 0){
      row0Byte = row0Byte - 1;
    } else if (i == 1){
      row0Byte = row0Byte - 2;
    } else if (i == 2){
      row0Byte = row0Byte - 4;
    } else if (i == 3){
      row0Byte = row0Byte - 8;
    } else if (i == 4){
      row0Byte = row0Byte - 16;
    }
  } else {
    if (i == 0){
      row0Byte = row0Byte + 1;
    } else if (i == 1){
      row0Byte = row0Byte + 2;
    } else if (i == 2){
      row0Byte = row0Byte + 4;
    } else if (i == 3){
      row0Byte = row0Byte + 8;
    } else if (i == 4){
      row0Byte = row0Byte + 16;
    }
  }
}

void row1CountByte(int i, boolean state){
  if (state){
    if (i == 0){
      row1Byte = row1Byte - 1;
    } else if (i == 1){
      row1Byte = row1Byte - 2;
    } else if (i == 2){
      row1Byte = row1Byte - 4;
    } else if (i == 3){
      row1Byte = row1Byte - 8;
    } else if (i == 4){
      row1Byte = row1Byte - 16;
    }
  } else {
    if (i == 0){
      row1Byte = row1Byte + 1;
    } else if (i == 1){
      row1Byte = row1Byte + 2;
    } else if (i == 2){
      row1Byte = row1Byte + 4;
    } else if (i == 3){
      row1Byte = row1Byte + 8;
    } else if (i == 4){
      row1Byte = row1Byte + 16;
    }
  }
}

void row2CountByte(int i, boolean state){
  if (state){
    if (i == 0){
      row2Byte = row2Byte - 1;
    } else if (i == 1){
      row2Byte = row2Byte - 2;
    } else if (i == 2){
      row2Byte = row2Byte - 4;
    } else if (i == 3){
      row2Byte = row2Byte - 8;
    } else if (i == 4){
      row2Byte = row2Byte - 16;
    }
  } else {
    if (i == 0){
      row2Byte = row2Byte + 1;
    } else if (i == 1){
      row2Byte = row2Byte + 2;
    } else if (i == 2){
      row2Byte = row2Byte + 4;
    } else if (i == 3){
      row2Byte = row2Byte + 8;
    } else if (i == 4){
      row2Byte = row2Byte + 16;
    }
  }
}

void row3CountByte(int i, boolean state){
  if (state){
    if (i == 0){
      row3Byte = row3Byte - 1;
    } else if (i == 1){
      row3Byte = row3Byte - 2;
    } else if (i == 2){
      row3Byte = row3Byte - 4;
    } else if (i == 3){
      row3Byte = row3Byte - 8;
    } else if (i == 4){
      row3Byte = row3Byte - 16;
    }
  } else {
    if (i == 0){
      row3Byte = row3Byte + 1;
    } else if (i == 1){
      row3Byte = row3Byte + 2;
    } else if (i == 2){
      row3Byte = row3Byte + 4;
    } else if (i == 3){
      row3Byte = row3Byte + 8;
    } else if (i == 4){
      row3Byte = row3Byte + 16;
    }
  }
}

void row4CountByte(int i, boolean state){
  if (state){
    if (i == 0){
      row4Byte = row4Byte - 1;
    } else if (i == 1){
      row4Byte = row4Byte - 2;
    } else if (i == 2){
      row4Byte = row4Byte - 4;
    } else if (i == 3){
      row4Byte = row4Byte - 8;
    } else if (i == 4){
      row4Byte = row4Byte - 16;
    }
  } else {
    if (i == 0){
      row4Byte = row4Byte + 1;
    } else if (i == 1){
      row4Byte = row4Byte + 2;
    } else if (i == 2){
      row4Byte = row4Byte + 4;
    } else if (i == 3){
      row4Byte = row4Byte + 8;
    } else if (i == 4){
      row4Byte = row4Byte + 16;
    }
  }
}

Geen opmerkingen:

Een reactie posten