Archivo de la etiqueta: Constantes

Estructuras Propias de Arduino

Lo visto hasta ahora son estructuras y sintaxis de programación que es casi genérica a C++, pero el core de Arduino incluye algunas funciones propias para el uso de Arduino como la lectura de entradas analógicas y digitales y la escritura de salidas analógicas y digitales.

Para saber más de C y de la API de Arduino:

Veamos estas estructuras más específicas que están documentadas en el reference de Arduino https://www.arduino.cc/en/Reference/HomePage

Cómo Leer el Reference Arduino

En el reference de Arduino tenemos toda la información necesaria para entender cómo funciona el lenguaje o core de programación de Arduino. Está todo perfectamente documentado de cómo funciona cada estructura y cómo se comportan las funciones,

Reference: https://www.arduino.cc/en/Reference/HomePage 

Cuando entramos en el reference y vemos un nuevo método o función deberemos leer:

  • Description: Hace una descripción de lo que hace ese método y función
  • Syntax: Sintaxis de la función con todas las formas de llamarlo y los parámetros a pasar. Puede haber varias formas de llamar a una función, por ejemplo https://www.arduino.cc/en/Reference/EthernetBegin
  • Parameters: Descripción de los parámetros a pasar a esa función. Puede que no haya que pasar ninguno: https://www.arduino.cc/en/Reference/Millis
  • Returns: que valor me devuelve y qué tipo de dato es. Puede que no devuelva nada como https://www.arduino.cc/en/Reference/PinMode
  • Note: Nota sobre el uso de la función
  • Example: Un ejemplo de cómo usar la función
  • See Also: Otras funciones relacionadas

Entradas y Salidas Digitales

En arduino para tratar las entradas y salidas digitales usamos las siguientes funciones:

En la imagen siguiente se muestra el estado por defecto de una I/O digital en un microcontrolador de Arduino. Se ha simplificado con interruptores la compleja electrónica que hay dentro. Por defecto los digital I/O pins están configurados como inputs en un estado de alta impedancia (equivalente a una resistencia de 100 Mohms en frente del pin), es decir, SW3 a ON y no hace falta llamar a la función pinMode() aunque es recomendable para aclarar el código.

  • PinMode(x, INPUT) –> SW3 = ON (resto a OFF). Los valores leídos serán aleatorios si el pin de Arduino está al aire. El pin está en un estado de alta impedancia (resistencia de 100 Mohms).
  • PinMode(x,INPUT_PULLUP) –> SW3 = ON & SW4 = ON (resto a OFF). Los valores leídos sin nada conectado al pin es HIGH. La Resistencia R1 tiene un valor dependiendo del microcontrolador, pero tiene un valor entre 20kOhm y 150kOhm.
  • PinMode(x, OUTPUT) & digitalWrite(x,HIGH) –> SW2 = ON & SW1 = +5V (resto a OFF). Estado de baja impedancia, no hay resistencia interna y es necesario poner una resistencia adecuada a la salida el pin para no superar los 40mA (source) máximos admitidos
  • PinMode(x, OUTPUT) & digitalWrite(x,LOW) –> SW2 = ON & SW1 = GND (resto a OFF). Estado de baja impedancia, no hay resistencia interna y es necesario poner una adecuada para no superar los 40mA (sink) máximos admitidos

Entradas y Salidas Analógicas

En Arduino para tratar las entradas y salidas analógicas usamos las siguientes funciones:

Otras funciones interesantes con entradas/salidas analóicas:

La mayoría de Arduino no tienen salidas analógicas puras sino PWM. Algunos pines digitales pueden usarse como salidas analógicas PWM:

Las Salidas PWM (Pulse Width Modulation) permiten generar salidas analógicas desde pines digitales. Arduino Uno no posee salidas analógicas puras, sin embargo el Arduino Due sí tiene salidas analógicas puras mediante dos DAC. El arduino due, posee dos salidas analógicas puras mediante dos conversores digital a analógico. Estos pines pueden usarse para crear salidas de audio usando la librería correspondiente.

La modulación por ancho de pulsos (también conocida como PWM, siglas en inglés de pulse-width modulation) de una señal o fuente de energía es una técnica en la que se modifica el ciclo de trabajo de una señal periódica (una senoidal o una cuadrada, por ejemplo), ya sea para transmitir información a través de un canal de comunicaciones o para controlar la cantidad de energía que se envía a una carga.

