Archivo de la categoría: Software

Programar ESP8266 desde el IDE Arduino y con sus librerías

¿Qué es un ESP8266?

El ESP8266 es un chip con capacidad Wi-Fi con un stack TCP/IP completo y un microcontrolador, fabricado por Espressif, una empresa China. El primer chip se hizo conocido el mercado con el módulo ESP-01, desarrollado por la empresa AI-Thinker. Este pequeño módulo permite a otros microcontroladores conectarse a una red inalámbrica Wi-Fi y realizar conexiones simples con TCP/IP usando comandos al estilo Hayes (comandos AT).


Características

•   CPU RISC de 32-bit: Tensilica Xtensa LX106 con un reloj de 80 MHz. El reloj de la CPU y la memoria flash puede duplicarse por overclocking en algunos dispositivos. La CPU puede funcionar a 160 MHz y la memoria flash puede trabajar entre 40 MHz y 80 MHz. Varía según la versión del chip.
•   RAM de programa de 64 KB, RAM de datos de 96 KB
•   Capacidad de memoria externa flash QSPI de 512 KB a 4 MB (puede manejar hasta 16 MB)
•   IEEE 802.11 b/g/n Wi-Fi
     o Tiene integrados: TR switch, balun, LNA, amplificador de potencia de RF y una red de adaptación de impedancias
     o Soporte de autenticación WEP y WPA/WPA2
•   16 pines GPIO (Entradas/Salidas de propósito general)
•   Interfaces SPI, I²C,
•   Interfaz I²S con DMA (comparte pines con GPIO)
•   Pines dedicados a UART, más una UART únicamente para transmisión que puede habilitarse a través del pin GPIO2
•   1 conversor ADC de 10-bit

Diversos modelos de módulos que utilizan el ESP8266

El ESP8266 se puede programar desde el IDE de Arduino. Para eso hay que instalar lo que se llama un plugin, en el que está incluido todo lo necesario para compilar y subir programas que fueron escritos tal como si fuesen .INO de Arduino.

En principio, y es importante, mantenga siempre actualizada la Interfaz de Usuario o IDE (Integrated Development Environment – Entorno de Desarrollo Integrado) del Arduino descargándola de la página oficial en www.arduino.cc.

Debemos incorporar bibliotecas y los programas de manejo de las placas con el chip ESP8266 a nuestro IDE. Para hacerlo, debemos indicarle la URL desde donde se obtienen.

Para hacerlo, debemos abrir el menú Archivo, y luego Preferencias.

Veremos este panel, en la parte inferior el recuadro de texto rotulado Gestor de URLs Adicionales de Tarjetas. Dentro de él, usando copiar y pegar, se debe introducir el texto indicado aquí:

http://arduino.esp8266.com/stable/package_esp8266com_index.json

(copie y pegue en el recuadro):

Luego pulse en el botón Ok.

Ahora debemos ir al menú Herramientas, luego Placa.

