dissabte, 25 de maig del 2013

Processing, 2 botons, Arduino 1 led

Crearem una finestra amb dos botons, apretant un encenem el led, apretant l'altre, l'apagem:

Codi processing:

// Activem el serial:
import processing.serial.*;
Serial port;

//configurem els colors:
color currentcolor;
//creem totes les figures que necesitem:
RectButton rect1, rect2;
//començem amb el ratolí despremut:
boolean locked = false;

//configurem tot el necessari:
void setup() {
  //configurem finestra (pixels) i color:
  size(200, 200);
  color baseColor = color(102, 102, 102);
  currentcolor = baseColor;
  
  //busquem tots els ports serials disponibles i escollirem el nostre entre []:
  println(Serial.list()); 
  port = new Serial(this, Serial.list()[1], 9600);

  //definim i creem el primer rectangle:
  int x = 30; //posició a partir del costat esquerre
  int y = 100; //alçada
  int size = 50; //costat x costat del rectangle
  color buttoncolor = color(153, 102, 102); //color base del botó
  color highlight = color(102, 51, 51); //color quan passem el ratolí per damunt
  rect1 = new RectButton(x, y, size, buttoncolor, highlight); //creem el botó1

  //definim i creem el segon rectangle:
  x = 90; //posició a partir del costat esquerre
  y = 100; //alçada
  size = 50; //costat x costat del rectangle
  buttoncolor = color(153, 153, 153); //color base del botó
  highlight = color(102, 102, 102); //color quan passem el ratolí per damunt
  rect2 = new RectButton(x, y, size, buttoncolor, highlight); //creem el botó2
}
void draw() {
  background(currentcolor); //definim el color de fons
  stroke(255);
  update(mouseX, mouseY); //actualitzarem la posició SEMPRE
  rect1.display(); //actualitzem el botó1
  rect2.display(); //actualitzem el botó2
}
void update(int x, int y) { //definim el update()
  if(locked == false) { //mirem si està el mouse apretat
    rect1.update(); //en cas afirmatiu, fem update als botons
    rect2.update();
  } else {
    locked = false; //en cas contrari, locked continua sent false
  }
  //enviarem per serial el "H" o "L" per activar el LED o desactivar-lo
  if(mousePressed) {
    if(rect1.pressed()) {            
      currentcolor = rect1.basecolor; //background del mateix color del botó
      port.write('H');  //activarem el LED
    } else if(rect2.pressed()) { //si es el segon rectangle que està apagat:   
      currentcolor = rect2.basecolor;  //canviarem el color de fons
      port.write('L'); //desactivarem el LED
    }
  }
}
class Button { //definirem la configuració interior de  botó.XXXXX
  int x, y; //necesitem varies dades
  int size;
  color basecolor, highlightcolor;
  color currentcolor;
  boolean over = false;
  boolean pressed = false;   
  void update() //primer botó.update():
  {
    if(over()){ //canviarem el color si el ratolí està sobre el botó o no:
      currentcolor = highlightcolor; //si està sobre, el botó serà de color highlight
    }else{ //sino:
      currentcolor = basecolor;  //el color serà el base 
    }
  }
  boolean pressed() //que farà si apretem o no:
  {
    if(over) { //si apretem damunt:
      locked = true; //la dada serà 1
      return true;
    } else { //sino:
      locked = false; //la dada serà 0
      return false;
    }    
  }
  boolean over() //ens retorna si està damunt o no del botó
  { 
    return true; 
  }
  void display() 
  { 
  }
}

class RectButton extends Button {
  RectButton(int ix, int iy, int isize, color icolor, color ihighlight) 
  {
    x = ix;
    y = iy;
    size = isize;
    basecolor = icolor;
    highlightcolor = ihighlight;
    currentcolor = basecolor;
  }
  boolean over() //ens retorna si està damunt o no del botó
  {
    if( overRect(x, y, size, size) ) { //amb el .over sabem de quin botó es tracta
      over = true;
      return true;
    } else {
      over = false;
      return false;
    }
  }
  void display() //mostrem el botó a la pantalla
  {
    stroke(255); //color de contorn:
    fill(currentcolor); //color de l'interior
    rect(x, y, size, size); //forma del rectangle
  }
}
boolean overRect(int x, int y, int width, int height) { //mirem si està el ratolí per damunt o no
  if (mouseX >= x && mouseX <= x+width && 
      mouseY >= y && mouseY <= y+height) {
    return true; //en cas afirmatiu, retorna SI
  } else {
    return false; //en cas negatiu, retorna NO
  }
}


