La finalitat de la lliçó és conèixer les entrades digitals i aprofitarem per llegir un polsador. Presentarem els valors booleans i un operador: Negació.
Imatge | Descripció |
---|---|
Arduino Uno o compatible | |
Una protoboard | |
Cables de connexió | |
Un díode led | |
2x resistència 330 Ohms | |
Un polsador |
Amb freqüència en electrònica necessitem saber si una llum està encesa o apagada, si algú ha premut un botó o si una porta ha quedat oberta o està tancada.
A aquesta mena de senyals tot/res, SI/NO, TRUE/FALSE, 0/1 se’n diu digitals, i podem manejar-les amb els pins de 0 al 13 de Arduino i per això parlem de pins digitals.
Molts dels sensors i actuadors que veiem en el món real són digitals:
Hem vist que Arduino poden usar els pins digitals com a eixides tot o res per a encendre un LED. De la mateixa manera podem llegir valors, tot o res, del món exterior.
En aquesta lliçó veurem que els pins digitals de Arduino poden ser usats tant d’entrada com d’eixida. Llegirem un botó o polsador extern i encendrem o apagarem un LED en funció que el botó es prema o no.
Muntarem un circuit amb un díode LED i resistència connectat al pin digital 10 de Arduino, tal com vam veure en les lliçons prèvies i a més un segon circuit amb un polsador S1 connectat al pin 6 amb una resistència com es mostra en el diagrama següent.
Observe’s que mentre no premem S1 el pin 6 de Arduino està connectat a 5V a través de la resistència R3 forçant una lectura de tensió alta (HIGH). En canvi quan premem S1 tancarem el circuit del pin 6 a negatiu amb el que llegirà tensió baixa, LOW. En tots dos casos tenim un valor de tensió definit.
Si no posàrem la resistència R3, en prémer S1 llegiríem correctament LOW en el pin 6. Però en deixar de prémer S1 el pin 6 estaria en un estat flotant, que és ni HIGH ni LOW sinó indeterminat. Com això és inacceptable en circuits digitals forcem una lectura alta amb R3.
I ací tenim l’esquema per a protoboard del circuit.
Comencem fent un programa que faça que el LED s’encenga quan premem el botó i s’apague quan el soltem. Per a això demanarem a Arduino que configure el pin digital 10 (D10) com a eixida per a manejar el LED, i el pin digital 6 (D6) com a entrada per a llegir el botó.
Normalment en programes senzills n’hi ha prou amb posar el número de pin en les instruccions. Però a mesura que el programa es complica això tendeix a provocar errors difícils de detectar.
Per això és costum definir variables amb els números de pin que usem, de manera que puguem modificar-los tocant en un sol lloc (i no havent de buscar al llarg del programa). Escriurem això una mica més elegantment:
int LED = 10 ;
int boto = 6;
void setup()
{
pinMode( LED, OUTPUT) ; // LED com a eixida
pinMode( boto , INPUT) ;// botó com a entrada
}
Vam veure que per a encendre el LED bastava usar digitalWrite(LED, HIGH)
. Per a llegir un botó es pot fer una cosa similar: digitalRead(boto)
. Vegem com podria ser nostre loop:
void loop()
{
int valor = digitalRead(boto) ; // llegim el valor de boto en valor
digitalWrite( LED, valor) ;
}
Fàcil no? Encara que el LED està encés fins que premem el botó i s’apaga en prémer.
Com podríem fer el contrari, que el LED s’encenga en prémer i s’apague si no? Bastaria amb escriure en LED el contrari del que llegim en el botó.
Existeix un operador que fa això exactament l’operador negació ” ! “ . Si un valor donat x és HIGH, llavors !x és LOW i viceversa.
De fet aquest tipus d’operacions són tan freqüents que C++ incorpora un tipus anomenat bool o booleà que només accepta dos valors TRUE (cert) i FALSE (fals) i són completament equivalents a l’1/0, i al HIGH/LOW.
Aquest nou programa seria una cosa així:
void loop()
{
bool valor = digitalRead(boto) ; // llegim el valor de boto en valor
digitalWrite( LED, !valor) ; // Escrivim valor contrari en LED
}
Hem definit valor com bool, perquè podem usar el valor de tensió alt com TRUE i el valor baix com FALSE. SI el botó no està premut el D6 llegirà TRUE i per tant posarà LED a FALSE. En cas contrari encendrà el LED.
void loop()
{
bool valor = digitalRead (LED) ;
digitalWrite( LED, !valor) ;
delay ( 1000) ;
}
De fet podríem escriure una variant curiosa del blinking LED usant l’operador negació, en només dues línies:
void loop()
{
digitalWrite( LED , ! digitalRead( LED)) ;
delay ( 1000) ;
}