Y finalmente Gestor de Tarjetas, se abrirá una ventana como la que sigue, en la cual escribimos, en el recuadro superior de filtro/busqueda, “ESP8266” (antes de terminar de escribir ya aparecerá el Gestor de Tarjetas que buscamos, que indica que fue creado por “ESP8266 Community”. Allí pulsamos sobre Instalar:

Al abrir nuevamente Herramientas, y luego Placa, deslizamos la lista para ver lo que aparece al final de ella (abajo), y vemos que ya existen las opciones referidas a los ESP8266:

Artículos relacionados:

ESP8266 (WiFi): Hacer que parpadee un LED desde el IDE de Arduino
Servidor web básico NodeMCU con IDE de Arduino



Arduino: bibliotecas de funciones personales

A menudo tenemos fragmentos de código con funciones que podemos reutilizar en muchos programas. Algo muy habitual en programación. Creamos una función que resuelve una necesidad concreta y queremos tenerla disponible para reutilizarla en cualquier otro programa en el que debamos resolver la misma necesidad.

Lo habitual —pero no lo más práctico— es copiar el código de esa función especial dentro de cada nuevo programa. Pero conviene tenerla en un formato reutilizable con facilidad, sobre todo si la función es muy extensa.

Para lograrlo, guardamos esa función (y todas las variables y constantes que incluya) en un archivo .ino separado, pero no debemos cargarlo individualmente en una placa Arduino, sino que luego lo incluiremos en cada programa que necesitemos, de al modo que siempre lo tendremos disponible.

( Nota: no le llamamos “sketch” sino “programa” para Arduino. )

¿Cómo incluimos un trozo de programa en otro?

Vamos a crear un código reutilizable, y lo guardaremos en una ubicación conocida del disco, un “reservorio” de funciones útiles que llevan un nombre que nos recuerde qué es y lo que hace.

Quedará con la extensión .INO, pero no es un programa para cargar al Arduino y ejecutarlo. Queda con esa extensión porque todos los programas editados en la IDE de Arduino se graban siempre con la extensión .ino.

El código es uno que hayamos creado como función o grupo de funciones dentro de un programa mayor.

Tomaremos como ejemplo una cantidad de funciones creadas para los distintos movimientos de los motores en un programa para un robot navegador.

El circuito que este programa mueve, para mejor comprensión de los ejemplos, es este:

Veamos el programa original con las funciones incluidas dentro de él:

Ahora vamos a escribir un programa diferente, con otra serie de movimientos. Suponemos que estamos editando en el IDE de Arduino, como sigue:

Pero así no funcionaría, ya que tiene llamados a funciones (como adelanteDerecho, atrasIzquierdo, etc.) que están en otro lugar.

De modo que abrimos el programa que las tiene, copiamos las funciones que necesitamos…

… y las pegamos en una ventana vacía del IDE. Luego las guardamos con Guardar como… en la carpeta que deseemos. A esta carpeta podemos llamarla, por ejemplo: /FuncionesUtiles/

El archivo de funciones que creamos y guardamos es este: FuncionesMotor.ino, y es así:

Ahora sólo debemos ver cómo hacemos para incluir el archivo de funciones auxiliares en nuestro nuevo programa.

Para eso desplegamos el menú Programa en la barra de menúes de la parte superior del IDE. Seleccionamos la opción Añadir fichero… y se nos abre un cuadro de diálogo para que busquemos el .ino que guardamos allí, con las funciones de motor que queremos incluir en este programa nuevo.




Lo abrimos, como si fuera un .ino estándar, pero, debido a la opción que hemos elegido, en lugar de abrirse en una nueva ventana del IDE se abre en una nueva pestaña auxiliar de la misma ventana. Nuestra ventana de trabajo queda como vemos aquí:

Ya podemos regresar a la pestaña principal, compilar y subir el programa al Arduino.

Cuando guardemos este programa principal, y volvamos a abrirlo otro día, el IDE de Arduino se abrirá con las dos pestañas. Si se observa dentro de la carpeta que, como es habitual, lleva el nombre del programa (en este ejemplo Otro_control_de_motores) veremos que dentro de ella están los dos archivos .ino: Otro_control_de_motores.ino y FuncionesMotor.ino

Esto no significa que el IDE haya movido FuncionesMotor.ino desde la carpeta /FuncionesUtiles/ que creamos, sino que sólo lo ha copiado. Así que, por supuesto, este archivo .ino de funciones auxiliares para adjuntar podemos incluirlo en todos los programas donde sea necesario. No será propiedad exclusiva de ninguno de ellos.


Arduino: Entradas y salidas – Manipulación de puertos

NOTA: Para ver el uso de los pines del ATmega328P en Arduino recomiendo leer el artículo Arduino UNO R3 – Conectándolo al mundo exterior.

Programación avanzada de puertos

En principio, es importante recordar que los puertos de un microcontrolador de 8 bits tienen esa misma cantidad de entradas/salidas, o sea ocho líneas. Esto nos haría pensar que el ATmega328P, que posee tres puertos (B, C y D), dispone de 3 x 8 = 24 líneas de entrada/salida disponibles. Sin embargo, utilizado en un Arduino no es así, como veremos.

La mayoría de los bits de los puertos de los microcontroladores son de uso múltiple, es decir que se comportan de una forma u otra de acuerdo con su configuración. Varias líneas de puertos cumplen funciones vitales en la operación de un Arduino, funciones que no son líneas de entrada/salida de uso general.

El PORTB (puerto B) tiene ocupadas dos líneas de entrada/salida que se utilizan para conectar el cristal oscilador. Estos pines, el PORTB bit-6 y PORTB bit-7, pueden quedar libres si se configura al chip para utilizar el oscilador interno, pero esta opción no podemos utilizarla en el Arduino debido a que ya tiene su sistema basado en la velocidad de cristal de 16 MHz, además de que el cristal está soldado a esos pines en el circuito de la placa.

El PORTC tiene dos bits que no están disponibles, uno de ellos, el PORTC bit-6 se utiliza como entrada de reinicio (RESET), y el otro bit (7) no está cableado hacia el exterior del ATmega328P con cápsula PDIP que viene enchufado en el zócalo del Arduino Uno R3, porque no posee suficientes líneas disponibles en su encapsulado de 28 patas. Y cuando se trata de un chip con encapsulado de montaje superficial TQFP de 32 pines (como en el Arduino Nano y en algunos clones de Arduino Uno), las dos líneas faltantes están dedicadas al convertidor analógico digital (ADC6 y ADC7) y no son pines de entrada/salida digital.

Dos bits del PORTD, el PORTD bit-0 y el PORTD bit-1, se utilizan durante la programación del Arduino, ya que están conectados a la interfaz USB, además de ser los pines TX y RX utilizados para la comunicación serie. Estos pines se pueden utilizar para comunicación serie asincrónica hacia el exterior, y también como entradas o salidas cuando no se está grabando un programa. Pero no deben tener conexiones instaladas mientras se programa el Arduino.

En consecuencia, no se llega a disponer de la cantidad de 24 entradas/salidas que ofrecerían tres puertos de 8 bits.

El ATmega328P, como cualquier otro microcontrolador, tiene registros para cada puerto con los cuales se define si cada bit del puerto será usado como entrada o como salida, y en varios casos otra función. El ATmega328P tiene tres puertos: PORTB, PORTC y PORTD, por lo cual hay tres bancos de registros de configuración, uno para cada puerto.

Bancos y puertos de ATmega 328p
Banco 27 26 25 24 23 22 21 20
PORTB     Digital 13 Digital 12 Digital 11 Digital 10 Digital 9 Digital 8
PORTC     A5 A4 A3 A2 A1 A0
PORTD Digital 7 Digital 6 Digital 5 Digital 4 Digital 3 Digital 2 Digital 1 Digital 0
Valor 128 64 32 16 8 4 2 1

Registros

El ATmega328P tiene tres registros de 8 bits con los que administra estos tres puertos:

  • DDRx (donde x es B, C o D en este caso) determina si un bit es entrada (fijándolo en 0) o salida (fijándolo en 1)
  • PORTx controla si el pin está en nivel ALTO (HIGH) o BAJO (LOW). También define la existencia o no de un resistor de polarización a Vcc (pull-up, en inglés) si es una entrada.
  • PINx permite leer el estado de los pines de un puerto (solo es para lectura)

Antes de entrar de lleno a explicar el uso de los registros, veamos primero para qué podría servir este esfuerzo.

Ventajas de usar registros:

  • Cada instrucción de máquina necesita un ciclo de reloj a 16 MHz. Las funciones digitalRead() y digitalWrite() se componen cada una de ellas de varias instrucciones de máquina, lo que puede influir negativamente en aplicaciones muy dependientes del tiempo. El uso de los registros PORTx puede hacer el mismo trabajo en muchos menos ciclos de reloj.
  • Si es necesario cambiar de estado varios pines simultáneamente en lugar de ir haciéndolo de a uno con un ciclo for, que tomaría mucho tiempo, es posibles escribir directamente al registro y establecer los valores de varios pines de una sola vez.
  • Si el código está llegando al límite de memoria de programa disponible (memoria Flash), es posible usar este método para hacer que el código use menos bytes de programa.




Desventajas de usar registros:

  • El código no es fácil de entender para novatos.
  • Es mucho mas fácil cometer errores de difícil depuración. Por ejemplo con DDRD = B11111111 se pone a todos los pines, D0 a D7 como salida, inclyendo el pin D0 (RX), lo que causará que el puerto serie deje de funcionar.

En las librerías es muy recomendable usar la manipulación directa de registros, de modo de hacerlas mucho más eficientes.

Registro DDRx – Definición de pines como entrada o salida

Al utilizar los registros DDR tenemos la ventaja de que con solo una instrucción podemos declarar el pin como entrada o salida, en cambio, utilizando pinMode() necesitaríamos 8 instrucciones.

Veamos un ejemplo con el registro DDRB del PORTB:

El ejemplo de la imagen define los 4 bits bajos o menos significativos (0 a 3) como entradas, y los 4 bits altos o más significativos (4 a 7) como salidas. Veamos cómo se verían este y otros ejemplos en el programa del IDE de Arduino.

Mediante estos registros también podemos controlar las resistencias internas de pull-up que se usan, básicamente, para no dejar los pines de entrada al aire, ya que esto genera ruido eléctrico. Se puede resolver el problema de dos maneras: poner una resistencia externa de 10K a Vcc (+5V) o usar los pull-up internos del microcomputador, que polarizan de la misma forma las entradas y hacen más simple el circuito.

Para habilitar las resistencias pull-up, primero tenemos que configurar como entrada el puerto (con el bit 0), mediante registro DDRx, y luego escribir un 1 en el registro PORTx.

Es el equivalente de usar varias veces las funciones digitalRead() y digitalWrite() de Arduino. Sin embargo, con acceso directo al puerto se puede ahorrar espacio en la memoria flash, porque cada operación con funciones de leer estados de un puerto ocupa varios bytes de instrucciones, y también se puede ganar mucha velocidad, porque las funciones Arduino puede tomar más de 40 ciclos de reloj para leer o escribir un solo bit en un puerto.

Nada mejor que un ejemplo concreto para entender las instrucciones de programa. Veamos un ejemplo con Leds.

Diagrama:

En este ejemplo, durante dos segundos todos los leds encienden, durante otros dos segundos se encienden los impares, luego los pares, y durante dos más se apagan todos.

Abrimos Arduino IDE y escribimos el siguiente código:

Un segundo ejemplo que puede resultar más divertido. Enciende un led en secuencia hacia a un lado y hacia el otro. No hice más sofisticado el programa para claridad y comprensión. Se puede hacer dentro de una estructura for, por ejemplo, tomando el dato a poner el puerto de una matriz. O usando otros recursos más complicados, como desplazar el dato sobre un registro antes de ponerlo al puerto. Pero prefiero que sea didáctico y comprensible para todos.

La secuencia suelen llamarla «El auto fantástico». Hasta se vende un dispositivo con ese efecto de luces para adornar los autos.

El programa es:

@nbsp;

Un chip de la liga mayor:

Sólo por completar la información, y dar una idea de la importancia de este tipo de ahorro de código en otros microcontroladores, voy a mostrar algunos datos de los puertos del ATMega2560, el núcleo del Arduino Mega 2560 R3 (esquemático). Un tremendo chip con nada menos que 100 pines y ONCE puertos, que van desde el PORTA al PORTL. ¡Imagínense el banco de registros que hay para manejar!

Microcontrolador ATmega2560-16AU

Placa Arduino Mega 2560 R3

Encapsulado del ATmega2560-16AU utilizado en el Mega 2560




Arduino: cómo hacer que los HEX queden en una carpeta conocida

Varias veces me han preguntado cómo se obtiene el archivo final de la compilación en «idioma de máquina» o hexadecimal (NombrePrograma.HEX) de un programa creado con el IDE de Arduino (también llamado Sketch por algunos).

Este archivo es útil para varias operaciones, como por ejemplo «descompilarlo» para ver el assembler, y también porque sería posible grabar el programa usando un programador de chips en un lote de microcontroladores que se necesite para un proyecto, sin usar bootloader ni una placa Arduino cuando vamos a producir una equis cantidad de plaquetas para uso personal, o para un cliente.

La secuencia para tenerlos en una carpeta accesible es:

1) Abrir el IDE de Arduino