Codi Arduino:

const int ledPin = 13; // the pin that the LED is attached to
int incomingByte;      // a variable to read incoming serial data into

void setup() {
  // initialize serial communication:
  Serial.begin(9600);
  // initialize the LED pin as an output:
  pinMode(ledPin, OUTPUT);
}

void loop() {
  // see if there's incoming serial data:
  if (Serial.available() > 0) {
    // read the oldest byte in the serial buffer:
    incomingByte = Serial.read();
    // if it's a capital H (ASCII 72), turn on the LED:
    if (incomingByte == 'H') {
      digitalWrite(ledPin, HIGH);
    } 
    // if it's an L (ASCII 76) turn off the LED:
    if (incomingByte == 'L') {
      digitalWrite(ledPin, LOW);
    }
  }
}

Control de Servo mitjançant entrada analògica

Que necessitem? Un arduino, Un servomotor, Una resitència variable de 10K, Una protoboard, Uns cables El circuit ha de quedar d'aquesta manera: . Aqui teniu el codi::: // Controlar un servomotor usant un potenciómetre (resitència variable) #include Servo myservo; // creem un objecte servo per al control int potpin = 0; // pin on connectem el potenciòmetre int val; // variable on guardarem el valor del pin void setup() { myservo.attach(9); // diem a quin pin connectem un servo (els pins que poden controlar un servo porten un "~" davant del número) } void loop() { val = analogRead(potpin); // llegim el valor del potenciòmetre (un valor entre 0 i 1023) val = map(val, 0, 1023, 0, 179); // escalem el valor usant la funció map, pero adaptar-lo als graus del servomotor (entre 0 i 180 graus) myservo.write(val); // posicionem el servo a la posició desitjada a partir del map delay(15); // ens esperem per a que el servo arribi a la posició } //Perdoneu, no va el enter...

dilluns, 6 de maig del 2013

Escriure per LCD lectura analògica i posició del servo

Boones!

Us col·loco un codi amb l'explicació al costat que he fet per tal de llegir un valor analògic i fer mou-re un servo en una posició segons la funció map().
El codi del servo és el mateix que el de l'entrada de control de servo motors, però ara afegirem escriure a la pantalla els valors llegits i al que està el servomotor!

El circuit:

El codi:


// incluim les llibreries:
#include <LiquidCrystal.h>
#include <Servo.h>

Servo myservo; //creem un objecte que es digui servo.
int val; //Aquesta dada l'utilitzarem per a indicar els graus al que em de col·locar el servo.
  // inicialitzem la llibreria indicant els pins on hi ha connectat cada cosa
  // i és lcd(RS, E, D4, D5, D6, D7);
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

void setup() {
  lcd.begin(16, 2); //configurem la pantalla
 myservo.attach(9); //indiquem a quin pin hi ha connectat el servomotor
}

void loop() {
  lcd.clear(); //primer de tot netejem la pantalla, perque sinò es quedarà l'ultim text escrit al darrere
  lcd.setCursor(0, 0); //com en el loop escriure'm a la segona línia, em de tornar a la primera per a escriure-ho be
  lcd.print("Valor: "); //escrivim el text
  //lcd.setCursor(7, 0); //no fa falta escriure'l, ja que el text de la dada continuarà darrere
  int sensorValue = analogRead(A0); //llegim l'entrada
  lcd.print(sensorValue); //i precedim el text anterior amb el valor        
  val = map(sensorValue, 0, 1023, 0, 179); //indiquem quin angle ha de tenir el servo     
  myservo.write(val); //escrivim l'angle al servo i fem que es mogui
  lcd.setCursor(0,1); //canviem a la segona fila
  lcd.print("Posicio: "); //escrivim "posició :" 
  //lcd.setCursor(9, 1); //no fa falta escriure'l perquè el text del valor s'escriurà darrere de l'últim text
  lcd.print(val); //i el valor en angles de la posició del servo
  delay(200); //en esperem per tornar a fer una lectura del potenciòmetre
}

Al final ens hauria de sortir una cosa així:



Funcions de la LCD!

Dins de la llibreria de la LCD podem trobar diferents funcions, que us les explicaré tot seguit:



  • LiquidCrystal()
