Unlimited Plugins, WordPress themes, videos & courses! Unlimited asset downloads! From $16.50/m
Advertisement
  1. Code
  2. Android SDK

Android Things: Entrada/Salida Periféricas

by
Difficulty:BeginnerLength:LongLanguages:
This post is part of a series called Android Things.
Android Things: Your First Project
Android Things: Understanding and Writing Drivers

Spanish (Español) translation by Nadia Castelli (you can also view the original English article)

Android Things posee la habilidad única de conectarse fácilmente a componentes electrónicos externos con la Peripheral API y su soporte integrado para dispositivos. En este artículo, aprenderás acerca de los distintos tipos de periféricos que puedes conectar para personalizar tus dispositivos IoT con Android Things.

Trabajando con Diferentes Interfaces

Android Things permite a la mayoría de los dispositivos conectarse a tu placa de circuito impreso mediante el uso de la Peripheral API, que soporta interfaces GPIO, PWM, I2C, SPI, y UART, cada una de las cuales son interfaces estándar de la industria para la comunicación con periféricos. En esta sección aprenderás qué son estas interfaces, y cómo comunicarte con dispositivos que has conectado a tu placa de circuito impreso Android Things utilizando estas conexiones.

GPIO

Los pins de Entrada/Salida de Propósito General (GPIO) son utilizados para comunicación digital (binaria) con componentes, como leer si un botón es oprimido o no, o encender y apagar un LED. De los métodos de E/S que verás en este tutorial, GPIO es el más simple de usar, ya que solo requiere un pin y el uso de valores booleanos para estados alto y bajo.

Antes de que puedas conectarte a un pin GPIO, necesitas saber el nombre único de dicho pin. Puedes obtener los nombres de todos los pins disponibles mediante PeripheralManagerService, invocando getGpioList(). En un Raspberry Pi, este método retornará la siguiente lista:

Para darte cuenta a qué pin representa cada uno de estos valores, puedes referirte al diagrama de E/S del Raspberry Pi.

Raspberry Pi IO pin name chart for Android Things

Una vez que conozcas el nombre del pin del cual estarás leyendo, o al cual estarás escribiendo, puedes obtener una referencia de objeto Gpio a ese pin, invocando openGpio(String pin_name) desde tu PeripheralManagerService.

Los pins GPIO pueden ser utilizados para entrada o salida. Si tú usas este pin para leer información, debes configurar la dirección del pin como DIRECTION_IN, y establecer el tipo de disparador para ese pin, para que sepa cuándo permitirle a tus apps saber que algo ha ocurrido.

El disparador consiste de EDGE_NONEEDGE_RISINGEDGE_FALLING, y EDGE_BOTH. Si se presiona un botón, se genera un evento mientras se completa el circuito del botón, y una señal de alto voltaje aparece en el pin físico. Otro evento ocurre cuando el botón deja de ser oprimido. Se le notificarán los cambios a tu código, en base al tipo de disparador que configures.

GPIO input component Button

Ahora que tu GPIO está escuchando disparadores, necesitas crear un GpioCallback para registrar el valor del componente GPIO en tu app.

Una vez creado tu callback, regístralo con tu objeto Gpio.

Si tu pin GPIO está escribiendo información, necesitarás configurar la dirección como DIRECTION_OUT_INITIALLY_LOW o DIRECTION_OUT_INITIALLY_HIGH, dependiendo de si deseas que el componente inicie encendido o apagado. No se requieren tipos de disparados para los pins de salida.

Para poder escribir al dispositivo, puedes invocar setValue(boolean) en el objeto Gpio para establecer el estado del componente.

Una vez que tu app haya terminado de correr, necesitarás anular el registro de tu callback de entrada, si hubiera sido creado y registrado, y cerrar el acceso al periférico utilizando el método close() en onDestroy().

PWM