2) Abrir el menú «Archivos» y allí elegir «Preferencias»

3) En el panel de Preferencias, abajo de todo, ingresar a la capeta de «preferences.txt» por medio del enlace que está debajo de un texto que dice «Más preferencias pueden se editadas [etc]…»

4) Una vez abierta la carpeta donde esta el archivo de preferencias, cerrar el IDE de Arduino (esto es muy importante)

5) Hacer una copia del archivo de preferencias para tenerlo de reserva por cualquier problema que se presente.

6) Abrir el TXT preferences.txt con un editor de texto simple, como el Bloc de Notas o Notepad

7) Hay una extensa lista allí. Buscar en el archivo de preferencias la zona donde está esta opción:

sketchbook.path=C:\Users\toshiba pc\Documents\Arduino

Obvio que la dirección dentro del disco C: que va luego del signo «=» será propia de cada máquina

8) Puede estar o no definida la opción build.path (es la que le indica al compilador dónde debe guardar el archivo compilado). Allí se puede crear o editarla. En mi caso, yo debí insertarla porque no existía y escribí:

build.path=C:\Users\toshiba pc\Documents\Arduino\HEX

Nota: En la publicación fuente de esta aplicación dice que es importante que este código agregado quede ubicado después de la opción export.application, pero sin embargo esto sería en una versión anterior, ya que ahora cada vez que se abre el IDE de Arduino estas opciones quedan ordenadas alfabéticamente.