Descripció:
Crea una variable del tipus CristallLíquid. Que pot ser controlat per 4 o 8 pins. Nosaltres utilitzem de d4 a d7, connectant RW a massa (GND).
Sintaxis:
LiquidCrystal(rs, enable, d4, d5, d6, d7) 
Paràmetres:
rs: el número de pin de l'Arduino que està connectat al pin RS de la LCD
enable: el número de pin de l'Arduino que està connectat al pin enable (E) de la LCD
d4, d5, d6, d7: els pins de l'Arduino que estan connectats al corresponent pin de la LCD
Exemple:
#include <LiquidCrystal.h>

LiquidCrystal lcd(12, 11, 10, 5, 4, 3, 2);

void setup()
{
  lcd.print("hello, world!");
}
void loop() {}

  • begin()
Descripció:
Especifica la dimensió (amplada i alçada) del display.
Sintaxis:
lcd.begin(cols, rows)
Paràmetres:
lcd: una variable del tipus CristallLíquid
cols: el nombre de columnes que té el display (nosaltres tenim 16 normalment)
rows: el nombre de files que té el display (nosaltres normalment 2)
  • clear()
Descripció:
Neteja la LCD i col·loca el cursor a la part superior esquerre
Sintaxis:
lcd.clear()

  • home()
Descripció:
Col·loca el cursor a la part superior esquerre de la LCD, es a dir, s'utilitza per tornar a escriure alguna cosa a la LCD des del principi
Sintaxis:
lcd.home()

  • setCursor()
Descripció:
Posicionament del cursor; es a dir, indica on vols que comenci a escriure el següent text.
Sintaxis:
lcd.setCursor(col, row)
Paràmetres:
lcd: una variable del tipus CristallLíquid
cols: la columna a la que vols que escrigui (amb 0 comença la primera columna)
rows: la fila a la que vols que escrigui (amb 0 comença la primera fila)

  • write()
Descripció:
Escriu un caràcter a la LCD
Sintaxis:
lcd.write(data)
Paràmetres:
lcd: una variable del tipus CristallLíquid
data: el caràcter que s'haurà d'escriure
Exemple:
#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 10, 5, 4, 3, 2);
void setup()
{
  Serial.begin(9600);
}
void loop()
{
  if (Serial.available()) {
    lcd.write(Serial.read());
  }
}

  • print()
Descripció:
Escriu text a la LCD.
Sintaxis:
lcd.print(data) 
lcd.print(data, BASE)
Paràmetres:
BASE (opcional): la base en la qual escriure el text: BIN per a binari (base 2), DEC per a decimal (base 10), OCT per a octal (base 8), HEX per a hexadecimal (base 16).
Exemple:
#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 10, 5, 4, 3, 2);
void setup()
{
  lcd.print("hello, world!");
}
void loop() {}

  • cursor()
Descripció:
Dibuixa el cursor ("_"): una linia inferior a la posició on el següent caràcter anirà escrit. Va bé per entendre com anirà escrivint la LCD al passar de files o columnes.
Sintaxis:
lcd.cursor()

  • noCursor()
Descripció:
Amaga el cursor.
Sintaxis:
lcd.noCursor()
Exemple:
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
void setup() {
  // Configura la LCD
  lcd.begin(16, 2);
  // Escriu un missatge:
  lcd.print("hello, world!");
}
void loop() {
  // Apaga el cursor:
  lcd.noCursor();
  delay(500);
   // Encén el cursor:
  lcd.cursor();
  delay(500);
}

  • blink()
Descripció:
Mostra el cursor, però encenent i apagant tot el rectangle de píxels on està el cursor.
Sintaxis:
lcd.blink()

  • noBlink()
Descripció:
Amaga tot el cursor.
Sintaxis:
lcd.noBlink()
Exemple:
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
void setup() {
  // configura la LCD: 
  lcd.begin(16, 2);
  // Escriu un text de mostra.
  lcd.print("hello, world!");
}
void loop() {
  // apaga el cursor:
  lcd.noBlink();
  delay(3000);
   // encén el cursor:
  lcd.blink();
  delay(3000);
}
  • display()
Descripció:
Encén el display, s'utilitza després d'apagar-lo amb la funció noDisplay(). Tornarà a encendre el text (i el cursor) que estaven escrits a la pantalla.
Sintaxis:
lcd.display()

  • noDisplay()
