Entendiendo mi primer Sketch

La programación ha sido una profesión para pocos, y un misterio para muchos. Muchas personas consideran que programar es muy complicado o que no podrán aprender a hacerlo. Este curso se propone enseñar a programar Arduinos de una manera inclusiva, considerando que quien aprende no sabe nada de nada.

El método que usaremos es mezclar todo, es decir, enseñar electrónica, con un Sketch, explicarlo y desde ahi enseñar más y más conceptos de programación. De esta manera evitaremos el aburrimiento por concentrarnos demasiado en programación o demasiado en electrónica sin ver el resultado aplicado de lo que aprendemos. Por el contrario, cada etapa presentará un poco de todo.

Nuestro primer Sketch

De la página anterior copiamos el Sketch que les compartimos que es el que usaremos para explicar los primeros conceptos de programación.

/*
 * Código de ejemplo. Led que parpadea
 * Curso de Arduino - ArduinoHobby.com
 */
 
void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
}

void loop() {
  digitalWrite(LED_BUILTIN, HIGH);
  delay(1000);
  digitalWrite(LED_BUILTIN, LOW);
  delay(1000);
}

Un poco de conocimiento base

El lenguaje de programación que usamos es C/C++. Es una combinación de C y C++ ya que C es compatible con C++ que significa que el código C funciona en C++ también (no al reves). Arduino usa una versión modificada del lenguaje pero las bases son las mismas. Que use una versión modificada significa que algunas funcionalidades (en especial de C++) pueden no estar disponibles en Arduino.

El lenguaje C es uno de los lenguajes más potentes que jamás haya existido, y uno de los preferidos para programar los elementos más importantes de nuestra vida tecnológica, incluyendo por ejemplo nuestros celulares! Es potente y a la vez simple de comprender en su escencia aunque usado en su máxima potencia, los programas pueden tornarse muy complejos.

No entiendo nada!!

No se preocupe, todo tendrá sentido en breve. Lo primero que veremos son comentarios. Los comentarios son texto en un programa que no cumple ninguna función en nuestro Arduino. Su función es informar, es decir, decirle al que está viendo el código del programa algo preferentemente importante o relacionado con el programa, aunque es de libre uso y usted puede decir lo que quiera.

Los comentarios son ignorados por el compilador (ya veremos que es un compilador). Usualmente usted usará comentarios grandes al principio del programa para explicar algo referido a todo el programa. Por ejemplo quien lo escribió, cuando, que hace el programa y cualquier otro dato complementario. También usará comentarios en partes específicas del programa para ayudar a la comprensión de esa parte específica.

Existen 2 maneras de agregar comentarios en C/C++:

Comentarios de una sola línea

Por ejemplo:

// Este es un comentarios de una sola linea

La forma de usarlos es con doble barra: // delante del comentario. Lo que sigue a las barras es considerado un comentario y será ignorado en el programa. El comentario es considerado hasta que usted presiona Enter, es decir, hasta la siguiente línea. Si usted divide el comentario en dos líneas como se muestra asi:

// Este es un comentario muy largo y 
la segunda linea dara error.

La segunda línea no se considerará parte del comentario y le dará un error al momento de compilar (luego veremos la acción de compilar). Si desea usar este método de agregar comentarios para un comentarios de 2 líneas, lo correcto sería:

// Este es un comentario muy largo y
// la segunda linea NO dara error.

También es válido agregar un comentario a la derecha de una instrucción, como en el siguiente ejemplo:

  pinMode(LED_BUILTIN, OUTPUT); // Configura el modo del pin 13 como salida

Sugerencia: Al finalizar ésta sección, puede probar agregar comentarios de una línea en todas las líneas importantes del programa para aclarar lo que hacen, basado en lo que aprendió hoy!

Comentario de múltiples líneas