9) Ahora sólo queda guardar este archivo editado y correr el IDE




10) Para comprobar que funciona, compilar cualquier programa y revisar si ha aparecido la carpeta HEX, y dentro de ella el compilado .HEX. Por ejemplo, si se compila el famoso ejemplo Blink.ino encontraremos el archivo Blink.ino.hex. Pero también encontrarán un Blink.ino.with_bootloader.hex. Es importante, ya que en este caso obtendrán un HEX con el que se podrán programar chips que además posean el habitual bootloader de la placa Arduino.

11) Luego uno puede ir distribuyendo estos .HEX en las carpetas de cada proyecto, ya que sólo estarán allí hasta que se haga la compilación de un nuevo programa. El IDE de la versión actual los borra antes de escribir un nuevo HEX.



Puente H: Placa controladora de motores L9110S

La placa L9110S está diseñada para que los microcontroladores o circuitos lógicos puedan controlar con sencillez motores de corriente continua.

Driver de motores L9110S

El circuito está diseñado en base al chip controlador L9110, fabricado en la clásica cápsula DIP8 o en un diseño SOP8 SMD y basado en transistores MOSFET.

Circuito integrado L9110S

La tensión de alimentación para los motores puede variar de 2,5 a 12 V.

Diagrama de conexión

Como se observa en el siguiente diagrama, el control con el cableado típico no requiere componentes adicionales.

