Ahora que tenemos nuestra placa correctamente instalada y conocemos el entorno de programación para nuestro Arduino, llega el momento de aprender a programar!!. He de decir que esta es la parte difícil y quizás aburrida para muchos, pero del conocimiento del lenguaje de programación va a depender que nuestros programas puedan hacer cosas increíbles.
Arduino, como muchos otros lenguajes de programación, tiene infinidad de funciones, operadores, variables.... si tuviera que enunciarlos y explicarlos todos en este capítulo sería larguísimo y no creo que nadie llegara hasta el final sin aburrirse, por ello lo que voy a hacer es una introducción al lenguaje para que conozcáis que podemos encontrarnos y de que recursos disponemos a la hora de programar. Iremos aprendiendo el uso de las funciones poco a poco usándolas en pequeñas aplicaciones.
Para aquellos que queráis avanzar algo mas rápido os recomiendo que uséis alguno de los muchos libros o manuales que hay para iniciarse en Arduino, muchos de los cuales son gratuitos. Yo he confeccionado un manual a partir de la información que se puede encontrar en la página oficial de Arduino, este manual explica todos los conceptos básicos y está muy bien para aprender, el manual lo podéis descargar de aquí.
Estructura
Al empezar a trabajar con Arduino, tenemos que tener muy claro la estructura de trabajo básica, esta estructura es muy simple y debe aparecer en TODOS los programas, se trata de dos funciones, la función "setup" y la funcion "loop".
void setup() //Funciópn SetUp (configuración) { pinMode(13, OUTPUT); } void loop() //Función Loop (se ejecutará cíclicamente) { digitalWrite(13, HIGH); delay(1000); digitalWrite(13, LOW); delay(1000); }
Arriba podemos ver estas dos funciones en un ejemplo que ya conocemos el "blink", como se aprecia, la función "Setup" declara el Pin 13 como salida, ya que es por este Pin por donde pretendemos sacar información, o en nuestro caso el estado del Led. La función "Setup" solo se invoca una vez al inicio del programa, y se usa para configurar los pines, configurar la comunicación serie o establecer un estado inicial o de partida para algún dispositivo.
La función "Loop" será la función donde se encuentre el grueso de nuestro programa, esta función se repetirá una y otra vez ejecutando lo que se encuentre en su interior, esta repetición es la que posibilita que el programa este actualizándose y respondiendo a los eventos que ocurran.
Las funciones "Loop" y "Setup" son necesarias en todos los programas que hagamos, pero no tienen por qué ser únicas, podemos crear tantas funciones como queramos para organizar el contenido de nuestro programa ó para hacer tareas repetitivas dentro de nuestro programa principal. Las funciones están acotadas por las llaves{}, estas llaves definirán el bloque de la función.
Instrucciones y operadores
Delimitadores: son elementos que acotan o detienen el alcance de una función o instrucción
{} Llaves: definen el principio y el final de un bloque de instrucciones o función, podemos encontrarlas en estructuras de control definiendo el bloque al cual afecta la función. Podemos anidar tantos bloques como queramos.
; Punto y coma: Se utiliza para separar instrucciones, es común olvidar colocarlo al final de línea. Si no lo ponemos no reconocerá el fin de la función y el programa dará un problema al compilar.
Comentarios: Es muy recomendable usar comentario desde el principio para hacer anotaciones sobre el funcionamiento del programa, esto nos va a ahorrar muchos problemas si nuestro programa se hace muy grande y va a permitir que otras personas entiendan como hemos hecho el programa.
/*….*/ Bloque de comentario: Son áreas de texto que pueden abarcar más de una línea, lo que escribamos entre esos símbolos será ignorado por el programa.
// Línea de Comentario: Funciona como el bloque de comentario, con la diferencia que solo será ignorado el texto que este a su derecha, al cambiar de línea perderá el efecto.
Operadores
Operadores: Los operadores son los elementos con los que vamos transformar variables, hacer comparaciones, contar un número determinado de eventos… en definitiva, los operadores se pueden considerar los elementos más importantes del programa junto con las estructuras de control. Dentro de los operadores, podemos encontrarlos de varios tipos
Aritméticos: Son operadores básicos como la suma, resta, multiplicación y división, también podríamos incluir aquí la operación de asignación “=”
/* OPERADORES ARITMÉTICOS */ x = x + 5; //suma x+5 y guarda el valor en x y = y - 8; //resta 8 a el valor "y" almacena el resultado en "y" z = z * 2; //multiplica z*2 y guarda el valor en z k = k / 3; //divide k entre 3 y guarda el valor en k p = 10; // asigna a p el valor 10
Asignaciones compuestas: Combinan una operación aritmética con una variable ya asignada. Se usan comúnmente en bucles.
/* OPERADORES DE ASIGNACIÓN COMPUESTA */ x ++; //equivale a x = x + 1 (incrementa x en 1) x --; //equivale a x = x - 1 (decrementa x en 1) x += y; //equivale a x = x + y x -= y; //equivale a x = x - y x *= y; //equivale a x = x * y x /= y; //equivale a x = x / y
De comparación: Este tipo de operadores se usan para comprobar variables o constantes con otras verificar así si una condición es verdadera o no. Suelen utilizarse en conjunto con estructuras de control.
/* OPERADORES DE COMPARACIÓN */ x == y; //x es igual a y x != y; //x es distinto de y x < y; //x es menor que y x > y; //x es mayor que y x <= y; //x es menor o igual que y x >=y; // x es mayor o igual que y
Booleanos: Son operadores lógicos que se usan para comparar 2 o más expresiones y que no devuelven un valor, sino que dan un estado de “verdadero” (si se cumple la expresión) o “falso” (si no se cumple).
/* OPERADORES BOLEANOS */ if (x<3 && x>0) //Cierto si se cumplen las dos expresiones if (x<7 || x=20) //Cierto si se cumple alguna de las dos expresiones if (!x=3) //Cierto si x es distinto de 3
Estructuras de control
Estructuras de control: En las estructuras de control se engloban todos los estamentos que sirven para guiar al programa en una u en otra dirección en función de si se cumplen las condiciones que le marquemos. Dentro de estas estructuras podemos encontrar condicionales, bucles o elementos de salto.
Condicionales: Los condicionales chequean un estado o condición y si esta condición se cumple se pasa a ejecutar las sentencias englobadas dentro de la condición.
/* CONDICIONALES */ if (x==10) //Si x es igual a 10 ejecuta la instrucción { ejecuta instrucciones } if (y != 10) // Si y es distinto de 10 ejecuta la instrucción { ejecuta instrucciones } else //si no, ejecuta esta instrucción { ejecuta instrucciones }
Bucles: Los bucles son unos estamentos los cuales harán que el programa entre en un ciclo de repetición mientras se cumplan las condiciones del bucle.
/* BUCLES */ /*Entra en el bucle "for" y se repetirá mientras se cumpla la condición*/ for(int x=0; x<20; x++) //asigna a x el valor 0; condición ; incrementa x en 1 { ejecuta instrucciones } /* El bucle while se ejecutará siempre que se cumpla la condición*/ while (x!=0) { ejecuta instrucciones } /* El bucle "do...while" se ejecuta almenos 1 vez, luego dependerá de si se cumple la condición */ do { instrucciones }while (x!=0);
Sentencias especiales
Sentencias especiales: Estas sentencias se usan en programas avanzados y normalmente se utilizan cuando trabajamos con varias funciones. Si estás empezando a programar con Arduino no tengas demasiado en cuenta estas instrucciones.
Break: Esta es una sentencia que debemos evitar a la hora de programar, tan solo se usará cuando sea totalmente inevitable. Lo que hace la sentencia es "romper" la iteración del bucle saliéndose del mismo sin tener en cuenta que se cumplan las condiciones marcadas para salir.
Goto: Esta sentencia marcará un lugar del código al cual realizaremos un salto. La posición desde la que saltemos quedará almacenada en la pila del programa para que podamos regresar. Esta sentencia se usa para hacer saltos a funciones que puedan hacer tareas repetitivas o que tengamos que chequear constantemente y una vez ejecutada continuar con el programa normalmente.
Return: Es la sentencia que se utiliza para volver de un salto (goto)
Funciones basicas
Funciones Básicas: Para los que tengáis nociones de programación las instrucciones vistas hasta ahora os sonarán, ya que son comunes a varios lenguajes de programación como por ejemplo #C, pero no debemos de olvidar que lo que estamos programando es un dispositivo físico dotado con pines de entrada/salida que comunican nuestra placa con diversos elementos, por ello existen instrucciones adicionales a las que podemos encontrar en otros lenguajes de programación similares y que en Arduino son BASICAS, ya que en prácticamente la totalidad de las aplicaciones que creemos tendremos que leer el estado de pulsadores, sensores, niveles de tensión.... y normalmente tendremos que actuar sobre relés, leds, motores...
Pin mode: Esta instrucción se usa para configurar los pines de nuestro Arduino como entrada o como salida. Se declarará dentro de la función "SetUp", por lo que la configuración de pines solo se hará una vez antes de empezar a ejecutar el programa principal. Los pines de Arduino están configurados como entrada por defecto, por lo que no es necesario definirlos en caso de usarlos como entrada
/* PIN MODE */ pinMode (13,OUTPUT); //establece el pin 13 como salida int led=10; pinMode led,OUTPUT); //establece "led" (que esta asociado al 10) como salida
Entradas/Salidas digitales: Las entradas y salidas digitales solo trabajaran con dos estados "ALTO" o "BAJO" que irá asociados a un nivel de 5 voltios(alto) ó 0 voltios (bajo) (también podemos encontrarnos con Arduinos que trabajan a 3.3v).
/* ENTRADAS/SALIDAS DIGITALES */ //digitaRead (pin) entrada = digitalRead(10); //hace que la variable "entrada" sea igual al estado del pin 10 //digitalWrite (pin, valor) digitalWrite (10, HIGH); //establede el pin 10 como HIGH (saca 5 voltios)
Entradas/Salidas analógicas: Estos pines a diferencia de los pines digitales pueden tomar cualquier valor entre 0 y 5 voltios. A la hora de leer un valor tendremos una resolución de 10bit's o lo que es lo mismo, el valor que podemos leer tendrá un rango entre 0 y 1023. Para escribir un valor analógico lo haremos usando el PWM (modulación por ancho de impulso), para esto la resolución será de 8 bit's teniendo un rango de 0 a 255.
/* ENTRADAS/SALIDAS ANALÓGICAS */ //analogRead (pin) entrada = analogRead (1); //hace que la variable "entrada" sea igual al valor del pin 1 //alnalogWrite (pin,valor) analogWrite (12, 128); //saca por el pin 12 el valor de tensión correspondiente a 128 (mas o menos 2,5 voltios)
Instrucciones de tiempo: Son instrucciones que nos sirven para hacer temporizaciones o para comprobar el tiempo transcurrido desde el inicio del programa.
/* FUNCIONES DE TIEMPO */ //delay (ms) delay (1000); //espera 1000 milisegundos antes de ejecutar la siguiente instrucción //millis() tiempo = millis(); //asigna a la variable "tiempo" el tiempo trasncurrido desde el inicio del programa.
Funciones de matemáticas: son funciones que nos ayudaran con el desarrollo de algunos de nuestros programas, hay que decir que existe una librería llamada "math.h" la cual añade nos da la posibilidad de añadir operaciones como elevar al cuadrado, hacer senos, cosenos, arcotangente... esto lo veremos con posterioridad, de momento solo nombraré las funciones básicas de matemáticas.
/* FUNCIONES MATEMÁTICAS */ //min (x,y) minimo = min(valor, 100); //asigna el valor mas pequeño (entre "valor" y 100) a la variable minimo //max (x,y) maximo = max(valor, 100); //asigna el valor mas grande (entre "valor" y 100) a la variable maximo //ramdomSeed(seed) randomSeed(valor); // hace que la variable valor tome un valor aleatorio
Funciones Serial : Las placas de Arduino tienen al menos 1 puerto serial para la comunicación con el ordenador o con otros dispositivos, esta comunicación se llevará a cabo mediante los pines TX y RX (podemos tener varios en nuestra placa según el modelo).
/* FUNCIONES SERIAL */ //Serial.begin(rate) Serial.begin(9600); //abre el puerto seríe y establece la velocidad de comunicación en 9600bps (esta funcion debe de ponerse en el SetUp) //Serial.println(data) Serial.println(digitalRead(12); //manda por el puerto serial el valor que tenga el pin 12 //Serial.read() Valor_leido = Serial.read(); //asigna a "Valor_leido" el valor que lea del puerto serial.
Existen más instrucciones en Arduino, además de todas las que pueden ser añadidas poniendo bibliotecas adicionales, pero creo que con todas las mencionadas anteriormente, tenemos más que suficiente para empezar a hacer nuestros proyectos, y no os preocupéis si ahora os suenan a chino, porque iré utilizándolas todas ellas en pequeños ejemplos donde veréis claramente cómo funcionan y empezareis a ver por vosotros mismo nuevas formas de combinarlas para conseguir hacer vuestros propios proyectos.
Comentarios potenciados por CComment