El ciclo de trabajo de una señal periódica es el ancho relativo de su parte positiva en relación con el período. duty cycle = (tiempo que la salida está a uno o HIGH)/ (periodo de la función)

Diferentes valores de una señal PWM:

Entradas y Salida Avanzadas

Advanced I/O:

  • tone() – Genera una onda cuadrada (ciclo y 50% de servicio) de la frecuencia especificada en un pin. Una duración se puede especificar, de lo contrario la onda continúa hasta una llamada a noTone (). El pin puede ser conectado a un zumbador piezo u otro altavoz para reproducir tonos.
  • noTone() – Detiene la generación de una onda cuadrada provocada por tone(). No tiene ningún efecto si no se está generando el tono.
  • shiftOut() – Desplaza un byte de datos de un bit cada vez. Comienza a partir del más o menos significativo. Cada bit es escrito en un pin cada vez que se produce un pulso de reloj.
  • shiftIn() – Desplaza un byte de datos de un bit cada vez. Comienza a partir dell más o menos significativo. Para cada bit, el reloj es puesto a HIGH, el siguiente bit es leído de la línea de datos y entonces el reloj es puesto a LOW.
  • pulseIn() – Lee un pulso de un pin. Si el valor es HIGH, la función espera a que el pin se ponga a HIGH, comienza a temporizar y espera hasta que el pin vuelve a LOW, devolviendo la longitud del pulso en microsegundos.

Ejemplo de uso: https://www.arduino.cc/en/Tutorial/ShiftOut 

Bits y Bytes

