Curso Arduino Nivel 1 - Clase 3: Las Variabl… Variabl… Variables Una variable es un «lugar» para almacenar un trozo de datos. Tiene un nombre, un valor y un tipo. Por ejemplo, esta declaración (llamada declaración ): int pin = 13; crea una variable cuyo nombre es pin , cuyo valor es 13 y cuyo tipo es int . Más adelante en el programa, puede hacer referencia a esta variable por su nombre, en cuyo punto se buscará y utilizará su valor. Global/local Una variable puede estar de nida como global o local. Se re ere a la parte de tu programa en la que se puede usar la variable. Esto está determinado por el lugar donde lo declaras en tu código. Por ejemplo, si quieres poder utilizar una variable en cualquier parte de tu programa, puedes declarar esa variable en la parte superior de tu código. Esto se llama una variable global ; Las variables en lenguaje de programación C, que usa Arduino, tienen esta propiedad llamada «alcance». Un ámbito (scope en inglés) es una región del programa. Hay tres lugares donde se pueden declarar variables: Dentro de una función o un bloque. Ahí se llaman variables locales . En la de nición de parámetros de función. Ahí se llaman parámetros formales . Fuera de todas las funciones. Ahí se llaman variables globales . Ejemplo global: Arduino 1 2 3 4 5 6 7 8 9 10 11 pin int = 13; //Esta variable es global. Se puede usar en todas las f void setup () { pinMode (pin, OUTPUT); } void loop () { digitalWrite (pin, HIGH); } //Como puedes ver usamos "pin" aquí en "voi //pero también aquí en "void loop" Como puede ver, pin se usa en las funciones setup () y loop (). Ambas funciones se re eren a la misma variable, así que cambiar esa variable, afectará el valor que tiene en todas las funciones. Ejemplo local Si solo necesitas usar una variable en una sola función, puede declararla allí mismo y en ese caso su alcance estará limitado a esa función. Por ejemplo: Arduino 1 void setup () 2 { 3 pin int = 13; //Esta variable es local. Solo se puede usar 4 pinMode (pin, OUTPUT); 5 digitalWrite (pin, HIGH); 6 } En este caso, la variable «pin» solo se puede usar dentro de la función setup (). Si intentas hacer algo como esto: Arduino 1 void loop () 2 { 3 digitalWrite (pin, LOW); // incorrecto: "pin" no está declarado aquí en 4 } obtendrás el mismo mensaje que antes: «error: ‘pin’ no se declaró en este void». Es decir, aunque haya declarado un «pin» en algún lugar de tu programa, estás intentando usarlo en algún lugar fuera de su alcance. Se entiende ¿no? Tipos de variables Los datos que guardamos en nuestro código en las variables pueden ser de diferentes tipos, vamos a listar algunos de ellos. Para ver todos los tipos de variables básicos de Arduino se puede consultar esta página web. bool, ocupa 1 byte (8 bits) y solo puede tener dos valores: falso (0) 0 verdadero (1). char, se utilizan para almacenar caracteres, ocupan un byte (8 bits). byte, pueden almacenar un número entre 0 y 255 (8 bits). int, ocupan 2 bytes (16 bits), y por lo tanto almacenan número entre 2-15 y 215-1, es decir, entre -32,768 y 32,767. unsigned int, ocupa trambién 2 bytes, pero al no tener signo puede tomar valores entre 0 y 216-1, es decir entre 0 y 65,535. long, ocupa 32 bits (4 bytes), desde -2,147,483,648 a 2,147,483,647. unsigned long. oat, son números decimales que ocupan 32 bits (4 bytes). Pueden tomar valores entre -3.4028235E+38 y +3.4028235E+38. double, también almacena números decimales, pero disponen de 8-bytes (64 bit). Siempre que elegimos un tipo de dato debemos escoger el que menos tamaño ocupe y que a la misma vez, cubra nuestras necesidades, ya que ocuparán espacio en la memoria del microcontrolador y podría darse el caso de que nuestro programa requiera más memoria de la que tenemos. Un dato que por ejemplo solo tendrá el valor «0» y el valor «1» se podría guardar en una variable «int» pero también «bool». Si ya sabemos que este dato solo tendrá dos valores, ¿porqué guardarlo en una variable tipo «int» que ocupa 16 bits? Mejor lo guardamos el una variable tipo «bool» que solo ocupa 1 byte y puede guardar un «cero» o un «uno», representando un «falso» o un «verdadero» (false y true). Pero, ¿cómo “hacemos” variables en nuestro código? Es muy sencillo: indicando el tipo y el nombre de la variable. Además podemos darle o no un valor inicial. Veamos un ejemplo: Arduino 1 2 3 4 5 char miCaracter ='a'; //declaramos una variable tipo char, llamada miCarcater y la inicializ byte unNumero = 189; // variable tipo byte inicializada a 189 int miEntero; //variable tipo int sin inicializar unsigned int numeroPositivo = 2343; //entero positivo inicializada float numDecimal = 12.212; //numero decimal inicializado a 12,212 Hay otro tipo muy importante, String, sirve para almacenar cadenas de texto, y es fundamental a la hora de enviar texto por el puerto serie. Permite crear cadenas a partir de número, otras variables, o concatenando cadenas. Veamos algunos ejemplos (de esta página): Arduino 1 2 3 4 5 String String String String String stringOne stringOne stringTwo stringOne stringOne = "Hello String"; = String('a'); = String("This is a string"); = String(stringTwo + " with more"); = String(13); // // // // // usando la consta convertiendo un convertiendo un concatenando dos usando un entero Existe aún otro tipo importante, llamado array, que es una agrupación ordenada de datos de un tipo determinado. Vamos a ver todos estos uno por uno. Las Variables Los tipos de datos en C o Arduino se re eren a un sistema extenso utilizado para declarar variables o funciones de diferentes tipos. El tipo de una variable determina cuánto espacio ocupa en el almacenamiento y cómo se interpreta el patrón de bits almacenado. La siguiente tabla proporciona todos los tipos de datos que usará durante la programación de Arduino. Void long Bool Unsigned long char short Unsigned char oat byte double int array Unsigned int String-char word String-object Void La palabra clave «void» se usa solo en declaraciones de funciones. Indica que se espera que la función no devuelva información a la función desde la que se llamó. Ejemplo Arduino 1 Void Loop ( ) { 2 // el resto del código 3 } Boolean Un booleano tiene uno de dos valores, verdadero o falso. Cada variable booleana ocupa un byte (8 bits) de memoria aunque solo guarda un cero o un 1. Ejemplo Arduino 1 bool val = false ; // declaración de variable tipo booleano e inicializd 2 bool state = true ; // declaración de variable tipo booleano e inicializd Char Es un tipo de datos que ocupa un byte de memoria que almacena un valor de carácter. Los literales de caracteres se escriben entre comillas simples como en este ejemplo: ‘A’ y para varios caracteres, las «cadenas» usan comillas dobles: «ABC» pero esto ya sería un String. Sin embargo, los caracteres se almacenan en la memoria como números. Puedes ver la codi cación de cada carácter en código ASCII aquí en este grá co ASCII . Esto signi ca que es posible realizar operaciones aritméticas en caracteres (letras y símbolos), en las que se utiliza el valor ASCII del carácter. Por ejemplo, ‘A’ + 1 tiene el valor 66, ya que el valor ASCII de la letra mayúscula A es 65. Ejemplo Arduino 1 Char chr_a = ‘a’ ; //declaración de la variable tipo char con nombre chr_ 2 Char chr_c = 97 ; ///declaración de la variable tipo char con nombre chr unsigned char Unsigned char (char sin signo) es un tipo de dato sin signo que ocupa un byte de memoria. El tipo de datos de caracteres sin signo codi ca números del 0 al 255. Ejemplo Arduino 1 Unsigned Char chr_y = 121 ; // decalración de la variable Unsigned char e byte Un byte almacena un número sin signo de 8 bits así que podemos tender de 0 a 255. Ejemplo Arduino 1 byte m = 25 ; //Variable declarada tipo byte con valor inicial 25 2 byte x; //Variable declarada tipo byte sin valor inicial int Los enteros son el tipo de datos principal para el almacenamiento de números. int almacena un valor de 16 bits (2 bytes). Esto produce un rango de -32,768 a 32,767 (valor mínimo de -2 ^ 15 y un valor máximo de (2 ^ 15) – 1). El tamaño int varía de una tabla a otra. En Arduino Due, por ejemplo, un int almacena un valor de 32 bits (4 bytes). Esto produce un rango de -2,147,483,648 a 2,147,483,647 (valor mínimo de -2 ^ 31 y un valor máximo de (2 ^ 31) – 1). Ejemplo Arduino 1 int mi_contador = 32 ; // declaración de una variable tipo int con valor 2 int mi_numero ; // declaración de una variable tipo int sin valor unsigned int Los int sin signo (enteros sin signo) son lo mismo que int en la forma en que almacenan un valor de 2 bytes. Sin embargo, en lugar de almacenar números negativos, solo almacenan valores positivos, produciendo un rango útil de 0 a 65.535 (2 ^ 16) – 1). El Due almacena un valor de 4 bytes (32 bits), que varía de 0 a 4,294,967,295 (2 ^ 32 – 1). Ejemplo Arduino 1 Unsigned int el_contador = 60 ; // declaración de una variable tipo unsig 2 Unsigned int numero = 52000 ; // declaración de una variable tipo unsig Word En el Uno y las otras placas basadas en ATMEGA, un «word» almacena un número sin signo de 16 bits. En Due and Zero, almacena un número sin signo de 32 bits. Ejemplo Arduino 1 word w = 1000 ; //variable declarada tipo word con valor inicial 1000 Long Las variables «long» son variables de tamaño extendido para el almacenamiento de números y almacenan 32 bits (4 bytes), de -2,147,483,648 a 2,147,483,647. Ejemplo Arduino 1 Long velocity = 102346 ; //Variable declarada tipo long con valor inicial Unsigned long Las variables long sin signo son variables de tamaño extendido para el almacenamiento de números y almacenan 32 bits (4 bytes). A diferencia de los largos estándar, los largos sin signo no almacenarán números negativos, haciendo su rango de 0 a 4,294,967,295 (2 ^ 32 – 1). Ejemplo Arduino 1 Unsigned Long velocity = 101006 ;// variable tipo unsigned long con valor Short Un «short» es un tipo de datos de 16 bits. En todos los Arduinos (basados en ATMega y ARM), un short almacena un valor de 16 bits (2 bytes). Esto produce un rango de -32,768 a 32,767 (valor mínimo de -2 ^ 15 y un valor máximo de (2 ^ 15) – 1). Ejemplo Arduino 1 short val = 13 ;// oat El tipo de datos para el número de «coma otante». Es un número que tiene un punto decimal. Los números de punto otante a menudo se usan para aproximar los valores analógicos y continuos porque tienen una resolución mayor que los enteros. Los números de coma otante pueden ser tan grandes como 3.4028235E + 38 y tan bajos como -3.4028235E + 38. Se almacenan como 32 bits (4 bytes) de información. Ejemplo Arduino 1 float num = 1.352; //Declaración de una variable tipo float con valor ini double En el Uno y otras placas basadas en ATMEGA, el número de coma otante de doble precisión ocupa cuatro bytes. Es decir, la implementación doble es exactamente la misma que la otante, sin ganancia en precisión. En el Arduino Due, los dobles tienen una precisión de 8 bytes (64 bits). Ejemplo Arduino 1 double num = 45.352 ; // Los Array Podemos considerar «array» como un tipo de variable pero en realidad es una cadena o matriz de otras variables. Una «matriz» (array de inglés) es un grupo consecutivo de ubicaciones de memoria que son del mismo tipo. Para referirnos a una ubicación o elemento particular en la matriz, especi camos el nombre de la matriz y el número de posición del elemento particular en la matriz. La ilustración que se muestra a continuación muestra una matriz de entero (int) llamada C que contiene 11 elementos. Puedes hacer referencia a cualquiera de estos elementos dando el nombre de la matriz, en este caso «C» seguido por el número de posición del elemento que quieres entre corchetes ([]). El número de posición es llamado de una manera más formal subíndice o índice (este número especi ca el número de elementos desde el principio de la matriz). El primer elemento tiene subíndice «0» (cero) y a veces se le llama el elemento «ceros». Por lo tanto, los elementos de la matriz C son C [0] (pronunciado «C sub cero»), C [1], C [2] y así sucesivamente. El subíndice más alto en nuestra matriz C es 10, que es 1 menos que el número de elementos en la matriz (11). Tienes que entender que si tienes una matriz de 20 elementos por ejemplo, los indices irán de 0 a 19 NO de 1 a 20. Los nombres de matriz siguen las mismas convenciones que otros nombres de variables, sin espacios y sin usar acentos. Examinemos la matriz C en la gura dada, más de cerca. El nombre de toda la matriz es C. Sus 11 elementos se denominan C [0] a C [10]. El valor de C [0] es -45, el valor de C [1] es 6, el valor de C [2] es 0, el valor de C [7] es 62 y el valor de C [10] es 78). Arduino 1 int C[11] = {-45, 6, 0, 72, 1543, -89, 0, 62, -3, 1, 78}; //Así definiría Para imprimir la suma de los valores contenidos en los primeros tres elementos de la matriz C, escribiríamos algo así: Arduino 1 Serial.print (C[ 0 ] + C[ 1 ] + C[ 2 ] ); Para dividir el valor de C [6] entre 2 y asignar el resultado a la variable x, escribiríamos algo así: Arduino 1 x = C[ 6 ] / 2; Declarar matrices Las matrices ocupan espacio en la memoria. Para especi car el tipo de elementos y la cantidad de elementos requeridos por una matriz, utiliza una declaración de la forma: Arduino 1 type arrayName [ arraySize ] ; //tipo nombre_matriz [tamaño] El compilador reserva la cantidad adecuada de memoria para tu matriz. (Recuerda que una declaración, que reserva memoria, se conoce mejor como «de nición»). El arraySize debe ser una constante entera mayor que cero. Por ejemplo, para indicarle al compilador que reserve 11 elementos para la matriz de enteros C, usa la declaración: Arduino 1 int C[ 11 ]; // C es una array (cadena o matriz) de 11 elementos las matrices pueden contener valores de cualquier tipo de datos sin referencia. Por ejemplo, una matriz de tipo String puede almacenar Strings de caracteres (letras, símbolos, números). Ejemplos de uso de matrices Esta sección ofrece muchos ejemplos que demuestran cómo declarar, inicializar y manipular matrices. Ejemplo 1: Declarar una matriz y usar un bucle para inicializar los elementos de la matriz Declaramos una matriz de enteros de 10 elementos n . Las líneas 8 – 16 usan una instrucción For para inicializar los elementos de la matriz y llenar los espacios con ceros. Al igual que otras variables automáticas, las matrices automáticas no se inicializan implícitamente a cero así que las tenemos que rellenar nosotros con ceros si queremos. El primer for incrementa el valor de i cada bucle, así que en cada bucle rellenamos la posición»i» de la matriz «n» con un cero. Con el segundo for, imprimimos por pantalla cada elemento de la matriz por separado. Código del ejemplo Arduino 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 int n [10]; //n es un array de 10 enteros void setup() { Serial.begin(9600); } void loop() { for( int i = 0; i < 10; i++){ n[i] = 0; //Rellenamos cada elemento de n con un cero Serial.print(i); Serial.print("\r"); } for( int j = 0; j < 10; j++){ Serial.print(n[j]); //Imprimimos por pantalla elemento por element Serial.print("\r"); } } Resultado : Se producirá el siguiente resultado: Elemento Valor 0 0 1 0 2 0 3 0 4 0 5 0 6 0 7 0 8 0 9 0 Ejemplo 2: Inicializar una matriz en una declaración con una lista de inicializadores Los elementos de una matriz también se pueden inicializar en la declaración de la matriz siguiendo el nombre de la matriz con un signo igual a y una lista de inicializadores separados por comas delimitados por llaves. El programa utiliza una lista de inicializadores para inicializar una matriz entera con 10 valores (línea a) e imprime la matriz en formato tabular . Código del ejemplo Arduino 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 //n es un array de 10 enteros int n [10] = {32, 27, 64, 18, 95, 14, 90, 70, 60, 37}; void setup() { Serial.begin(9600); } void loop() { for( int i = 0; i < 10; i++){ Serial.print(i); Serial.print("\r"); } for( int j = 0; j < 10; j++){ Serial.print(n[j]); //Imprimimos por pantalla elemento por element Serial.print("\r"); } } Resultado : Se producirá el siguiente resultado: Elemento Valor 0 32 1 27 2 64 3 18 4 95 5 14 6 90 7 70 8 60 9 37 Ejemplo 3: Sumar los elementos de una matriz A menudo, los elementos de una matriz representan una serie de valores que se utilizarán en un cálculo. Por ejemplo, si los elementos de una matriz representan las cali caciones del examen, un profesor puede desear sumar los elementos de la matriz y usar esa suma para calcular el promedio de la clase para el examen. El programa suma los valores contenidos en la matriz de enteros de 10 elementos a . Código del ejemplo Arduino 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 const int arraySize = 10; //una variable constante que representa el tam int a[arraySize] = {87, 68, 94, 100, 83, 78, 85, 91, 76, 87}; int total = 0; void setup() { Serial.begin(9600); } void loop() { //sumamos el contenido de a for( int i = 0; i < arraySize ; i++){ total = total + a[i]; Serial.print("El total de los elementos de la array es: "); Serial.print(total ); } } Resultado : Se producirá el siguiente resultado: Arduino 1 El total de los elementos de la array es: 849