Los dispositivos con Modulación por Ancho de Pulsos (PWM) utilizan la alternancia de estados digitales, conocidos como una señal de control proporcional, para funcionar. Hay tres partes importantes de una señal de control proporcional a tener en cuenta:

  • Frecuencia: Describe la frecuencia con que se repite el pulso de salida. La unidad de medida de la frecuencia es el hertz (Hz).
  • Ciclo de Trabajo: Representa el ancho de un pulso dentro de una frecuencia determinada. El ciclo de trabajo se expresa como un porcentaje de señales altas dentro de una frecuencia, por lo tanto, un ciclo que tiene señales altas durante la mitad de ese tiempo, tendrá un ciclo de trabajo del 50%.
  • Período: Representa el tiempo que tarda cada ciclo alto/bajo en ocurrir. El período es inversamente proporcional a la frecuencia.

Mediante el ajuste del ciclo de trabajo de una señal, se puede controlar el tiempo promedio de estado "encendido" de una onda. Debajo puedes ver un ejemplo de una señal con período del 50%.

Example of a PWM signal

Algunos dispositivos que puedes utilizar señales PWM incluyen servomotores, que utilizan la frecuencia para determinar su posición, o una matriz de LEDs, que puede emplear la señal PWM para ajustar el brillo.

PWM servo motor component

Solamente con motores y dispositivos GPIO, puedes crear un gran número de dispositivos IoT, como por ejemplo un árbol para gatos "inteligente" con láser motorizado.

Similar a GPIO, puedes obtener una lista de los puertos PWM disponibles creando un PeripheralManagerService e invocando getPwmList(). En un Raspberry Pi, esta lista se vería así:

Una vez que sepas el nombre del pin PWM que deseas utilizar, puedes abrir una conexión a ese periférico mediante el método openPwm(String). Éste debe encapsularse en un bloque try/catch para manejar la posibilidad de una IOException.

Una vez que hayas abierto la conexión a tu pin PWM, puedes controlar su configuración, como la frecuencia y el ciclo de trabajo.

Antes de terminar la ejecución de tu app y destruir la Activity, debes cerrar la conexión y liberar la referencia a tu dispositivo PWM.

I2C

El bus de Circuito Interintegrado (I2C)  le permite a tu proyecto la comunicación con múltiples dispositivos sobre una conexión física, y te permite enviar datos complejos con solo unos pocos pins de tu Pi u otro dispositivo integrado. I2C utiliza comunicación sincrónica entre dispositivos, y depende de una señal de reloj para asegurarse de que los dispositivos están respondiendo en el momento apropiado.

El dispositivo que provee la señal de reloj, que probablemente sea tu dispositivo Android Things, es conocido como "Master", y todos los periféricos conectados que reciben la señal son llamados "Slave".

Al contrario de PWM y GPIO, que solo requieren un único pin, los dispositivos I2C requieren tres conexiones:

  • Señal de reloj compartida (abreviado SCL), que provee la señal de reloj desde el dispositivo Master hacia los Slave.
  • Línea de datos compartida (abreviado SDA), que es la conexión usada para la transferencia de datos propiamente dicha. Como I2C es un estándar de comunicación sincrónico (semidúplex), lo que significa que los datos solo pueden moverse en una dirección a la vez, solo un dispositivo puede usar esta conexión en cualquier momento en particular.
  • Una conexión eléctrica a tierra.

Vale la pena destacar que cada dispositivo I2C Slave está programado con una dirección determinada, y solo responderá cuando el dispositivo Master haga una petición de datos a esa dirección particular.

I2C bus diagram

Algunos periféricos que pueden utilizar este método de conexión son las pantallas de matriz LED segmentada, y varios sensores avanzados.

I2C OLED component

Cada dispositivo Android Things tendrá un conjunto de pins utilizados para I2C, que puedes encontrar mirando la documentación de tu placa de circuito integrado específica. Para el Raspberry Pi, puedes referirte a la imagen de los pins al principio de este artículo, que indica que los SDA y SDL son los pins 3 a 5. Para hallar el nombre de tu I2C, puedes ejecutar el siguiente código:

El trozo de código aquí arriba mostrará lo siguiente en un Raspberry Pi.

Una vez que sepas el nombre de tu bus I2C, puedes conectarte a dispositivos en ese bus usando su dirección de software. Puedes encontrar la dirección de software y otros detalles a bajo nivel de la conexión en la "hoja de datos" del componente periférico—¡su lectura es requerida si quieres utilizar un periférico para un proyecto integrado!

Al comunicarte con un dispositivo sobre I2C, puedes emplear el protocolo de Bus de Administración del Sistema (SMBus) para persistir datos dentro de registros, o para recuperar datos que han sido almacenados en registros en casa dispositivo periférico. Esto se logra utilizando la dirección del dispositivo y la dirección del registro, y Android Things te permite leer o escribir bytes individuales desde un registro o grupo de bytes de registros múltiples con los siguientes métodos:

  • readRegByte() y writeRegByte(): Leer o escribir un único byte de un registro específico.
  • readRegWord() y writeRegWord(): Leer o escribir bytes de dos registros secuenciales en un periférico en formato little-endian.
  • readRegBuffer() y writeRegBuffer(): Leer o escribir bytes de hasta 32 registros consecutivos. Los valores son escritos o recuperados como byte array.

Cuando tu app esté lista para parar su ejecución en el dispositivo Android Things, asegúrate de anular el registro de tu bus I2C.

SPI

Las conexiones de Interfaz de Periféricos Serie trabajan de manera similar a las conexiones I2C, con la diferencia de que soportan comunicación dúplex. Esto significa que pueden leerse y escribirse datos en los periféricos a la vez, en lugar de requerir que el dispositivo Master pida información a los periféricos Slave. Aún se necesita una señal de reloj para controlar el flujo de datos de múltiples dispositivos en el bus de señal SPI. SPI requiere un mínimo de cuatro conexiones para funcionar:

  • Master Out Slave In (MOSI)
  • Master In Slave Out (MISO)
  • Señal de reloj (CLK)
  • Toma a tierra común (GND)

Además, se necesita una quinta conexión si se conectan múltiples dispositivos SPI a un bus SPI. Esta es denominada Chip Select (CS), que se utiliza para señalar la dirección de hardware de los periféricos, para que el dispositivo Master pueda comunicarse con un Slave específico.

Algunos ejemplos de periféricos que utilizan SPI son los visualizadores de matriz de puntos y los lectores de tarjeta SD, y vale la pena destacar que muchos periféricos que soportan I2C además soportan SPI.

SPI supported SD card reader and MP3 player component

Como en los ejemplos anteriores, necesitas saber el nombre de la conexión SPI de tu placa Android Things. Puedes averiguarlo creando un PeripheralManagerService y llamando a getSpiBusList() en ese objeto. En un Raspberry Pi, obtendrías lo siguiente:

Una vez que sepas el nombre del bus SPI que usarás, puedes abrir una conexión al mismo.

Para poder comunicar dispositivos sobre el bus SPI, todos deben "hablar el mismo lenguaje", lo que significa que deben estar configurados para el mismo ritmo de reloj y formato de datos. Si bien algunos periféricos pueden ajustar su formato de datos y ritmo de reloj, otros no. Como todos los dispositivos en un bus SPI deben operar con la misma configuración, es importante conocer las capacidades de tus periféricos antes de intentar integrarlos en tu bus SPI. Existen cuatro configuraciones/parámetros que deberán ser establecidos para tu bus SPI:

  • Modo SPI: El modo SPI tiene dos componentes principales: si la señal de reloj es alta o baja mientras que no hay datos siendo transferidos, y qué extremo de un pulso se utiliza para transferir datos.
  • Frecuencia: Representa la señal de reloj compartida en Hz, y muy probablemente sea un valor determinado por las capacidades de tus dispositivos Slave.
  • Justificación de bit: Utilizada para definir la extremidad (endianness) para tus datos. Por defecto, Android Things utilizará big-endian, colocando el bit más significativamente grande (MSB) primero.
  • Bits por palabra (BPW): Controla cuántos bits se enviarán a un dispositivo Slave antes de cambiar la señal de selección de chip. Por defecto, se enviarán ocho bits por palabra.