Descripció:
Apaga la pantalla de la LCD, no es perd cap contingut que estava escrit.
Sintaxis:
lcd.noDisplay()
Exemple:
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
void setup() {
  // Configura la LCD: 
  lcd.begin(16, 2);
  // Escriu alguna cosa.
  lcd.print("hello, world!");
}
void loop() {
  // Apaga la pantalla:
  lcd.noDisplay();
  delay(500);
   // Encén la pantalla:
  lcd.display();
  delay(500);
}
  • scrollDisplayLeft()
Descripció:
Mou tot el text (i cursor) de la pantalla una posició a la esquerre.
Sintaxis:
lcd.scrollDisplayLeft()

  • scrollDisplayRight()
Descripció:
Mou tot el text (i cursor) de la pantalla una posició a la dreta.
Sintaxis:
lcd.scrollDisplayRight()
Exemple:
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
void setup() {
  // Configura la LCD: 
  lcd.begin(16, 2);
  // Escriu alguna cosa.
  lcd.print("hello, world!");
  delay(1000)
  // Espera't un segon.
}
void loop() {
  // mou-te 13 posposició (llargada del text) a l'esquerra 
  // per a fer-lo desaparèixer de la pantalla:
  for (int positionCounter = 0; positionCounter < 13; positionCounter++) {
    // mou una posició a la esquerra:
    lcd.scrollDisplayLeft(); 
    // espera't un moment:
    delay(150);
  }
  // mou-te 29 posicions (llargada del text + llargada de la pantalla) to the right
  // fes desaparèixer el text pel costat dret:
  for (int positionCounter = 0; positionCounter < 29; positionCounter++) {
    // mou una posició a la dreta:
    lcd.scrollDisplayRight(); 
    // espera una mica:
    delay(150);
  }
    // mou el text 16 posicions(llargada de la pantalla + llargada del text) cap a la esquerra 
    // per a posar-ho de nou al centre:
  for (int positionCounter = 0; positionCounter < 16; positionCounter++) {
    // mou una posició a l'esquerre:
    lcd.scrollDisplayLeft(); 
    // espera't un moment:
    delay(150);
  }
  // espera't un segon al final de tot el codi:
  delay(1000);
  • autoscroll()
Descripció:
Activa el desplaçament automàtic de la pantalla LCD. Això fa que cada sortida de caràcter a la pantalla empenyi els anterior sobre una posició. Si la direcció del text actual es desplaça d'esquerra a dreta (per defecte), la pantalla es desplaça cap a l'esquerre, i si la direcció actual és de dreta a esquerra, la pantalla es desplaça cap a la dreta. Això te l'efecte de la sortida de cada nou caràcter en la mateixa ubicació de la pantalla de la LCD.
Sintaxis:
lcd.autoscroll()

  • noAutoscroll()
Descripció:
Desactiva la funció Autoscroll().
Sintaxis:
lcd.noAutoscroll()

  • leftToRight()
Descripció:
Configura la direcció en la qual s'escriu el text sobre la LCD, per defecte esquerra a dreta.
Sintaxis:
lcd.leftToRight()

  • rightToLeft()
Descripció:
Configura la direcció en la qual s'escriu el text sobre la LCD, en aquest cas, de dreta esquerre.
Sintaxis:
lcd.rightToLeft()

  • createChar()
Descripció:
Crea un caràcter personalitzat per a utilitzar-lo a la pantalla. Fins a 8 caràcters de 5x8 píxels són compatibles (numerats del 0 al 7). L'aparició de cada caràcter personalitzat s'especifica per una sèrie de vuit bytes, un per a cada fila. Els cinc bits menys significatius de cada byte determinen els píxels en aquesta fila. Per mostrar un caràcter personalitzat a la pantalla, s'ha d'utilitzar write() i el seu nom. 
Quan ens referim al caràcter "0", si no està disponible, necessitarem projectar-lo com un byte, en cas contrari el compilador genera un error. Vegeu l'exemple següent.
Sintaxis:
lcd.createChar(num, data)
Paràmetres:
lcd: una variable del tipus CristallLíquid
num: quin caràcter crear (de 0 a 7)
data: les dades dels píxels del caràcter
Exemple:
#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
byte smiley[8] = {
  B00000,
  B10001,
  B00000,
  B00000,
  B10001,
  B01110,
  B00000,
};
void setup() {
  lcd.createChar(0, smiley);
  lcd.begin(16, 2);  
  lcd.write(byte(0));
}
void loop() {}

Aquest caràcter dibuixarà una cara rient.