Bits and Bytes

  • lowByte(): extrae el byte más a la derecha (low-order o menos significativo de una variable.
  • highByte(): extrae el byte más a la izquierda (high-order o más significativo de una variable.
  • bitRead(): lee el bit de una variable numérica. 
  • bitWrite(): escribe el bit de una variable numérica
  • bitSet(): pone a 1 un bit de una variable numérica 
  • bitClear(): pone a 0 un bit de una variable numérica 
  • bit(): Calcula el valor del bit especificado (el bit 0 es 1, el bit 1 es 2, el bit 2 es 4, etc.)

Constantes

Constants;

  • HIGH | LOW – Al leer o escribir en un pin solo hay estas dos posibilidades. Su significado es diferente si el pin está configurado como INPUT o OUTPUT.
  • INPUT | OUTPUT | INPUT_PULLUP – Modo en el que pueden configurarse los pines digitales.
  • LED_BUILTIN – La mayoría de las placas Arduino tienen un pin conectado a un led en la placa y esta constante devuelve el número de pin en función de la placa.
  • true | false – Representación de las constantes booleanes en arduino
  • integer constants – son los números usados directamente en un sketch como ‘123’. Por defecto estos números son tratados como enteros pero puede cambiarse con los modificadores U y L. Las constante enteras se tratan como base 10 (decimal) pero puede usarse otra notación.
  • floating point constants – al igual que las constantes enteras, las constantes de coma flotante permite definir los número decimales. Son posibles varias notaciones para expresar constantes de coma flotante, por ejemplo: n = .005. También pueden expresarse en notación científica como 2.34E5.

Utilidades

Utilities:

  • sizeof() – devuelve el número de bytes en una variable o el número de bytes ocupados por un array.
  • PROGMEM – se usa para guardar en la memoria flash en lugar de en la SRAM. Al usarlo le dice al compilador que ponga la información de la variable en la memoria flash en lugar de la SRAM, donde iría normalmente.

PROGMEM es parte de la librería pgmspace.h http://www.nongnu.org/avr-libc/user-manual/group__avr__pgmspace.html que solo está disponible para la arquitectura AVR, así que para usarlo hay que inclirla al principio del sketch con #include <avr/pgmspace.h>

La macro F() se puede usar para facilitar el manejo de PROGMEM en las instrucciones print, de forma que todo el texto a imprimir (ya sea en Serial, Ethernet u otra librería) se lea de la Flash y no ocupando tamaño en la SRAM. Esta macro está incluida en el core de Arduino.

Operadores Bit a Bit

Bitwise Operators:

  • & (bitwise and)
  • | (bitwise or)
  • ^ (bitwise xor)
  • ~ (bitwise not)
  • << (bitshift left)
  • >> (bitshift right)

Operadores Compuestos

Compound Operators

  • ++ (increment)
  • (decrement)
  • += (compound addition)
  • -= (compound subtraction)
  • *= (compound multiplication)
  • /= (compound division)
  • %= (compound modulo)
  • &= (compound bitwise and)
  • |= (compound bitwise or)

Ambito de las Variables y Calificadores

Variable Scope & Qualifiers

  • variable scope – ámbito de la variable
  • static – hace que el valor de una variable local persista más alla de la función haciendo que su valor se mantenga entre llamadas a funciones
  • volatile – Declarar una variable volátil es una directiva para el compilador. Específicamente, dice al compilador que cargue la variable desde la RAM y no desde un registro de almacenamiento, que es una ubicación de memoria temporal donde se almacenan y manipulan las variables del programa. Bajo ciertas condiciones, el valor de una variable almacenada en registros puede ser inexacto.
  • const – es un cualificador de variable que modifica el comportamiento de la variable haciendo que sea de solo lectura.

Se deben declarar como “volatile” cualquier variable que sea modificada dentro de la función llamada por una interrupción.

Funciones de Tiempo

Funciones para trabajar con el tiempo

  • delay() – Para el programa en unidades de ms
  • delayMicroseconds() – Para el programa en unidades de us
  • micros() – Microsegundos transcurridos desde el inicio o reset de la placa
  • millis() – Milisegundos transcurridos desde el inicio o reset de la placa

Funciones USB

Keyboard – Las funciones del teclado permiten que las tarjetas micro basadas en 32u4 o SAMD envíen las pulsaciones de teclas a un ordenador conectado a través del puerto USB nativo de su micro.

Mouse – Las funciones del ratón permiten a las tarjetas micro basadas en 32u4 o SAMD controlar el movimiento del cursor en un ordenador conectado a través del puerto USB nativo de su micro. Cuando se actualiza la posición del cursor, siempre es relativa a la posición anterior del cursor.

Funciones Matemáticas

La librería math.h ya está incluida por defecto en Arduino. 

Librería math C++: http://www.cplusplus.com/reference/cmath/

Librería math.h de AVR libc:

Algunas de la funciones matemáticas del Reference de Arduino:

Números Pseudoaleatorios

random() – generador de números pseudoaleatorios

randomSeed() – Inicializa el generador de números

Comunicación Serie

Librería Stream de la que heredan las librerías de comunicación serie: https://www.arduino.cc/reference/en/language/functions/communication/stream/

Comunicación serie: https://www.arduino.cc/reference/en/language/functions/communication/serial/

Funciones:

Variables en Arduino

¿Que es una variable? Una variable es un lugar donde almacenar un dato, tiene un nombre, un valor y un tipo.

Los nombres de variables pueden tener letras, números y el símbolo ’_’. Deben empezar por una letra (pueden empezar por ’_ ’ pero no es recomendable pues es el criterio que usan las rutinas de la biblioteca).

Pueden llevar mayúsculas y minúsculas. En C se distingue entre mayúsculas y minúsculas. La costumbre es que las variables van en minúscula y las constantes en mayúscula

Usa las mismas reglas dentro del código para el nombramiento de variables, ya sea en minúscula con palabras separadas con guiones bajos, tantos como sea necesario para mejorar la legibilidad o utilizar la convención “CapWords” (palabras que comienzan con mayúsculas), aunque generalmente la primera palabra se pone en minúsculas.

Usa un solo guión bajo como prefijo para métodos no públicos y variables de instancia.

Las palabras reservadas if, else,etc . . . no pueden usarse como nombres de variables.

Nombres para evitar: Nunca uses los caracteres ‘l’ (letra ele en minúscula), ‘O’ (letra o mayúscula), o ‘I’ (letra i mayúscula) como simples caracteres para nombres de variables, para evitar confusiones a la hora de leer el código.

Declaración de variables.

Una variable tiene un nombre, un valor y un tipo. Con la asignación, se puede cambiar el valor de la variable.

Todas las variables deben ser declaradas antes de su uso. Las declaraciones deben aparecer al principio de cada función o bloque de sentencias. Al declarar una variable se debe indicar primero el tipo de variable y luego su nombre, opcionalmente se le puede dar un valor, lo que se llama inicializar la variable.

La declaración consta de un tipo de variable y una lista de variables separadas por coma.

  • int i,j;
  • float x,pi;
  • unsigned long longitud, contador;

Las variables pueden inicializarse en la declaración

  • float pi=3.1416;
  • unsigned long contador=0;

Puede utilizarse el modificador const para indicar que la variable no puede ser cambiada en tiempo de ejecución.

  • const float e=2.7182;

La declaración de una variable sólo debe hacerse una vez en un programa, pero el valor de la variable se puede cambiar en cualquier momento usando aritmética y reasignaciones diversas.

Una variable puede ser declarada en una serie de lugares del programa y en función del lugar en donde se lleve a cabo la declaración, esto determinará en qué partes del programa se podrá hacer uso de ella, es lo que se denomina ámbito de la variable o scope.

C y C++ se dice que son lenguajes de tipado estático, es decir, la comprobación de tipificación se realiza durante la compilación, y no durante la ejecución, por lo tanto no podemos cambiar el tipo de una variable en tiempo de ejecución. Otros lenguajes, generalmente interpretados, son de tipado dinámico y una misma variable puede tomar valores de distinto tipo en distintos momentos, como PHP o python.

La explicación de www.arduino.cc de las variables: http://arduino.cc/en/Tutorial/Variables y http://arduino.cc/en/Reference/VariableDeclaration

Usando Visualino tenemos de un apartado de variables donde tenemos los bloques para declarar, asignar y llamar las variables.

Ámbito de una variable

Una variable puede ser declarada al inicio del programa antes de la parte de configuración setup(), a nivel local dentro de las funciones, y, a veces, dentro de un bloque, como para los bucles del tipo if.. for.., etc. En función del lugar de declaración de la variable así se determinará el ámbito de aplicación, o la capacidad de ciertas partes de un programa para hacer uso de ella.

Una variable global es aquella que puede ser vista y utilizada por cualquier función y estamento de un programa. Esta variable se declara al comienzo del programa, antes de setup().

Recordad que al declarar una variable global, está un espacio en memoria permanente en la zona de static data y el abuso de variables globales supone un uso ineficiente de la memoria.

Una variable local es aquella que se define dentro de una función o como parte de un bucle. Sólo es visible y sólo puede utilizarse dentro de la función en la que se declaró. Por lo tanto, es posible tener dos o más variables del mismo nombre en diferentes partes del mismo programa que pueden contener valores diferentes, pero no es una práctica aconsejable porque complica la lectura de código.

En el reference de Arduino hay una muy buena explicación del ámbito de las variables: http://arduino.cc/en/Reference/Scope

Con Visualino es posible declarar variables locales y globales:

El modificador de variable static, es utilizado para crear variables que solo son visibles dentro de una función, sin embargo, al contrario que las variables locales que se crean y destruyen cada vez que se llama a la función, las variables estáticas mantienen sus valores entre las llamadas a las funciones.

La variables estáticas solo se crean e inicializan la primera vez que la función es llamada. Ver ejemplo en: http://arduino.cc/en/Reference/Static

Con Visualino no es posible declarar variables estáticas.

Probar este ejercicio y luego añadir static a la variable valor. Ver la diferencia.

Solución: https://github.com/jecrespo/aprendiendoarduino-Curso_Arduino_2017/tree/master/Ejercicio03-Visualino_Variables

Constantes

En programación, una constante es un valor que no puede ser alterado/modificado durante la ejecución de un programa, únicamente puede ser leído. Una constante corresponde a una longitud fija de un área reservada en la memoria principal del ordenador, donde el programa almacena valores fijos. Por ejemplo el valor de PI = 3.1416.

El modificador const, modifica el comportamiento de una variable haciéndola “read-only”, esto significa que puede usarse como cualquier otra variable pero su valor no puede ser cambiado.

Más información en: http://arduino.cc/en/Reference/Const

El entorno de programación de Aduino también tiene predefinidas unas constantes o expresiones, que facilitan la lectura del código: http://arduino.cc/en/Reference/Constants

En C++ las constantes también pueden ser definidas a nivel de módulo antes de compilar, de forma que no ocupan memoria y su nombre es sustituido por el valor definido en el proceso de compilación. Estas constantes por norma se escriben con letras en mayúscula y guiones bajos separando palabras. Por ejemplo, MAX_OVERFLOW y TOTAL. Se usa la palabra clave #define para definirlas.

Más información en: https://www.arduino.cc/en/Reference/Define

En Visualino no está disponible la opción de declarar constantes, pero se pueden declarar variables globales y luego añadir el modificador const.

Arrays, Strings y Constantes

Arrays

Un array es un conjunto de valores a los que se accede con un número índice. Cualquier valor puede ser recogido haciendo uso del nombre de la matriz y el número del índice. El primer valor de la matriz es el que está indicado con el índice 0, es decir el primer valor del conjunto es el de la posición 0. Un array tiene que ser declarado y opcionalmente asignados valores a cada posición antes de ser utilizado.

Declaración de un array:

int miArray[] = {valor0, valor1, valor2…}

Del mismo modo es posible declarar un array indicando el tipo de datos y el tamaño y posteriormente, asignar valores a una posición específica:

  • int miArray[5];
  • miArray[3] = 10;

Para leer de un array basta con escribir el nombre y la posición a leer:

  • x = miArray[3];

Las matrices se utilizan a menudo para estamentos de tipo bucle, en los que la variable de incremento del contador del bucle se utiliza como índice o puntero del array. Utilizando un bucle tipo for, el contador comienza en cero 0 y escribe el valor que figura en la posición de índice 0 en la serie que realizada sigue escribiendo en las siguientes posiciones. Con un bucle for podremos recorrer un array ya sea para leerlo o para escribir en él.

int myPins[5];

int i;

for (i = 0; i < 5; i = i + 1) {

 Serial.println(myPins[i]);

}

No se puede crear un array sin definir su tamaño, sino da un error de compilación.

Los arrays sólo pueden contener elementos del mismo tipo de datos. Si quisiéramos guardar tipos de datos diferentes en una misma variable, C nos ofrece la opción definir estructuras: http://c.conclase.net/curso/?cap=011

Ver más información en: http://arduino.cc/en/Reference/Array

Es posible definir arrays de varias dimensiones o matrices, simplemente haciendo un array de arrays:

Definición:

int matriz[5][5];

matriz[2][0] = 3;

string (char array)

Un string es un array de chars. Cuando se trabaja con grandes cantidades de texto, es conveniente usar un array de strings. Puesto que los strings son en si mismo arrays.

Ver:

String (Objeto)

Se trata de una clase que permite usar y manipular cadenas de texto de una forma más sencilla que los strings. Puedes concatenar, añadir, buscar, etc… usando los métodos/funciones que ofrece esta clase.

Los Strings tienen un uso intensivo de memoria, pero son muy útiles y se van a utilizar mucho en el apartado de comunicación, por ese motivo es importante aprender a manejar los Strings.

Tener en cuenta que al no ser un tipo de dato propiamente dicho sino una clase, tienes unas funciones asociadas (métodos), operadores y unas propiedades. Es una abstracción del dato y para aprender a usarlo hay que leerse la documentación correspondiente.

Ver documentación de Arduino sobre la clase String:

Además de la clase String, podemos utilizar las funciones estándar de C++ para manipular strings y hacer lo mismo que hacemos con la clase String, pero de una forma más compleja, donde tendremos que manejarnos bien con los punteros.

Conversiones de tipos (Casting)

En ocasiones es necesario forzar el cambio de tipo de dato (casting). Podemos usar las siguientes funciones:

Constantes

Las constantes son generalmente definidas a nivel módulo, escritas con todas las letras en mayúscula y con guiones bajos separando palabras. Por ejemplo, MAX_OVERFLOW y TOTAL. Se usa la palabra clave #define para definirlas.

Más información en: https://www.arduino.cc/en/Reference/Define

El modificador const, modifica el comportamiento de una variable haciéndola “read-only”, esto significa que puede usarse como cualquier otra variable pero su valor no puede ser cambiado.

Más información en: http://arduino.cc/en/Reference/Const

El entrono de programación de Aduino también tiene predefinidas unas constantes o expresiones, que facilitan la lectura del código: