¿QuéesAr dui no? De fi ni rAr d ui n oe sc omp l i c a d o,mu yc omp l i c a do .Cu an doha bl a mo mo sde And r oi d,porej emp l o,t o do ss ab emosqu es et r at adeu ns i s t ema oper at i v o.Si nembar go,Andr oi dnoesunúni c os i s t emaoper at i v o es t át i c o,c adaf abr i c ant el oi mpl ement aas umodo,ei nc l us ol a c omuni daddedes ar r ol l oi ndependi ent ehapues t oenI nt er netmul t i t udde v e r s i on esde ls i s t e mao ma per at i v o .Yh as t aempr e sa sc omoNo ki ay Amaz onut i l i z anAndr oi ds i ns i qui er amenc i onar l o.
Servidor web constituido por varias placas Arduino.
dui no.Se Al gos i mi l aral odes c r i t oenel pár r af oant er i oroc ur r ec onAr t r at adeunmi c r oc ont r ol ador ,u nap l a c a,u np eq ueñ os i s t e mad ma e pr oc es ami ent o.Si nembar go,s uc ondi c i óndes i s t emal i br ehapr opi c i ado t a nt asv a r i ac i o ne sd el omi s mo,qu mo eAr dui n on oe sun ap i ez ad e h ar d war eú ni c a ,ydeh ec h op od emo se nc o nt r a rt a nt a sc o nfi g ur a c i o ne s c o mod mo es a r r o l l a do r e sdi s p ue s t o sah ac e rc a mb mb i o senl o ses q ue ma ma s puedanex i s t i r .
Pe r oc l a r o ,d eb emo sc ua ndome me no sda r l eunar a z óndes eraAr d ui n o. Par ael l ot enemo squés aberquéha cee x ac t ament eunmi c r oc ont r ol ad or . Lar e s pu es t a,d en ue v o,e squedepe ndedel ac on figur ac i ó n.As í , e nc o nt r a r e mo mo sp l a c asd eAr d ui n oc a pa c esd ed arv i d aaunt el éf ono móvi l ,u nma ndoad i s t a nc i a, c ons ol aspor t át i l es ,yhas t acámar as f ot ogr afi cas . Par as i mpl i fi carl asc os as( yt omandoal gunal i c enc i a) ,Ar dui noesel har dwar el i br eyhar dwar el i br eel esAr dui no.
Unpoc odehi s t or i a Has t ahac er el at i v ament epoc o,unes t udi ant edes i s t emasoel ec t r óni c a t ení aqueenf r ent arqueunodel osgr andesi nc on v eni ent esdes uc ar r er a esquepar aal gunospr o y ec t oshac í af al t ahac er s ec onpl ac asy mi c r o c on t r o l a dor e sq uec o mop mo oc or o nda ba nl o s1 00dól a r e s.Es et i po depr ec i o sy aer aba st an t ec ompl i c adoenel pr i mermun dopar aun es t udi ant e,s i end oquel asc os ases t a banmu chop eo rp ar al ospa í s esen v í asdedes ar r ol l o,dondeenl ama y or í adel osc as osdi r ec t ament e pr ef er í anpas ardees t ospr oy ec t os .
Pe r oc l a r o ,d eb emo sc ua ndome me no sda r l eunar a z óndes eraAr d ui n o. Par ael l ot enemo squés aberquéha cee x ac t ament eunmi c r oc ont r ol ad or . Lar e s pu es t a,d en ue v o,e squedepe ndedel ac on figur ac i ó n.As í , e nc o nt r a r e mo mo sp l a c asd eAr d ui n oc a pa c esd ed arv i d aaunt el éf ono móvi l ,u nma ndoad i s t a nc i a, c ons ol aspor t át i l es ,yhas t acámar as f ot ogr afi cas . Par as i mpl i fi carl asc os as( yt omandoal gunal i c enc i a) ,Ar dui noesel har dwar el i br eyhar dwar el i br eel esAr dui no.
Unpoc odehi s t or i a Has t ahac er el at i v ament epoc o,unes t udi ant edes i s t emasoel ec t r óni c a t ení aqueenf r ent arqueunodel osgr andesi nc on v eni ent esdes uc ar r er a esquepar aal gunospr o y ec t oshac í af al t ahac er s ec onpl ac asy mi c r o c on t r o l a dor e sq uec o mop mo oc or o nda ba nl o s1 00dól a r e s.Es et i po depr ec i o sy aer aba st an t ec ompl i c adoenel pr i mermun dopar aun es t udi ant e,s i end oquel asc os ases t a banmu chop eo rp ar al ospa í s esen v í asdedes ar r ol l o,dondeenl ama y or í adel osc as osdi r ec t ament e pr ef er í anpas ardees t ospr oy ec t os .
T o ma ma nd oe nc u e nt aes t o , Mass i moBanz iyHer nando Bar r agan de ci di er onqueha bí aqueha cera l goal r es p ec t o.Fu ea síc omo s epus i er onmanosal aobr apar ades ar r ol l arunapl at af or maquef uer al o s ufi c i e nt eme nt ec omp l e t ac omopa r ac ompe t i rc onl o sc os t o s oss i s t e mas ma c omer c i al es ,per oqueal mi s mot mo i empopudi er amant ener s el i ger a, ec onómi c ayf ác i l dec ompar t i rporI nt er net . Esas í ,c omoenl aac t ual i dad,Ar dui noys usv ar i ant es ,puedens er nt r e10y30dól a r e s,d adqui r i dospore epe nd i e nd od ep r o v e ed or e sy di s t r i bui dor es .Cl ar o,l osdi s eñost ambi énpuedens erdi r ec t ament e des c ar gadosdeI nt er ne tdemaner agr at ui t a,yel us uar i opuede ens ambl ar l osyc ar garel s of t war enec es ar i opar ahac erf unc i onarl os mi c r oc ont r ol ador es .
¿Cómof unci onaAr dui no? Comopas ac onl ama y or í ad el aspl a c asmi mi c r oc ont r o l ad or e sl as f unc i onesdeAr dui nopuedenr es umi r s eent r es .Enpr i mer ai ns t anc i a,
t enemosunai nt er f azdeent r ada,quepuedees t ardi r ec t ament euni daa l o p s er i f ér i c os,oc onec t ar s eael l osporpuer t os .El obj et i v odees a i nt er f azdeent r adaesl l ev arl ai nf or mac i ónal mi c r oc ont r ol ador ,l api ez a enc ar gadadepr oc es ares osdat os .El ment adomi mi c r oc ont r ol adorv ar í a de pendi endodel a sne c es i da de sd el pr o y ec t oenel ques edes eaus arl a pl ac a,yha yunabuenav ar i edaddef abr i c ant esyv er s i onesdi s poni bl es .
Porúl t i mo,t enemosunai nt er f azdes al i da,quel l ev al ai nf or mac i ón pr oc es adaal osper i f ér i c osenc ar gadasdehac erel us ofi nal dees os dat os ,queenal gunosc as ospuedebi ent r at ar s edeot r apl ac aenl aque s ec ent r al i z ar áypr oc es ar anuev ament el ai nf or mac i ón,osenc i l l ament e, porej empl o,unapant al l aounal t a v ozenc ar gadademo s t r a r l av er s i ón fi nal del osdat os . Denue v o,Ar dui noesuns i s t ema,ynounapl ac aúni c a.Pores t o,el f unc i onami ent oc onc r et odepender ádel pr o y ec t o.As í ,enunmóv i l hec ho c onAr dui not endr emosv ar i osmi mi c r oc ont r ol ador es ,enc ar gadosdel as c one x i on esder ed ,l o sd at osnec es ar i o spar al ae nt r a daden úmer o sy mos t r ari nf or mac i ónenpant al l a,ent r eot r asc os as .As ími s mo, mo unr el oj
h ec h oc o nAr d ui n o s ol ament ehar í af al t aunc hi pquec uant i fi quel ahor ay l amues t r eenunapant al l a. Comoy ahemosd i c ho,Ar du i noesc a s is i nón i modehar dwar el i br e,yc o n e s o,e s t a mo sha bl a nd od eu nadel a spl a t a f o r ma smá sc omp l e j a sy v ar i abl esquepodr í anex i s t i r . INTRODUCCION ALA PROGRAMACION EN ARDUINO Si no has programado nunca no te preocupes: formas parte del 99.5% de la humanidad que nunca ha escrito una línea de código. El propósito de este tutorial es iniciarte en los rudimentos de la programación del Arduino de una forma sencilla y asequible. ecuerda que! como di"o Ste#e $obs! todo el mundo debiera saber programar porque programar te ense&a a pensar'.
1. UN POCO DE HISTORIA
El lengua"e del Arduino est( basado en el mítico lengua"e ). Si ya has traba"ado en ) este tutorial te parecer( un paseo. Si no! te basta con saber que ) es el lengua"e en el que se ha desarrollado los sistemas operati#os *+,-! inu/! y cientos de sistemas! programas y aplicaciones de ordenador. El lengua"e del Arduino es una #ersión reducida y mucho m(s sencilla de mane"ar que el lengua"e ). El ob"eti#o de este lengua"e es que puedas programar de una manera intuiti#a concentr(ndote en lo que quieres hacer m(s que en la manera de hacerlo. Arduino fue desarrollado originalmente en el ,nteracti#e 0esign ,nstitute en ,#rea 1,talia2 donde los estudiantes estaban familiari3ados con un lengua"e llamado 4rocessing. Este lengua"e estaba orientado a estudiantes de arte y dise&o y utili3aba un entorno de desarrollo #isual e intuiti#o en el cual se basó el entorno de desarrollo del Arduino y su lengua"e de programación. raba"ar con un Arduino consiste fundamentalmente en interactuar con los diferentes puertos de entrada y salida del Arduino. A fin de e#itar al programador el engorro y la comple"idad de programar estos puertos 1ya sean analógicos! digitales o de cualquier otro tipo2 el lengua"e de Arduino usa una serie de librerías 1de las que no te tienes que preocupar ya que forman parte del lengua"e! ya las iremos #iendo con detenimiento m(s adelante2. Estas librerías te permiten programar los p ins digitales como puertos de entra da o salida! leer entradas analógicas! controlar ser#os o encender y apagar motores de
continua. a mayor parte de estas librerías de base 1core libraries'2 forman parte de una macro librería llamada 6iring desarrollada por 7ernando 8arrag(n.
)ada #e3 que un nue#o puerto de entrada o salida es a&adido al Arduino! un nue#o con"unto de librerías especiali3adas en ese puerto es suministrada y mantenida por los desarrolladores del nue#o puerto.
2. VARIABLES
4rogramar consiste b(sicamente en decirle a tu Arduino y a los actuadores que este controla desde sus puertos 1o shields'2 lo que tiene que hacer 1o esperamos que haga, todos los programadores saben que estas son cosas frecuentemente diferentes2. *n programa 1o setch' en la "erga Arduino2 consigue este ob"eti#o fundamentalmente mediante el procesamiento m(s o menos comple"o de datos y la transmisión de estos datos procesados a los actuadores. o que llamamos #ariables es simplemente una manera de codificar o representar estos datos dentro del setch para facilitar su manipulación de cara a su transmisión hacia o desde los actuadoressensores. 0esde un punto de #ista pr(ctico! podemos considerar las variables como los ca"ones de un escritorio! cada uno tiene una etiqueta describiendo el contenido y dentro de ;l se encuentra el #alor de la #ariable 1el contenido del ca"ón2. 7ay tantos tipos de #ariables como de datos: n
2.1 TIPOS DE VARIABLES
El lengua"e de Arduino mane"a los siguientes tipos d e #ariables:
TIPO
void
byte
int
DESCRIPCIÓN
eser#ado para la declaración de funciones sin #alor de retorno.
*n n
55 codificado en un octeto o byte 1? bits2
1Int eger@entero2. *n n!BC D>!BC? codificado en dos octetos 1C bits2
*n entero comprendido entre >!FB!F?!CFB y G long
>!FB!F?!CF? y codificado en > bits 1equi#alen a F bytesoctetos2.
*n n
bytes 1es decir > bits2 y comprendido entr e .F=>?>5EH? y D.F=>?>5EH?
unsigned int
*n n bytes2 y comprendido entre = y C5!5F5
*n n
> bits 1F bytes2 y comprendido entre = y F!>9F!9CB!>9C
word
o mismo que unsigned int
TIPO
boolean
DESCRIPCIÓN
*na #ariable booleana que puede tener solamen dos #alores: true 1#erdadero2 o false
*n car(cter AS),, almacenado en ? bits 1un byt Esto permite almacenar caracteres como #alore char
num;ricos1su código AS),, asociado2. El código AS),, para el car(cter IaJ es 9B! si le a&adimos obtendríamos el código AS),, del car(cter IdJ
Este tipo de datos es id;ntico al tipo byte e/plica unsigned char
arriba. Se utili3a para codificar n55. Kcupa byte de memoria.
En el lengua"e de Arduino cuando queremos utili3ar una #ariable primero hay que declarar el tipo de #ariable de la que se trata 1por e"emplo Iint J y luego el nombre que le queremos dar a esa #ariable 1ItestLariableJ en los e"emplos de la tabla anterior2. 4odemos de"ar la #ariable sin iniciali3ar 1es decir! sin asignarle un #alor de partida2: int comienzo;
o! si nos interesa asignarle un #alor inicial: int comienzo = 0;
Ks aconse"amos iniciali3ar siempre #uestras #ariables en el momento de declararlas. Esto os puede ayudar a depurar #uestros setches y al mismo tiempo ah orra código. Asimismo! al declarar una nue#a #ariable tratad de anticipar el uso que el setch #a a darle a esa #ariable y el rango de #alores que #a a tomar durante la e"ecución 1por e"emplo si #a a
sobrepasar el #alor >!=== interesa hacerla long en #e3 de int ! o si #a a tomar #alores decimales entonces necesitaremos una float 2. 0e no hacerlo así podríamos encontrarnos con situaciones inesperadas durante la e"ecución del setch. E"emplo de uso de #ariables en un setch: Leamos el típico setch que hace parpadear un E0 acti#ado a tra#;s de un pin: int LEDpin = 6;
//la variable LEDpin se inicializa a 6,es decir vamos a activar
el pin 6
void setup(){
pinMode(LEDpin,OUTPUT); }
void oop(){
di!it"#$ite(LEDpin,%&'%); de" (000);
di!it"#$ite(pinLED,LO#); de" (000); }
El uso de #ariables nos permite reutili3ar este código para otro pin con tan sólo cambiar la asignación inicial de la #ariable E0pin. +o te asustes si no entiendes todo en este código. 0e momento basta con que comprendas el uso de las #ariables. odo lo dem(s lo iremos #iendo en detalle m(s adelante. +ota que cada instrucción debe de terminarse con un punto y coma 1M2 de lo contrario el compilador no entendería que la instrucción ha acabado y nos daría un error.
2.2 ARRAYS
*n IarrayJ es una colección inde/ada 1como un diccionario2 de #ariables del mismo tipo. En el caso de un array el índice no es una palabra como en el diccionario! sino simplemente un n
Si deseas iniciali3arlo al mismo tiempo puedes hacerlo de la siguiente manera:
int miList"*6+ ={,,-,.,/,6} ;
+ota importante : ten en cuenta que el primer índice de un array es siempre = 1no
•
2. •
+ota importante >: ten especial cuidado de no tratar de acceder datos fuera del array 1por e"emplo en en caso anterior miLista [7] ya que esto nos de#ol#ería datos sin sentido de la memoria.2
E"emplos de operaciones con arrays: int minuev"List"*.+ ={,,-,.} ; nuev""$i"1e = minuev"List"*+; minuev"List"*0+ = 236; nuev""$i"1e = minuev"List"*0+;
a primera instrucción crea e iniciali3a el array con F #alores. a segunda crea una nue#a #ariable y le asigna el #alor de la tercera #ariable del array que habíamos acabado de crear 1el int 2. a tercera asigna a la primera #ariable del array el #alor e ntero 1int2 9?C. 4or
2.3 STRINGS
*n string es una cadena 1array2 de caracteres. os strings pueden ser declarados de dos maneras diferentes: como #ariables tipo Ichar J o como ob"etos pertenecientes a una clase m(s comple"a llamados NStringsN de los que hablaremos al final de este capítulo. 0e momento nos ce&imos a las cadenas de caracteres definidas como #ariables Ichar J.
2.3.1 Strings como cadenas o arrays de caracteres: )uando una cadena de caracteres es almacenada en una #ariable tipo char normalmente se les hace terminar por el car(cter nulo 1AS),, =2. Esto se hace con el fin de permitir a las funciones que manipulan cadenas de caracteres en #ariables char reconocer el final de la cadena. 4or lo tanto! cuando calcules el tama&o de una cadena dentro de un array char no te ol#ides de a&adir una posición para el car(cter de Ifin de cadenaN 1AS),, =2. *n array char puede ser declarado de di#ersas maneras:
c4"$ poic4o$i*0+; c4"$ poic4o$i*3+= {57,747,7o7,7$7,7i7,7z7,7o7} ; c4"$ poic4o$i*3+= {57,747,7o7,7$7,7i7,7z7,7o7,7807} ; c4"$ poic4o$i*+= 94o$izo:; c4"$ poic4o$i*3+= 94o$izo:; c4"$ poic4o$i*0+= 94o$izo:;
En la primera línea creamos un array sin inciali3ar. En la segunda lo dimensionamos e iniciali3amos y el sistema a&ade autom(ticamente un car(cter nulo 1AS),, = ó O=2 al final del array . En la tercera a&adimos el car(cter de fin de array e/plícitamente. En la cuarta línea el array se fracciona en caracteres indi#iduales y se dimensiona autom(ticamente. En la quinta el array se fracciona autom(ticamente y en la se/ta de"amos espacios libres al final del array para nue#os datos.
2.3.2 Strings como objetos de una clase: la variable tipo ‘String’: )omo hemos se&alado antes podemos definir una #ariable de tipo String 1con la S' inicial en may
t$in!(>">);
dec"$"ndo un t$in! 9const"nte: convi$tiendo un" const"nte tipo c4"$ en
un t$in!
En el módulo Punciones Arduino' #eremos como opera la función String( y como podemos reali3ar todas las operaciones con strings que hemos citado anteriormente
2.4 CONSTANTES
Algunas #ariables no cambian de #alor durante la e"ecución del setch. En estos casos podemos a&adir la palabra reser#ada Iconst J al comien3o de la declaración de la #ariable. Esto se utili3a típicamente para definir n
Si tratas de asignar un #alor a una constante m(s adelante en el setch! el compilador te ad#ertir( de este error mediante un mensa"e. El Arduino tiene una serie de palabras reser#adas que son constantes:
•
•
•
•
•
,+4*K*4* 1EntradaSalida2. os pins digitales pueden ser configurados de ambos modos: como entrada 1,+4*2 o como salida 1K*4*2 mediante la función pin!ode(: pin!ode("#, $%&'%& )onfigura el pin como salida digital. ,+4*R4**4: eser#ado como par(metro de la función pin!ode( para el uso de resistencias pullDup integradas en el chip Atmega del Arduino. E0R8*,,+: para el uso del ed de serie con el que #iene equipado el Arduino 1generalmente conectado al pin digital 2. *EPASE 1LerdaderoPalso2. 4ara el Arduino rue 1Lerdadero2 es cualquier #alor que no es =. Palse 1Palso2 es el #alor =. 7,7K6 1Alto8a"o2. Es el #alor lógico en una puerta digital: K6 es el #alor = D= LoltiosD y 7,7 es el #alor D5 LoltiosD
onstantes tipo int: Se trata de constantes usadas directamente en un setch! como por e"emplo >. 4or defecto! estos n
8ASE
= 1decimal2
E$ET4K
>
PKTAEA0K
ninguno
8ASE
> 1binario2
? 1octal2
C 1he/adecimal2
E$ET4K
PKTAEA0K
8=
prefi"o I8J
=B
prefi"o ='
=/B8
prefi"o =/'
0ecimal es base =. Esta es la base en la que com. Sólo los caracteres = y son #(lidos. E"emplo: B0
eCuiv"e " decim" /
(( F) G (0 F) G )
El formato binario 182 solo funcionan con on bytes 1? bits2 entre = 18=2 y >55 182. Si necesitas utili3ar un entero 1int de C bits2 en forma binaria! lo piuedes hacer con un procedimiento en dos pasos como el siguiente: miInt ) (*""++""++ -./ 0 *"+"+"+"+
11 *""++""++ es el byte de orden superior
+
ECuiv"e " nHme$o decim"
6/
(( 3F) G (0 3F) G )
+ota: Es posible inducer en error al compilador incluyendo por accidente un cero como prefi"o de una constante que el compilador #a a interpreter como un n
7e/adecimal 1o he/2 se refiere a numeros en base C. os caracteres #(lidos para estos numeros son las cifras del = al 9 y las letras A a la PM A equi#ale a =! 8 a y así hasta la P 152. Lalores 7e/ #alues se identifican con el prefi"o =/'. as letras de la A a la P pueden ser escritas tanto en may
ECuiv"e " nHme$o decim" /J decim"
!ormateadores " y #:
(( 6F) G (0 6F) G )
eneralmente! una constant entera es tratada como un int con las consiguientes limitaciones en cuanto a #alores. 4ara especificar que la constant entera tiene otro tipo hay que a&adirle el sufi"o:
• • •
IuJ o I*J para que el formato de la constante sea unsigned '. E"emplo: u IlJ o IJ para que el formato de la constante sea long '. E"emplo: ===== IulJ o I*J para que el formato de la constante sea unsigned long '. E"emplo: >BCBul
onstantes tipo coma $otante % foat ): 0el mismo modo que las constantes enteras! las constantes en coma flotante se usan para hacer el código m(s legible. Estas constantes se reempla3an durante la compilación por el #alor asignado en la e/presión declarati#a. E"emplo: n @ .==5M as constantes en coma flotante pueden tambi;n ser e/presadas en una #ariedad de notaciones científicas. Ambos caracteres IEJ y IeJ pueden ser utili3ados como indicadores de e/ponente.
)K+SA+E E+ )KTA PKA+E
EU*,LAE A
=.=
=
>.FE5
>.F H =5
)K+SA+E E+ )KTA PKA+E
EU*,LAE A
CBeD>
CB!= V =D>
2.& '()*+, - #AS /AR*A)#S
2.&.1 /ariables locales y globales En todos los lengua"es estructurados como el del Arduino las #ariables tienen una propiedad llamada (mbito' 1scope' en ingl;s2. Esta propiedad se refiere al hecho de que el #alor de la #ariable puede ser accedido o no en unas partes del setch seg
(pin?oLed'o1" de@inid" como v"$i"1e !o1")
{
pinMode(pin?oLed'o1", OUTPUT); } void oop
{
int pin?oLedLoc" =-; de oop
pin?oLedLoc" de@inid" como v"$i"1e oc" dent$o
pinMode(pin?oLedLoc", OUTPUT); di!it"#$ite(pin?oLed'o1", %&'%); di!it"#$ite(pin?oLedLoc", LO#);
}
A medida que tus programas 1setches2 crecen en tama&o y comple"idad! el uso de #ariables locales es aconse"ado porque e#ita confusiones entre #ariables con el mismo nombre. En este punto pod;is preguntaros que sucede con el (mbito de las #ariables en el caso de #ariables declaradas dentro de funciones anidadas 1una función llamada desde otra función! que a su #e3 ha sido llamada desde otra función2. ógicamente! ;l (mbito de aquellas #ariables definidas en las funciones e/teriores se e/tiende a las funciones interiores! pero no #ice#ersa. a siguiente figura ilustra este concepto:
El #alor de la #ariable var3' puede ser accedido desde las funciones funci4n3'! funci4n*' y funci4n5 ' es decir! es una #ariable global. En cambio las #ariables var*' y var5 ' son #ariables locales. El #alor de la #ariable var*' sólo puede ser accedido desde las funciones funci4n*' y funci4n5 '! mientras que la #ariable local var5 ' sólo puede ser leída desde la función funci4n5 '.
2.&.2 /ariables est0ticas a palabra reser#ada 1eyWord2 static ' se usa para crear #ariables que son #isibles
creadas y destruidas cada #e3 que se llama a una función. as #ariables definidas como static ' persisten cuando la function ha terminado y conser#an los datos almacenados en ellas disponibles para la pró/ima #e3 que se llame a esa función. Estas #ariables se crean e iniciali3an solamente la primera #e3 que la función que las crea es llamada. E"emplo: K"ndom#" P"u B"d!e$ 00J K"ndom#" "nde$s up "nd don $"ndom 1eteen to endpointsA T4e m"Iimum move in one oop is !ove$ned 1 t4e p"$"mete$
e$i"A1e!in(2600);
} void oop() {
tetst $"ndom#" @unction
stepsize = /; t4isTime = $"ndom#"(stepsize);
e$i"Ap$intn(t4isTime);
de"(0);
} int $"ndom#"(int moveize){ st"tic int
p"ce;
v"$i"1e to sto$e v"ue in $"ndom " dec"$ed
st"tic so t4"t it sto$es v"ues in 1eteen @unction c"s, 1ut no ot4e$ @unctions c"n c4"n!e its v"ue p"ce = p"ce G ($"ndom(moveize, moveize G )); i@ (p"ce Q $"ndom#"LoK"n!e) {
c4ec oe$ "nd uppe$ imits p"ce = p"ce G ($"ndom#"LoK"n!e p"ce); $e@ect num1e$ 1"c in
positive di$ection } ese i@(p"ce R $"ndom#"%i!4K"n!e){
p"ce = p"ce (p"ce $"ndom#"%i!4K"n!e);
$e@ect num1e$ 1"c
in ne!"tive di$ection } $etu$n p"ce; }
2.&.3 /ariables vol0tiles )uando declaramos una #ariable como volatile' lo que estamos haciendo es instruyendo al compilador a cargar siempre la #ariable desde la memoria AT y no desde uno de los registros internos del procesador. a ra3ón por la que hacemos esto es que! ba"o ciertas condiciones! el #alor de una #ariable almacenada en los registros internos puede sufrir alteraciones. En Arduino el
st"te = st"te;
}
2.6 MARCADORES SINTÁCTICOS
Antes de proseguir #amos a e/plicar algunos marcadores que hemos #isto en e"emplos anteriores sin e/plicarlos debidamente:
2..1 !in de instruccin: 45 7abr(s obser#ado que todas las declaraciones e instrucciones terminan en un punto y coma: int " = -;
Esta es una con#ención sint(ctica que con#iene no ol#idar si no queremos tener que #;rnoslas con un impenetrable y a parentemente ilógico error del compilador.
2..2 #laves %curly brac6ets57 895 as lla#es de apertura y cierre son una parte importantísima de la sinta/is del lengua"e de programación de ). Se utili3an en di#ersas estructuras 1que #eremos a continuación2 y son frecuentemente una fuente de dolores de cabe3a para los principiantes. a lla#e de apertura X' debe de ser complementada siempre por un a lla#e de cierre Y'. El ,0E de Arduino ,0E 1entorno de desarrollo integrado2 incluye una función que nos ayuda a comprobar este equilibrio entre lla#es de apertura y de cierre. Simplemente con seleccionar una lla#e de aperturacierre! el ,0E nos indicar( donde est( la lla#e de cierreapertura que casa' con la seleccionada 1logical companion'2. +o te fíes demasiado de esta funcionalidad del ,0E ya que a #eces se puede equi#ocar y se&alar una compa&era' equi#ocada. 0ado que el uso de las lla#es es tan #ariado y e/tendido en )! se recomienda escribir la lla#e de cierre "usto despu;s de la de apertura para ir rellenando' el interior con código y e#itar así ol#idarnos de escribir la lla#e de cierre al final 1piensa que probablemente #as a escribir bucles! funciones! etc. dentro de estas lla#es que lle#aran a su #e3 lla#es de apertura y cierre. 0e esta manera e#itas ol#idos que te lle#arían a errores bastante impenetrables del compilador que pueden a #eces ser difíciles de locali3ar en un programa grande. 4or otra parte! ten en cuenta que las lla#es de apertura y cierre son el marcador sint(ctico m(s importante del lengua"e y su uso en una posición incorrecta pueden lle#arte a una e"ecución del programa totalmente diferente de la que habías pre#isto. *n peque&o resumen de los usos m(s frecuentes de las lla#es de apertura y cierre: En funciones: void m@unction(d"t"tpe "$!ument){
inst$uccion(es) }
En bucles: 4ie (1ooe"n eIp$ession) {
inst$uccion(es) } do {
inst$uccion(es) } 4ie (1ooe"n eIp$ession); @o$ (initi"is"tion; te$min"tion condition; inc$ementin! eIp$) {
inst$uccion(es) }
En instrucciones condicionales: i@ (1ooe"n eIp$ession) {
inst$uccion(es) }
ese i@ (1ooe"n eIp$ession) {
inst$uccion(es) } ese {
inst$uccion(es)
}
2..3 omentarios dentro de un programa %documentando nuestros programas7 7abr(s notado que muy frecuentemente a&adimos comentarios al código de un setch o programa con el efecto de hacerlo m(s legible! f(cil de entender 1y mantener2 por otro programador! en definiti#a! me"or documentado. eneralmente los comentarios se utili3an para informar sobre la manera en que traba"a el programa 1a otros programadores! o recordase a sí mismo cuando tienes que modificar un programa que escribiste hace tiempo2 os comentarios son ignorados por el compilador y no se e/portan al procesador! así que no toman ning
Esto es un coment"$io de un" so" ne"A Todo o Cue 4" desde " do1e 1"$$" incin"d"
4"st" e @in" de " ne" es un coment"$ioA esto es un coment"$io de 1oCue VCue ocup" v"$i"s ne"s Ve suee us"$ p"$" coment"$ un 1oCue de cSdi!o (en vez de un" so" inst$ucciSn como e coment"$io de ne" de "$$i1"
+ota: se pueden incluir comentarios de línea dentro de un comentario de bloque! pero no #ice#ersa. 7ay que tener mucho cuidado y cerrar el comentario de bloque con un V. 0e lo contrario el compilador producir( un mensa"e de error. 4oner entre comentarios de bloque 1VQV2 una bloque entero de código que da problemas es una buena idea de cara a identificar el elemento que da problemas sin tener que borrar 1y reescribir2 todo el código del bloque en cuestión.
2.. ;de
El compilador sustituir( el nombre de la constante 'inLedo8o por #o8o. a sinta/is del Zdefine es: de@ine ?om1$econst"nte
v"o$
1nota que el 6 debe de ir pegado al define y es obligatorio2 E/ample #define ledPin 3
•
•
+ota importante: ecuerda que +K hay punto y coma tras la instrucción 6define. Si lo pones el compilador te agreder( con una serie de mensa"es ininteligibles mensa"es de error. Zdefine 4ined FM [erroneo\\. [+o pongas el M al final\
0el mismo modo incluir un signo igual tras el nombre de la constante conseguir( tambi;n irritar igualmente al compilador. #define PinLed =5
//¡Error!! ¡o pon"as el si"no i"al!
2..& ;include: *ncluyendo bibliotecas e=ternas. a instrucción 6include' se utili3a para incluir bibliotecas e/ternas en un setch. Esto da el programador el acceso a un gran n
, 23,
0, /J6., 3./6,
0,0,0,0,0,0,0,0,230,3263,2J6,2J6,./00};
2.7 OPERADORES ARITMÉTICOS
Arduino mane"a los siguientes operadores aritm;ticos: @ operador de asignación Almacena el #alor a la derecha signo de igualdad en la #ariable a la i3quierda del signo de igualdad.
Es importante notar que este operador de asignación del lengua"e de programación de ) tiene un significado diferente del que se le da com
dec"$" un" v"$i"1e int "m"d"
sens"
"m"cen" en sens" (t$"s di!it"iz"$o) e vot"We
medido en e pin "n"S!ico 0
•
•
+otas importantes: a #ariable en el lado i3quierdo del operador de asignación 1@ 2 necesita poder almacenar el #alor que se le asigna. Si la #ariable no es lo suficientemente grande 1int en #e3 de long int ! por e"emplo2! el #alor almacenado en la #ariable ser( incorrecto. +o confunda al operador de asignación ]@^ 1un
Adicin> substraccin> multiplicacin> y divisin Estos operadores de#uel#en la suma! la diferencia! el producto! o el cociente 1respecti#amente2 de los dos operandos. a operación se lle#a a cabo usando el tipo de datos de los operandos! así pues! por e"emplo! 9F da > puesto que 9 y F son ints. Esto tambi;n significa que la operación puede desbordar si el resultado es m(s grande que el que se pueda almacenar en el tipo de datos 1por e"emplo! a&adiendo a un int con el #alor >.BCB da D>.BC?2. Si los operandos son de di#ersos tipos! el tipo m(s grande' se utili3a para el c(lculo. Si uno de los n
Sinta/is $esut"do = v"o$ G v"o$; $esut"do = v"o$ v"o$; $esut"do = v"o$ v"o$;
$esut"do = v"o$ v"o$;
4arametros: valor$% cal&ier variable o constante
valor'% cal&ier variable o constante
+otas importantes:
•
•
•
•
en en cuenta que las operaciones entre constantes de tipo int se almacenan por defecto en una #ariable tipo int ! de manera que en algunos c(lculos entre constantes 1por e"emplo C=V ===2 el resultado puede desbordar la capacidad de almacenamiento de una #ariable int y de#ol#er un resultado negati#o. Eli"e #ariables de tama&o suficientemente grande para que puedan almacenar los resultados de los c(lculos por grandes que estos sean. 4ara c(lculos con fracciones usa #ariables en coma flotante 1float 2! pero sea consciente de sus des#enta"as: utili3ación de m(s memoria! lentitud de c(lculo. *tilice la función de con#ersión my
? %mdulo7: El operador = 1módulo2 calcula el resto cuando un n
I contiene
I = 2 Y /;
I contiene .
I = / Y /;
I contiene 0
I = . Y /;
I contiene .
E"emplo en un setch: modi@ic" posiciSn " posiciSn os v"o$es de un "$$" voviendo " empez"$ en " p$ime$" posiciSn (0) cu"ndo se 4"" e!"do " " Htim" (2) int v"ues*0+; int i = 0;
void setup() {} void oop() { v"ues*i+ = "n"o!Ke"d(0); i = (i G ) Y 0;
moduo ope$"to$ $os ove$ v"$i"1e
}
El operador modulo no funciona con #ariables tipo float .
•
2.8 OPERADORES COMPUESTOS
@@ %incremento7 B %decremento7 Estos operadores se utili3an respecti#amente para incrementar o decrementar un #ariable. Sinta/is IGG;
inc$ement"
un" unid"d $eto$n" e "nti!uo v"o$ de I
GGI;
inc$ement" I un" unid"d $eto$n" e nuevo v"o$ de I
I ;
dec$ement" I un" unid"d $eto$n" e "nti!uo v"o$ de I
I ;
dec$ement" I un" unid"d $eto$n" e nuevo v"o$ de I
E"emplos: I = ; = GGI;
I contiene "4o$" e v"o$ -, contiene -
= I;
I contiene "4o$" e v"o$ , si!ue conteniendo -
,peradores compuestos @C > DC > EC > C Estos operadores reali3an una operación matem(tica en una #ariable con otra constante o #ariable. Estas notaciones son simplemente una simplificación pr(ctica de una sinta/is m(s comple"a tal y como se muestra a continuación: Sinta/is: I G= ;
eCuiv"e " " eIp$esiSn I = I G ;
I = ;
eCuiv"e " " eIp$esiSn I = I ;
I = ;
eCuiv"e " " eIp$esiSn I = I ;
I = ;
eCuiv"e " " eIp$esiSn I = I ;
4arametros:
/: cualquier tipo de #ariable y: cualquier tipo de #ariable o constante E"emplos: I = ; I G= .;
I contiene 6
I = -;
I contiene -
I = 0;
I contiene -0
I = ;
I contiene /
2. UTILIDADES
2.F.1 l operador siGeoH Este operador nos permite conocer el n
4ar(metros: Lariable: cualquier tipo de #ariable o array 1int! float! byte2 E"emplo: Este operador es muy pr(ctico para traba"ar con arrays 1por e"emplo strings de te /to2 cuando queremos cambiar el tama&o d el array sin alterar otras partes del programa. El programa del e"emplo imprime car(cter a car(cter un string de te/to. 4rueba el siguiente programa cambiando la frase: c4"$ mt$*+ =
e$i"A1e!in(2600);
} void oop() {
@o$ (i = 0; i Q sizeo@(mt$) ; iGG){ e$i"Ap$int(i, DE); e$i"Ap$int(< = <);
e$i"A$ite(mt$*i+); e$i"Ap$intn(); } de"(/000); $"entiz" e p$o!$"m"Z
}
2.F.2 l operador IR,J(( Este operador almacena datos en la memoria flash en #e3 de hacerlo en la AT del sistema. Este operador 4KTET debe de ser usado . Este operador ordena al compilador que almacene los datos especificados en la línea del operador en la memoria flash en #e3 de hacerlo en la AT del sistema donde iría normalmente. El operador 4KTET forma parte de la librería Ipgmspace:hJ! por lo tanto debes incluir esta librería al comien3o de tu setch: incude Q"v$p!msp"ceA4R
Sinta/is: data&ype variable?ame[] '$@!A! ) BdataInt+, dataInt", dataInt#CD •
program memory data&ype Ecualquier tipo de variable de los incluidos aba8o (program memory data types variable?ame E el nombre del array que quieres almacenar en memoria flash:
•
7ay que tener en cuenta que! dado que el operador utilidad 4KTET es un modificador #ariable! no hay una regla fi"a sobre donde colocarla dentro de la línea de especificaciones. a e/periencia muestra que las dos siguientes ubicaciones de 4KTE+ tienden a funcionar bien: d"t"Tpe v"$i"1e?"me*+ PKO'MEM = {}; PKO'MEM
d"t"Tpe
est" u1ic"ciSn de PKO'ME? @uncion"A
v"$i"1e?"me*+ = {}; est" t"m1i[n
4ero no esta otra: d"t"Tpe PKO'MEM v"$i"1e?"me*+ = {};
ni o intentesZ
4KTET puede ser usado con una simple #ariable! sin embargo! debido a la comple"idad de su uso! sólo merece la pena usarla cuando quieres almacenar en memoria flash un bloque relati#amente grande de datos 1generalmente un array2.
El uso del operador 4KTET implica dos operaciones bien diferenciadas: almacenamiento en memoria flash y lectura usando m;todos 1funciones2 específicos definidos en la librería Ipgmspace:hJ para de#ol#er los datos a la memoria AT del sistema afín de poder usarlos dentro del setch. al y como hemos mencionado antes! es esencial usar los tipos de datos especificados en pgmspace:h. 4or alguna e/tra&a ra3ón! el compilador no admite los tipos de datos ordinarios. 0etallamos deba"o la lista completa de #ariables 1 program memory data types'2. 4arece ser que la program memory ' no se lle#a nada bien con los n
5c4"$7 con si!no ( 1te) J " 3
p$o!Xuc4"$
5c4"$7 sin si!no (unsi!ned) ( 1te) 0 " //
p$o!Xint6Xt
5 int7 con si!no ( 1tes) -,J6J " -,J63
p$o!Xuint6Xt
5int7 sin si!no ( 1tes) 0 " 6/,/-/
p$o!Xint-Xt
5on!7 con si!no (. 1tes) ,.J,.3-,6.3 " ,.J,.3-,6.JA
p$o!Xuint-Xt
on!\7 sin si!no (. 1tes) 0 " .,2.,26J,2/
E"emplo Este e"emplo muestra como leer y escribir #ariables tipo unsigned charN 1 byte2 e I int J en 4KTET. incude Q"v$p!msp"ceA4R
"1$i$ i1$e$" 5p!msp"ceA47
"m"cen"$ en PKO'MEM "!unos 5unsi!ned ints PKO'MEM
p$o!Xuint6Xt c4"$et*+
= { 6/000, -J26, 63.-, 0, -.};
s"ve some c4"$s p$o!Xuc4"$ si!nMess"!e*+ PKO'MEM
= {
EPNaOL<}; unsi!ned int disp"&nt; int ;
cont"do$
c4"$ m4"$; ee$ un 5int7 de dos 1tes de " PKO'MEM "m"cen"$o en 9disp"int: disp"&nt = p!mX$e"dXo$dXne"$(c4"$et G ) ee$ un 5c4"$t7 de un 1te de " PKO'MEM "m"cen"$o en 9m4"$t: m4"$ =
p!mX$e"dX1teXne"$(si!nMess"!e G );
TOMANDO DECISIONES: LAS ESTRUCTURAS DE CONTROL
4rogramar consiste b(sicamente en decirle a nuestro ordenador 1el Arduino2 que es lo que queremos que haga cuando se confronte con una o #arias opciones. En otras palabras! queremos que el Arduino pueda tomar decisiones en base a los datos disponibles en ese momento 1el #alor de las #ariables2. Estas decisiones se toman en base a el resultado de uno o #arios tests lógicos 1boolean tests' en ingl;s2. El resultado de estos tests lógicos ser(true o false 1#erdaderofalso2 y determinar( la decisión elegida. E"emplos de tests lógicos: 6( ) $'(* tre
3( + '* tre
-5)= 3'* false
'( == '$* false
a siguiente tabla muestra los operadores lógicos y su descripción:
OPERADOR
DESCRIPCIÓN
OPERADOR
_
Tayor que
`
_@
Tayor o igual que
`@
@@
,gual que
\@
Es importante notar que @@ no es lo mismo que @. @@ es el operador lógico de igualdad y de#uel#e el #alor true o false mientras que @ se usa para asignar #alores a #ariables o arrays. os tests lógicos tienen lugar dentro de las llamadas estructuras de control' 1control statements' en ingl;s2. Estas estructuras son las que deciden el camino seguido por el setch en cada momento. 4or e"emplo pueden #erificar el ni#el de tensión 17,7K62 en la entrada de cierto pin y en base a el #alor leído acti#ar 1o no2 un led conectado a otro pin.
A continuación #amos a e/plicar las estructuras de control utili3adas en el lengua"e del Arduino.
3.1
*H> else> else iH
a primera estructura de control que #amos a considerar es el operador if' 1si' en espa&ol2. Este operador #erifica simplemente si un test lógico es cierto o falso 1es decir! si de#uel#e el #alor true o false2 y en función de esto reali3a 1o no2 una serie de acciones. En t;rminos pr(cticos el if ' act
4or e"emplo: i@ (v"$N Q v"$B) { di!it"#$ite(PinLedKoWo, %&'%); }
En el caso de arriba el setch compara el calor de las #ariables var3' y var*'. Si el #alor de var3 es inferior al de var*! el código contenido en el bloque del if 1entre las lla#es BF y FDG 2 ser( e"ecutado a continuación. En caso contrario! este código queda sine"ecutar y se pasa a la instrucción siguiente despu;s del bloque if . El operador ifG puede ser complementado con el operador elseG 1sinoQ2. El bloque de acciones asociadas al else' son e"ecutadas si el test lógico del if ' dió falseG como resultado. Esto funcionaría de la siguiente manera: i@ (test S!ico) { $e"iz" un" se$ie de "cciones si e test S!ico devueve ve$d"de$o (9t$ue:) } ese { $e"iz" un" se$ie de "cciones si e test S!ico devueve @"so (9t$ue:) }
Leamos el siguiente e"emplo pr(ctico: i@ (v"$N Q v"$B) { di!it"#$ite(PinLedKoWo, %&'%);
} ese {
di!it"#$ite(PinLedKoWo,LO#);
}
En este caso! si el #alor de var3 es mayor o igual que el de var* el led conectado al pin 1'inLedo8o2 ser( apagado. 4odemos complicar esta estructura de control un poco m(s con la inclusión de una condición dentro del if9 el Felse ifG: El e"emplo siguiente muestra el uso de esta nue#a condición: i@ (v"$N Q v"$B) { di!it"#$ite(PinLedKoWo, %&'%); } ese i@ (v"$N == v"$B) { di!it"#$ite(PinLede$de, %&'%); } ese {
di!it"#$ite(PinLedKoWo,LO#);
}
)omo #eis el else ifG nos permite afinar el control dentro del if '. En efecto! con el else if' hemos introducido un test lógico dentro del if': si el #alor de las dos #ariables 1#arA' y #ar8'2 es id;ntico podemos e"ecutar un bloque alternati#o de acciones. En este caso acti#amos el led #erde. Es importante notar que solamente un bloque de acciones es e"ecutado dentro de un if '. 0e hecho podemos incluir #arios else if ' dentro de un if ' para reali3ar un control mucho m(s fino dentro del setch. Sin embargo! esto no sería una solución muy elegante 1ni de f(cil lectura dentro del setch2. 4or eso! para este tipo de tomas de decisión donde nos enfrentamos a muchas opciones diferentes! la estructura de control ideal es el switch case' que #eremos a continuación.
3.2 ligiendo entre mKltiples opciones: SLitcM case a estrutura switch case' es la opción ideal cuando tenemos que elegir entre un n a la de moda! a la de electrodom;sticos! etcQ2.
Esta estructura funciona de la siguiente manera: sitc4 (v"$i"1e){ c"se v"o$ inst$ucciones eWecut"d"s cu"ndo e v"o$ de " v"$i"1e == v"o$
1$e";
c"se v"o$ inst$ucciones eWecut"d"s cu"ndo e v"o$ de " v"$i"1e == v"o$
1$e";
c"se v"o$- inst$ucciones eWecut"d"s cu"ndo e v"o$ de " v"$i"1e == v"o$
1$e";
AAAAA de@"ut inst$ucciones eWecut"d"s en cu"Cuie$ ot$o c"so 1$e"; }
El brea2 ' al final de cada bloque de instrucciones dentro de cada case' es opcional. 0e no ponerlo! tras haber e"ecutado ese bloque se seguirían anali3ando los dem(s casos hasta el final. 4or tanto! es con#eniente incluir la instrucción brea2 ' al final de cada bloque si queremos impedir que el setch se siga e"ecutando dentro del switch' 1esto har( nuestro setch m(s eficiente2. a instrucción default ' es tambi;n opcional. Se utili3a cuando queremos que se realicen una serie de acciones concretas en caso de que ninguno de los casos anteriores haya sido acti#ado.
3.3 #os operadores lgicos booleanos. os operadores lógicos booleanos son la sal de la programación. Sin ellos no podríamos reali3ar programas de una cierta comple"idad. 4or esto es importante que entendamos bien cómo funcionan. Arduino usa los tres operadores lógicos m(s conocidos: A+0! K y +K pero los representa de una manera diferente:
•
A+0 se representa como
•
K se representa como ||
•
+K como \
Leamos cómo funcionan:
AND i@ (v"$N R v"$B bb v"$ R v"$D) { di!it"#$ite(pinLedKoWo, %&'%); }
Si el #alor de la #ariable #arA es mayor que el de #ar8 Y el #alor de la #ariable #ar) es mayor que el de #ar0! e"ecutar las instrucciones del bloque: encender el led ro"o.
OR i@ (v"$N R v"$B
|| v"$
R v"$D) {
di!it"#$ite(pinLede$de, %&'%); }
Si el #alor de la #ariable #arA es mayor que el de #ar8 O el #alor de la #ariable #ar) es mayor que el de #ar0! e"ecutar las instrucciones del bloque: encender el led #erde.
NOT i@ (1otonPus"do) { di!it"#$ite(pinLedNzu, %&'%); }
Si el botón no est( pulsado 1+K boton4ulsado @@ true2 encender el led a3ul.
3. ,peradores lgicos binarios A medida que progreses en tus setches para Arduino #er(s que necesitas acceder al contenido de algunas #ariables a ni#el binario 1bit a bit2. En algunos casos tendr(s que leer información de sensores que sólo se puede encontrar a este ni#el! en otros se tratar( de programar un dispositi#o o una acción. a operación lógica m(s sencilla a ni#el de bit es el +K. )omo sin duda sabes! un +K aplicado sobre un bit simplemente cambia su polaridad 1es decir! su #alor pasa de ser el contrario del que tenía antes: con#ierte un = en un y #ice#ersa2. *n e"emplillo: 1recuerda que en Arduino el +K a ni#el binario se escribe 2 int I = .; En 1in"$io esto es 000 int = I; == 000
4or otra parte los operadores lógicos A+0! K y -K! 1! y en el lengua"e Arduino2 funcionan del siguiente modo a ni#el de bit:
A
B
A AND B (A&B)
=
=
=
=
=
=
=
=
=
=
A OR B (A | B)
A XOR B(A^B)
Estos operadores se usan a #eces para enmascarar ciertos bits en un n
4uedes tambi;n acti#ar 1set2 o borrar 1clear2 uno o #arios bits en un n
NN y OO
`` y __ son los operadores de despla3amiento binario 1bit shift operators2 que te permiten despla3ar los bits de una #ariable a una cierta posición antes de traba"ar con ellos. El primer operador despla3a los bits hacia la i3quierda y el segundo a la derecha como muestran los siguientes e"emplos. int I = .; En 1in"$io esto es 000 int = I QQ ; == 3. == B0000 int z = I RR ; z == 0 == B00
a segunda instrucción 1int y @ / `` M2 copia el #alor de / en y para luego despla3ar sus bits 1los de y2 una 12 posición hacia la i3quierda rellenado con un cero a la derecha. a tercera instrucción copia el #alor de / en 3 para luego despla3ar sus bits 1los de 32 dos 1>2 posiciones a la derecha rellenando con ceros a la i3quierda. 7a de notarse que la #ariable / original permanece inalterada. Estos shifts 1despla3amientos2 tienen lugar sobre las #ariables y! 3. 7ay que e#itar las operaciones de despla3amiento con n
4. !A TRABA"AR# LAS ESTRUCTURAS EN BUCLE $ LOOPS )
e estar(s preguntando cuando le #amos a poner a traba"ar al Arduino en serio. a hemos llegado. as estructuras en bucle 1loops' en ingl;s2 reali3an una tarea de manera repetiti#a hasta que ;sta se ha completado. os puedes #isuali3ar como una la#adora que da #ueltas y #ueltas a la ropa reali3ando una serie de acciones hasta que est( limpia. Arduino mane"a tres estructuras en bucle diferentes: forG ! whileG y do whileG .
.1 l bucle Hor5 Este tipo de bucles se utili3a para e"ecutar un bloque de código un cierto n
e$i"A1e!in(2600);
} void oop {
@o$ (int i = 0; i Q 00; iGG){
e$i"Ap$intn(i); }
}
E/pliquemos cómo funciona el bucle for ' basados en el e"emplo anterior:
a #ariable i es iniciali3ada con el #alor =. Al final de cada bucle la #ariable se incrementa en 1i00 es una manera abre#iada de codificar i ) i 0 "2. El código en el interior del bucle se e"ecuta una #e3 tras otra hasta que alcan3a el #alor ==. En ese punto el bucle finali3a y recomien3a #ol#iendo a poner la #ariable i a =. a primera línea del bucle es la instrucción for '. Esta instrucción tiene siempre tres partes: iniciali3ación! test y el incremento o decremento de la #ariable de control o contador. a iniciali3ación sólo sucede una #e3 al comien3o del bucle. El test se reali3a cada #e3 que el bucle se e"ecuta. Si el resultado del test es #erdadero' 1true2! el bloque de código se e"ecuta y el #alor del contador se incrementa 1HH2 o decrementa 1G2 tal como est( especificado en la tercera parte del for '. El bloque de código 1o rutina2 continuar( e"ecut(ndose hasta que el resultado del test sea false' 1es decir! cuando el contador i haya alcan3ado el #alor ==2.
.2 l bucle LMile5 Tuchas #eces la condición para que el bucle siga e"ecut(ndose es mucho m(s comple"a que la estudiada en el caso anterior. En estos casos utili3aremos el bucle while'. Este tipo de bucle testea una e/presión contenida entre par;ntesis y e"ecuta el bloque de código contenido entre lla#es 1curly braquets' en ingl;s2 hasta que la e/presión es falsa. 4ie (eIp$ession) { do st"tements }
El código del bucle for ' que hemos e/plicado antes se puede reescribir como un bucle while' de la siguiente manera: void setup() {
e$i"A1e!in(2600);
} void oop(){ int i = 0; 4ie (i Q 00){
e$i"Ap$intn(i);
iGG; }
}
4uedes considerar un bucle for ' como un caso particular del bucle while'. El bucle 'while' se usa cuando no estamos seguros de cuantas #eces se #a a e"ecutar el bucle. El bucle while' se suele usar para testear la entrada de sensores o botones. a siguiente rutina testea el #alor de un sensor: int senso$"ue = 0; 4ie (senso$"ue Q 000 { senso$"ue = "n"o!Ke"d("n"o!Pin); }
El código entre lla#es se e"ecutar( ininterrumpidamente mientras el #alor de sensorHalue sea inferior a >===. )uando programes bucles while' aseg
.3 l bucle do LMile5 Este tipo de bucle es algo menos usual que el bucle while'. a diferencia con el while' es que el do while' testea la e/presión test al final del bucle 1es decir despu;s de e"ecutar el bucle. 0e esta manera nos aseguramos que el bucle se e"ecuta al menos una #e3. El bucle do while' se usa típicamente para leer datos de un fichero do { 1oCue de cSdi!o ($utin")
} 4ie (eIp$esiSn);
Al igual que en el caso anterior! el bloque de código comprendido entre las lla#es del bucle se e"ecutar( hasta que la e/presión resulte ser falsa.
. ontinue. vitar la ejecucin de parte del bloPue de cdigo en el bucle. A #eces dentro de un bucle 1for ! do o while2 queremos que sólo parte del bloque de código se e"ecute antes de iniciar la siguiente iteración. a instrucción continue' nos permite saltar el resto del bloque de código y #ol#er a la e/presión de control del bucle para proceder con las siguientes iteraciones. Leamos un e"emplo: @o$ (I = 0; I Q //; I GG) { i@ (I R .0 bb I Q 0){
s"t"$ v"o$es de I en " eWecuciSn de 1uce
continue; } di!it"#$ite(P#Mpin, I);
de"(/0);
}
En este e"emplo #emos cómo conseguir que se e#ite la e"ecución de la función digitalrite( cuando J est; comprendido entre F= y >=.
.& Joto. scapando de un bucle A #eces sucede que se nos enreda' un poco el código con bucles anidados en otros bucles que est(n dentro de otros buclesQ. y no sabemos cómo salir de este laberinto de bucles. En este tipo de situaciones a #eces una instrucción de escape' puede sernos de gran ayuda. a instrucción goto permite transferir el control a un punto especificado mediante una etiqueta 1por e"emplo fuera de la mara&a de bucles en la nos hemos metido2. Esta es la sinta/is del goto: etiCuet" Z
!oto etiCuet"; t$"ns@ie$e " eWecuciSn de p$o!$"m" " " etiCuet"
+ormalmente se desaconse"a el uso del goto en programación ya que el uso del goto puede lle#arnos a la creación de programas con un flu"o de e"ecución indefinido! que puede dificultar mucho la detección y eliminación errores 1debugging2. Leamos un e"emplo de utili3ación del goto9 @o$(1te $ = 0; $ Q //; $GG){ @o$(1te ! = //; ! R ; !){ @o$(1te 1 = 0; 1 Q //; 1GG){ i@ ("n"o!Ke"d(0) R /0){ !oto esc"pe;} mo$e st"tements AAA } } } esc"pe
En este e"emplo podemos salir bruscamente' de ese grupo de tres bucles anidados en caso de que la lectura de un pin analógico sea mayor que >5=. En ese caso! el flu"o de e"ecución sería transferido fuera de los tres bucles a la etiqueta escape'.
%UNCIONES
7emos #isto ya de pasada las dos funciones o rutinas principales de un setch: setup( y loop(. Ambas se declaran de tipo void ! lo cual significa que no retornan ning
función entre par;ntesis. ya sólo queda lo m(s difícil: escribir el código de la función entre lla#es: tpe @unction?"me(p"$"mete$s){ e cSdi!o de " @unction v" "CuiA }
ecuerda que si la función no retorna un #alor hay que definirla como de tipo void ' 1#acio2. 4ara de#ol#er el control a setch la función usa la instrucción return seguida por el nombre de la #ariable que se quiere de#ol#er y luego un punto y coma 1M2. a siguiente rutina muestra una función que con#ierte una temperatura e/presada en grados Pahrenheit a )elsius 1tambi;n conocidos como grados centígrados2: @o"t c"cTemp(@o"t @"4$en4eit){ @o"t cesius; cesius = (@"4$en4eit V -) A3; $etu$n cesius; }
a function se declara de tipo float y se le pasa un par(metro 1tambi;n de tipo float 2 que representa los grados Pahrenheit medidos p or un sensor. 0entro de la función se declara la #ariable )elsius 1de tipo float que #a a contener la medida de la temperatura pasada en Pahrenheit tras su con#ersión a )elsius 1imagino qu e la fórmula de con#ersión te resulta familiar2. a instrucción return de#uel#e el #alor en )elsius de la temperatura pasada en Parenheit. Esta función puede ser usada como parte de un sistema para registrar las temperaturas captadas por un sensor a lo largo del tiempo. )omo puedes #er! el uso de funciones es la manera ideal de simplificar tu código y abordar tareas repetiti#as.
float e/ponenteM float resultadoM
#oid setup12 X Serial.begin19C==2M
Y #oid loop 12 X for 1e/ponente@=M e/ponente`CM HHe/ponente2X resultado @ poW 1>.=!e/ponente2M uint?Rt 3 @ 1byte2resultadoM int b @ 1int2resultadoM int t @ int1resultado2M Serial.print1> ele#ado a 2M Serial.print1e/ponente2M Serial.print1 @ 2M Serial.print1resultado2M Serial.print1 en floatM 2M Serial.print132M Serial.print1 en byteM 2M Serial.print1b2M Serial.print1 en enteroM 2M Serial.print1t2M Serial.println1 en entero 2M delay1===2M Y esultado > ele#ado a =.== @ .== en floatM en byteM en enteroM en entero > ele#ado a .== @ >.== en floatM > en byteM > en enteroM > en entero > ele#ado a >.== @ F.== en floatM en byteM en enteroM en entero > ele#ado a .== @ ?.== en floatM B en byteM B en enteroM B en entero > ele#ado a F.== @ C.== en floatM 5 en byteM 5 en enteroM 5 en entero > ele#ado a 5.== @ >.== en floatM en byteM en enteroM en entero