Conexión básica

Las entradas se pueden conectar directamente al microcontrolador. Si se conectan a un circuito que tiene salidas OC (Open Colector, o Colector Abierto) se requiere una resistencia pull-up conectada a la alimentación de 5V. Si bien en la hoja de datos del chip indica que el valor adecuado es ?1 k?, el módulo en sí incluye en su circuito resistores de 10 k? conectados al voltaje de alimentación de la lógica, o Vcc.

El circuito tiene dos entradas: una que puesta en ALTO hará que el motor avance, y una que puesta en ALTO hará que retroceda. Si se desea que el motor esté detenido, ambas entradas deben estar en el mismo valor: las dos en estado BAJO (LOW), o ambas en estado alto (HIGH). La placa tiene dos salidas, con bornera, que se conectan directamente al motor.

Las entradas que no se conectan a un circuito son tomadas como nivel BAJO (L, o Low) sin que ingrese ruido. Con un nivel ALTO (H, o HIGH), la corriente en esa entrada será de alrededor de 1 mA. El nivel de tensión para que el chip detecte la entrada en estado lógico BAJO o L es como máximo de 0,7 V.

Típicamente, para el nivel ALTO o H, la tensión en el pin de entrada debe ser de alrededor de la mitad del valor de alimentación o más (hasta, como máximo, el valor de la tensión de alimentación).

La corriente del motor se puede mantener constantemente desde 0,75 hasta 0,8 A (750 a 800 mA), y el circuito soporta picos de 1,5 a 2 A.

La hoja de datos ofrece una lista de los valores lógicos de las entradas y salidas.

nuevo-5

Esta tabla se puede ampliar para situaciones no típicas. Si sólo hay una entrada en el nivel H y la otra está en nivel L, el motor gira. Pero si ambas entradas están en H, o ambas entradas están en L, las salidas están en un tercer estado, o “flotante” (ningún voltaje), y no ambas en 0 volt, o “L”, como se muestra en la tabla.

Las salidas están conectadas internamente a diodos que protegen al circuito de los pulsos de contracorriente.




El L9110 gestiona dinámicamente frecuencias de hasta 40 kHz, mientras que el tiempo de conmutación más breve para la regulación por ancho de pulso (PWM) es de alrededor de 15 uS.

Diagrama de conexiones

Conexiones

Diagrama eléctrico

Circuito Eléctrico

Ejemplo práctico para controlar un robot

Ejemplo práctico - Control de un Robot

Ejemplo de programa para Arduino: prueba de movimientos

L9110S como amplificador de sonido para su robot

El control de un motor no es la única aplicación posible. El circuito también se puede utilizar como un sustituto de amplificador de potencia para una salida de audio digital de un microcontrolador.

En lugar de conmutar corriente a través del parlante como se realiza habitualmente, con un transistor, este circuito proporciona una doble amplitud de los impulsos de salida y, por lo tanto, aporta una potencia significativamente mayor.

Para una fuente de alimentación de 5 V es conveniente conectar un altavoz con una impedancia de 8 ? (o superior), mientras que con una entrada de 3 voltios puede utilizarse un altavoz adaptado a un voltaje menor. Para controlar el altavoz es necesario utilizar dos salidas en las que el nivel H alternará en cada media onda de la frecuencia del sonido.

En la siguiente figura hay una conexión que es normal con una salida, y funciona bien de 5 Hz a aproximadamente 30 kHz. Es importante mantener la condición de salida del microcontrolador en un nivel H cuando no se emite sonido, de lo contrario circulará corriente constante por el parlante.

Amplificador

Artículos relacionados:
Uso de la placa L298N para motores de CC
Puente H: Placa controladora de motores L9110S
Guía rápida de placas de control de motores
Manejo de potencia para motores con el integrado L293D
Control de motores de CC por Ancho de Pulso (PWM)