vineri, 28 februarie 2014

MATRICE LEDURI CU ARDUINO SI PROCESSING


     Imi doream de ceva vreme sa experimentez cu o matrice cu leduri. La vremea cand ma batea acest gand nu am gasit de vanzare matrici 8x8, asa ca mi-am construit una. Acum ca am gasit resursele de timp necesare am zis sa ma joc putin cu ea impreuna bineinteles cu Arduino. De la inceput am remarcat ca pentru a afisa diferite tipare pe matrice trebuie introduse in programul scris pentru Arduino datele respective sub forma de bytes. Daca dupa incarcare rezultatul nu este cel dorit ... se modifica programul cu datele noi ... se reincarca si tot asa. Ce ar fi insa daca Arduino ar primi datele de pe un PC, printr-o  interfata grafica prietenoasa urmand ca apoi sa le afiseze in timp real pe matrice? 
     Urmarind ideea de mai sus am scris un mic programel in processing care fix asta face. Iata un screenshot: 

INTERFATA PROCESSING

CEEA CE SE VEDE :)




    Asadar: dupa rularea programului in Processing suntem intampinati de fereastra de mai sus. Mai departe totul este intuitiv: se deseneaza tiparul printr-un simplu click pe fiecare led iar apoi se trimit datele catre Arduino apasand butonul send. 
     Inainte de a posta codurile sa aruncam un ochi pe schema pentru a intelege modul de functionare:

SCHEMA ELECTRONICA
     Tranzistoarele Q1-Q8 reprezinta coloanele iar Q9-Q16 reprezinta liniile. Odata polarizat, un tranzistor "de coloana", va permite aprinderea oricarui led care apartine acelei coloane cu conditia ca ledul la randul sau  sa fie polarizat corespunzator. De acest fapt se ocupa tranzistoarele "de linii". Dupa cum se vede si in schema Q1 fiind deschis va permite aprinderea oricarui led de pe coloana 1 cu conditia ca tranzistorul aferent acelei linii sa fie deschis.Urmarind rationamentul si privind poza inseamna ca Q9-Q16 sunt deschise. Daca Q1 se inchide si se deschide Q2 atunci toata coloana 2 se va aprinde, si asa mai departe. Din cele mentionate anterior rezulta ca o anumita imagine pe matrice se poate obtine daca se deschid pe rand tranzistoarele "de coloana", iar in timpul in care acestea sunt in stare de conductie se deschid numai tranzistoarele "de linie" care formeaza imaginea.  

      Iata si codurile:

1. Processing :
    1.1. Programul propriuzis:


import processing.serial.*;
Serial arduino;


led[] led_matrix  = new led [64];
int [] columns = new int[8];
byte[] to_send=new byte [16];
int y;
int x;
int startx=50;
int starty=50;
int back=125;
button send=new button(120,350,30,100,"SEND");

void setup() {
  size(500,400);
  background(back);
  arduino = new Serial(this, Serial.list()[0], 9600);
  for(int i=0;i<64;i++){
    if(i%8==0&&i>0){
      y++;
      x=0;
    }
    led_matrix[i]=new led(30,startx+x*35,starty+y*35);
    x++;
  }
}

void split(){
  int j=0;
  int h_nibble=240;
  int l_nibble=15;
  for(int i=0;i<8;i++){
    to_send[j]= (byte)(((h_nibble & columns[i])>>4)|16);
    to_send[j+1]= (byte)((l_nibble & columns[i])|16);
    print(to_send[j]);
    print("/");
    print(to_send[j+1]);
    print("//");
    j=j+2;
  } 
  println("");
  println("_______________________________________________________");
  for(int i=0;i<16;i++){
    arduino.write(to_send[i]);
  }
}

void draw(){
  stroke(0,0,0);
  int index=0;
  fill(0,255,0);
  rect(send.x_corner,send.y_corner,send.b_width,send.b_height);
  fill(0,0,255);
  textSize(16);
  text(send.caption,send.x_corner+30,send.y_corner+20);
  for(int i=0;i<led_matrix[0].size; i++){
    if(!led_matrix[i].state){
      fill(100,0,0);
    }
    if(led_matrix[i].state){
      fill(255,0,0);
    }
    ellipse(led_matrix[i].x_center,led_matrix[i].y_center,30,30);
  }
  fill(back);
  noStroke();
  rect(led_matrix[0].x_center-10,led_matrix[0].y_center-50,290,30);
  for(int i=0;i<8;i++){
    fill(255,255,255); 
    text(columns[i],led_matrix[i].x_center-5,led_matrix[i].y_center-30);
  }
}

void mouseClicked(){
  int end=0;
  int start=0;
  int j=0;
  int col_val=0;
  int step=0;
  boolean k=false;
  for(int i=0;i<64;i++){
    if((led_matrix[i].x_center-15<mouseX && led_matrix[i].x_center+15>mouseX) &&
    (led_matrix[i].y_center-15<mouseY && led_matrix[i].y_center+15>mouseY)
    ){
      led_matrix[i].state =!led_matrix[i].state;
      led_matrix[i].bin=abs(led_matrix[i].bin-1);
    }
  }
  if((send.x_corner<mouseX&&(send.x_corner+send.b_width)>mouseX)&&
  (send.y_corner<mouseY&&(send.y_corner+send.b_height)>mouseY)){
    k=true;
  }
  while(end<64){
    end=64-(7-start);
    for(int i=start;i<end;i=i+8){
      if(led_matrix[i].state==true){
        col_val=col_val|led_matrix[i].bin<<step;
      }
      step++;
    }
    start++;
    columns[j]=col_val;
    col_val=0;
    j++;
    step=0;
  }
  if(k){
    split();
    k=false;
  }
}

    1.2. Clasa led:


class led{
  static int size;
  public int diameter;
  public int x_center;
  public int y_center;
  public boolean state;
  public int bin;
  public led(int d, int x,int y){
    size++;
    this.diameter=d;
    this.x_center=x;
    this.y_center=y;
    this.state=false;
  }
}

    1.3. Clasa button:


class button {
  public int x_corner;
  public int y_corner;
  public int b_height;
  public int b_width;
  public String caption;
  
  public button(int x,int y, int h, int w, String c){
    this.x_corner=x;
    this.y_corner=y;
    this.b_height=h;
    this.b_width=w;
    this.caption=c;    
  }

}

2. Programul pentru Arduino :


int columns[8]={2,3,4,5,6,7,8,9};
int rows[8]={24,26,28,30,32,34,36,38};

char buffer[16];
int data[8];
int i;
int j;
void setup(){
 for(i=0;i<8;i++){
  pinMode(rows[i],OUTPUT);
  pinMode(columns[i],OUTPUT);
 }
 Serial.begin(9600);
 
}

void loop(){
 if(Serial.available()>0){
  int index=0;
  Serial.readBytes(buffer,16);
  for(i=0;i<16;i=i+2){
   data[index]=((buffer[i]^16)<<4|(buffer[i+1]^16));
   index++;
  }
 }


  for(i=0;i<8;i++){
   digitalWrite(columns[i],HIGH);
   for(j=0;j<8;j++){
    int k=data[i]&(1<<j);
    digitalWrite(rows[j],k);
    delayMicroseconds(250);
    digitalWrite(rows[j],LOW);
    //delayMicroseconds(10);
   } 
   digitalWrite(columns[i],LOW);
  }
 
}

     Cele doua programe se pot downloada de AICI.
     Cam asta ar fi pentru azi. Succes.


Niciun comentariu:

Trimiteți un comentariu