En tu código Java Android Things, puedes configurar estos cuatro valores en tu bus SPI de la siguiente forma:

La manera en que interactúas contus dispositivos en el bus SPI depende de si estás operando en modo dúplex o semidúplex. Sui tus dispositivos están configurados como semidúplex, querrás intercambiar datos entre los Slave y el Master con los métodos read() y write() del objeto SpiDevice. Si estás operando en modo dúplex, querrás utilizar el método transfer() con dos buffers de array de bytes: uno con los datos a enviar, y otro vacío para almacenar los datos de la respuesta.

Cuando tu app esté lista para detenerse, asegúrate de anular el registro de tu dispositivo SPI.

UART

Los periféricos más complejos, como pantallas LCD, lectores de tarjeta SD, y módulos GPS, a menudo usarán comunicación en serie mediante puertos UART al comunicarse con un dispositivo Master. UART permite a los dispositivos el envío de data asincrónica hacia un buffer en otro dispositivo. Luego, este buffer se lee en orden first-in-first-out. También permite que tanto el formato de datos como la velocidad de transferencia sean configurados en ambos dispositivos conectados. Ambos dispositivos deben ponerse de acuerdo en una velocidad de transferencia, ya que UART no soporta una señal de reloj, pero la velocidad de transferencia tiende a ser más rápida que I2C, y los datos pueden ser transferidos en modo dúplex entre dispositivos. Al contrario que I2C y SPI, se permite solo un periférico conectado por cada conexión UART.

Los periféricos UART poseen tres cables principales:

  • RX, que se usa para recibir datos.
  • TX, que se usa para transmitir datos.
  • GND, toma a tierra.
UART wiring diagram

En los componentes periféricos, estos pins serán generalmente etiquetados de la siguiente manera:

Simple UART component

Además, algunos dispositivos UART pueden incluir dos conexiones más para controlar el flujo de datos:

  • Petición para Enviar (RTS)
  • Listo para Enviar (CLS)
UART component with RTS control signal pin

De forma similar a todos los ejemplos anteriores, necesitas saber el nombre de la conexión UART de tu dispositivo Android Things. Puedes hallarlo con el siguiente código:

En un Raspberry Pi, la salida de la ejecución será la siguiente:

Una vez que sepas el nombre de tu conexión UART, puedes crear un dispositivo Android Things UART de la misma manera que ya has abierto otras conexiones en dispositivos.

Cuando tengas listo tu dispositivos, necesitarás configurar el formato para los marcos de datos que se envíen entre dispositivos. Hay cuatro propiedades a tener en cuenta:

  • Número de bits de datos: UART puede enviar entre cinco y nueve bits para representar un carácter de datos. El envío de menos bits posibilita una tasa de transferencia de datos más alta, pero limita el rango de caracteres que pueden ser enviados.
  • Bit de paridad: Utilizado para chequear si el contenido de los datos de una transmisión suman un número par o impar. Si la paridad está configurada como nula, el bit de paridad se remueve de la transmisión. Esto se utiliza para chequear que las transmisiones no contengan errores.
  • Bits de parada: Pueden ser uno o dos bits. La transmisión permanecerá detenida durante un tiempo equivalente al número de bits de parada para indicar que un marco de datos ha terminado.
  • Tasa de baudios: La tasa de baudios es la velocidad de transmisión para tu marco de datos. Como las señales de reloj no existen en UART, ambos dispositivos deben ser configurados con una tasa de baudios antes de comenzar la transmisión.

Cada una de estas configuraciones puede ser definida en un dispositivo UART de la siguiente forma:

Más temprano aprendiste que existen dos configuraciones de cableado para los dispositivos UART, los que poseen señales de control adicionales, y los que no. Puedes configurar tu dispositivos UART en el código, usando el método setHardwareFlowControl().

Una vez que hayas terminado de configurar tus dispositivos, es hora de leer y escribir datos desde tu placa Android Things y tu periférico UART. La escritura se maneja invocando el método write() con un buffer de array de bytes y la longitud del mismo.