Los comentarios de múltiples líneas son usados para textos largos. Por ejemplo cuando usted quiere explicar que hace el programa y mucha información que sería difícil de organizar usando comentarios de una línea (debería usar // con cada línea lo que sería impráctico). Los comentarios de múltiples líneas comienzan con /* (barra y asterisco) y finalizan con */ (asterisco y barra). Todo lo que se encuentre entre estos dos símbolos será considerado comentario e ignorado por el compilador.

Lo interesante de este tipo de comentarios es que cuando usted inicia un comentario de múltiples líneas con /* en su Arduino IDE, el mismo le facilita la operación creando el cierre y dándole un formato en donde cada línea entre los comentarios comienza con un * (asterisco). De ésta manera, el comentario quedará más amistoso. Por ejemplo el comentario de nuestro código:

/*
 * Código de ejemplo. Led que parpadea
 * Curso de Arduino - ArduinoHobby.com
 */

pero el mismo también podría escribirse así:

/*
Código de ejemplo. Led que parpadea
Curso de Arduino - ArduinoHobby.com
 */

ya que los asteriscos no son obligatorios en las líneas intermedias.

Observación: Como los procesadores y compiladores no comprenden mucho de letras especiales y acentos, es recomendable que los evite cuando agregue comentarios. De no hacerlo, es posible que algunos caracteres especiales no se muestren luego de la misma manera que usted los agregó.

Sugerencia: Modifique el comentario al principio del primer Sketch de manera de que explique que el mismo ahora es el trabajo suyo aprendiendo los primeros elementos del lenguaje C/C++ para programar Arduinos! Si quiere, verifique que luego de cambiar el comentario, si sube el Sketch a su Arduino el resultado es el mismo, ya que los comentarios son ignorados sin importar su contenido!

Sintaxis del lenguaje C/C++

La sintaxis del lenguaje C/C++ es bastante restrictiva. Significa que tiene muchas restricciones o condiciones que debe cumplir al escribir un programa. Veamos algunas reglas básicas:

Las líneas de instrucciones deben terminar con punto y coma

Todas las líneas de instrucciones deben terminar con punto y coma. Esto es simple de comprender si vemos una línea de nuestro Sketch como:

  pinMode(LED_BUILTIN, OUTPUT);

El punto y coma ( ; ) le dice al programa donde finaliza una instrucción o una orden si prefiere, y lo que sigue luego de ese punto y coma es una instrucción nueva que debe hacer algo diferente (o al menos separado) de la anterior. Hay excepciones a esta regla lamentablemente, o como me gusta verlo a mí, complementos a la misma.

Veremos varias excepciones a ésta regla a lo largo del curso, pero de momento podemos usar de ejemplo la siguiente parte del código:

void setup() {

La misma no es un comentario y no finaliza con un punto y coma. Veamos por qué en la siguiente sección.

Estructura de un programa Arduino

Antes de explicar lo anterior, quiero compartir un concepto básico de la estructura de los programas en C (en parte heredado por C++) y que hace a la esencia de los programas de Arduino.

Los programas en C (y esto es cierto en Arduino) se ejecutan (en general) una línea a la vez, de arriba hacia abajo, y de izquierda a derecha. La razón de la aclaración es que también es posible escribir más de una instrucción en una misma línea (aunque no será simple de leer) ya que como dijimos, el compilador comprende que una instrucción finaliza cuando encuentra un punto y coma.

Por ejemplo, y sin entrar en detalles sobre qué hacen cada una de las líneas, podemos usar la siguiente parte de nuestro Sketch de ejemplo:

  digitalWrite(LED_BUILTIN, HIGH); // Esta linea se ejecuta primero
  delay(1000);                     // Esta se ejecuta segundo
  digitalWrite(LED_BUILTIN, LOW);  // Esta se ejecuta tercero
  delay(1000);                     // Y esta se ejecuta ultimo

Funciones especiales de Arduino

Las funciones en C/C++ son todo un tema en especial que veremos más adelante. De momento solo nos concentraremos en las funciones especiales de Arduino que son las que nos aparecen ya escritas en un Sketch nuevo cuando comenzamos un proyecto de cero. Ejemplo:

void setup() {
  // put your setup code here, to run once:

}

void loop() {
  // put your main code here, to run repeatedly:

}

Como vimos antes, la línea que menciona a “setup()” no respeta la regla de que cada instrucción debe finalizar con un punto y coma, o si?

Resulta que las funciones no son consideradas instrucciones sino más bien un grupo de instrucciones que se ejecutarán en grupo, siguiendo las reglas básicas. Veamos rápido las dos funciones especiales de Arduino.

La función especial setup() de Arduino

Cuando Arduino comienza la ejecución de su programa ejecuta todo lo que pongamos dentro de esta función al principio de todo, es decir, es lo primero que Arduino hará o ejecutará cuando comience su trabajo. Esto es válido no solo para cuando recién suba su Sketch, pero también para cuando presiones el botón de reset de la placa Arduino (ver las partes del Arduino UNO). También cuando enciendas la placa Arduino nuevamente (ya que el programa instalado quedará en ella y se ejecutará cada vez que la alimentemos).

La función especial setup() de Arduino es obligatoria en todo Sketch, y debe comenzar con ” void setup() { ” y finalizar con ” } “. Todo lo que agreguemos dentro de las llaves se ejecutará una sola vez, al inicio de la ejecución de nuestro Arduino, y de acuerdo con las reglas del lenguaje como ya explicamos.

Observación: Si bien la función setup() es obligatoria en todo Sketch, no es obligatorio agregarle ninguna instrucción dentro. Es perfectamente aceptable y válido dejar a la función vacía, es decir, sin instrucciones dentro, tal y como el Arduino IDE nos la presenta al inicio de un nuevo Sketch.

La función especial loop() de Arduino

Luego de ejecutar todo lo que se encuentre en setup(), Arduino ejecutará todo lo que hay dentro de la otra función especial de Arduino, loop(). El código dentro de esta función especial se ejecutará una y otra vez, todo el tiempo sin parar y sin pausas. Dentro de esta función especial es donde pondremos nuestro código que queremos que Arduino repita todo el tiempo.

La función especial loop() de Arduino es también obligatoria en todo Sketch, y debe comenzar con ” void loop() { ” y finalizar con ” } “. Aunque parezca algo complejo, lo bueno es que Arduino IDE, cuando usted comienza un proyecto nuevo, ya le escribe automáticamente estas funciones pero vacías, listas para que usted las llene con su código.

Observación: Al igual que con la función especial setup(), si bien la función loop() es obligatoria en todo Sketch, no es obligatorio agregarle ninguna instrucción dentro. Es perfectamente aceptable y válido dejar a la función vacía, es decir, sin instrucciones dentro, tal y como el Arduino IDE nos la presenta al inicio de un nuevo Sketch.

Veamos lo que falta del Sketch

Código dentro de setup()

Como dijimos, el código dentro de setup() es el que se ejecutará una sola vez, al principio de la ejecución del programa. Veamos la única línea que tenemos y que es lo que hace:

  pinMode(LED_BUILTIN, OUTPUT);

La función pinMode() (modo del pin en Inglés) le avisa a nuestra placa Arduino sobre cómo usaremos un pin específico de la misma. Antes de ver el concepto de constante, déjeme decirle que la instrucción anterior es equivalente (en Arduino UNO) a la siguiente:

  pinMode(13, OUTPUT);

Ahora basados en lo explicado antes, la instrucción le dice a nuestro Arduino que usaremos el pin 13 como OUTPUT (que en Inglés significa SALIDA) y es lo que necesitamos para poder activar estados en nuestros pines. El pin 13 es un pin denominado “digital” y los pines digitales pueden tomar solo 2 estados: HIGH (alto) y LOW (bajo). Luego veremos más al respecto, pero lo interesante de nuestro pin 13 (diferente a los demás pines de la placa) es que tenemos un led conectado a dicho pin e integrado en la placa misma. Podrá verlo en nuestro reconocimiento de las partes de la placa, pero usualmente en la placa está etiquetado con la letra L (mayúscula).

Con lo anterior en mente, significa que cuando el pin 13 esté en estado HIGH, el led se encenderá, y cuando esté en estado LOW, se apagará. Esto es especialmente útil para un primer Sketch que muestra cómo controlar un led con Arduino (eso hace nuestro Sketch). Antes de ver más sobre la función pinMode(), retomemos la diferencia entre usar el número 13 y la palabra LED_BUILTIN.

Resulta que LED_BUILTIN (led construido dentro o integrado en Inglés) es lo que se denomina una constante, y está predefinida por nuestro entorno de programación para facilitarnos el trabajo. Para un Arduino UNO (y la mayoría de las placas Arduino), la constante LED_BUILTIN es igual al número 13, así de simple. Sin embargo, es mucho más simple de comprender que la misma apunta al pin que está conectado al led interno de Arduino, que recordar que 13 es el pin del que hablamos.

Ahora volviendo a la función pinMode(), la misma cumple, como dijimos, el objetivo de indicarle a Arduino cómo usaremos un pin específico. Por ejemplo si lo usaremos como salida (nuestro caso) o como entrada (lo veremos más adelante). OUTPUT es también una constante que Arduino nos provee para facilitarnos el trabajo y es la que usaremos siempre en caso de pines configurados como salidas digitales.

Dentro de los paréntesis, la función pinMode() requiere 2 datos (los llamaremos parámetros desde ahora). El primero es el pin a configurar, y el segundo el modo.

Vemos ahora el código dentro de loop()

Dentro de la función especial loop() de Arduino, tenemos 4 líneas, 2 de las cuales son iguales, y 2 similares. Veamos la primera línea:

  digitalWrite(LED_BUILTIN, HIGH);

La función digitalWrite() (escribir digital en Inglés) le indica a nuestro Arduino que queremos escribir (write en Inglés) o enviar como salida un nuevo estado para un pin determinado. Ya vimos antes que LED_BUILTIN refiere al pin 13 y HIGH es el estado alto. Cambiando el estado de nuestro pin 13 a HIGH (alto) estaremos encendiendo nuestro led integrado.

La función digitalWrite(), al igual que la función pinMode(), también requiere 2 parámetros dentro de los paréntesis. El primero es el pin, y el segundo el estado.

Veamos la siguiente línea:

  delay(1000);

La función delay() (demorar en Inglés) le dice a nuestro Arduino que no haga nada durante un tiempo. Concretamente el microprocesador no estará inactivo, pero a los efectos prácticos digamos que durante un tiempo no ejecutará ninguna instrucción. El tiempo que Arduino esperará, será indicado en el único parámetro que indicaremos entre los paréntesis. El mismo va indicado en milisegundos (hay 1000 milisegundos en un segundo), y en nuestro caso es 1000, lo que equivale a 1 segundo.

Veamos la tercera línea:

  digitalWrite(LED_BUILTIN, LOW);  // Esta se ejecuta tercero

Similar a la primera, usa la función digitalWrite() para cambiar el estado del pin 13 a LOW, lo que ya sabemos resultará en nuestro led integrado en nuestra placa Arduino apagado.

Y finalmente la cuarta línea es igual a la segunda provocando otra demora de 1 segundo.

Resumiendo

En definitiva, lo que el Sketch hace es configurar el pin 13 (led integrado en placa Arduino) en modo OUTPUT (salida) al principio del programa i ejecutado una sola vez al comienzo. Luego de ello, Arduino encenderá el led y lo mantendrá encendido por 1 segundo y luego lo apagará manteniéndolo apagado por 1 segundo también, repitiendo la operación continuamente.

¿Qué sigue?

¿Qué tal si comenzamos a conocer las capacidades de nuestro Arduino? En la siguiente entrega comenzaremos conociendo las salidas digitales. Les dejo el enlace: http://www.arduinohobby.com/salidas-digitales-con-arduino/

Deja un comentario