Si bien puedes sondear continuamente los datos del buffer de lectura de tu dispositivo, lo mejor es crear un objeto UartDeviceCallback, que provee un método llamado onUartDeviceDataAvailable(), el cual será disparado cuando haya datos disponibles. En ese momento, podrás leer datos del buffer de datos de tu dispositivo. Podrás asociar este callback a tu dispositivo UART con registerUartDeviceCallback, aunque debes recordar hacer la llamada a unregisterUartDeviceCallback cuando termines de utilizar el callback. Cuando haya datos disponibles, puedes obtenerlos utilizando el método read() de UART.

Cuando termines de utilizar tu Activity, asegúrate de cerrar y anular la referencia a tu dispositivo UART.

E/S Avanzada y Actualizaciones Futuras

Mientras que la Peripheral API te permite comunicarte con casi cualquier dispositivo capaz de ser cableado a tu placa Android Things, Google ha provisto soporte adicional para que el armado de tus dispositivos IoT sea aún más sencillo. Esta sección se enfocará en parte del soporte periférico adicional disponible en Android Things.

E/S Nativa

Si bien Android Things provee una manera simple para que los desarrolladores Android se involucren en el desarrollo IoT con Android SDK y Java, existe muchas apps IoT en C y C++, y otros desarrolladores quizás prefieran trabajar en esos lenguajes por varios motivos. Para dar soporte a esto, Google ha complementado la Peripheral API con soporte para aplicaciones nativas y NDK. No profundizaré en este tema, pero las conexiones están establecidas y su uso es muy similar a las maneras previamente discutidas.

WiFi y Bluetooth

Sin una manera de conectarse a Internet, los dispositivos IoT simplemente serían cosas. Con soporte inalámbrico integrado, tus dispositivos Android Things pueden conectarse a Internet y utilizar variados recursos online, como Firebase y otros servicios de Google, o cualquier otro servicio back-end. Además, el uso de herramientas como Google Play Services como Nearby Connections API les permite a los usuarios la comunicación directa con tu dispositivo sobre su red WLAN.

Aunque en este momento no está habilitada en las versiones developer preview de Android Things, la conectividad Bluetooth es también una capacidad importante para IoT. Usando Bluetooth, puedes crear múltiples dispositivos o accesorios IoT y comunicarlos en la corta distancia. Esto permite a cada dispositivo tener información contextual adicional sobre su entorno, como la casa o lugar de trabajo de un usuario, con el objetivo de servir mejor al usuario.

USB

Algunos dispositivos trabajan con puertos USB de las placas de circuito impreso, aunque no está enteramente habilitado en la versión corrientes de la developer preview de Android Things. En la segunda developer preview, Google agregó audio USB con soporte para texto a voz, y los desarrolladores han confirmado que también funcionan otros dispositivos, como los micrófonos USB. A medida que las API USB se prueben y aprueben en versiones futuras de Android Things, habrá un amplio rango de dispositivos que puedan ser simplemente conectados a tu dispositivo IoT como un accesorio.

Cámaras y Pantallas

Algunos dispositivos, como Raspberry Pi, vienen con conexiones E/S adicionales, como HDMI, Pantalla, y Cámara. Afortunadamente, todas ellas están habilitadas en Android Things, permitiéndote conectar una cámara con un cable cinta de 15cm...

Raspberry Pi with connected camera module

... o una pantalla mediante un cable cinta o conexión HDMI:

Raspberry Pi 5 display connected through HDMI

Conclusión

¡Felicitaciones! Has cubierto mucho terreno, pero has aprendido información increíblemente valorable sobre la conexión y el control de dispositivos periféricos con una placa Android Things. Utilizando este conocimiento, deberías ser capaz de conectarte y comunicarte con varios componentes de hardware.

En la próxima publicación de esta serie, usaremos nuestro conocimiento de la Peripheral API para crear un controlador de software para un sensor de movimiento GPIO, que puede utilizarse luego en un proyecto Android Things mayor.

¡Mientras tanto, revisa algunos de nuestros otros tutoriales y artículos acerca de desarrollo Android!

Advertisement
Advertisement
Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.