bclose

TEA5767 FM con display I2C

Arduino y la radio FM

 
    • Vamos a añadirle un display al modulo de radio TEA5767
    • Veremos como mezclar dos dispositivos I2C
    • Escribiremos un primer programa que maneje ambos. 
 

 

Material requerido.

Imagen principalModulo de radio TEA5767

Vista principal
Un Arduino UNO o similar

Añadiendo un display a la radio

 

En la última sesión vimos como seleccionar una frecuencia determinada con el módulo de radio FM TEA5767, porque el objetivo de la sesión era básicamente quitar el miedo a los temas de radio que siempre hacen desconectar a una parte importante de oyentes.

Ya vimos que resulta muy fácil programar el modulo mediante I2C y vimos también que enviábamos información de la frecuencia sintonizada al puerto serie para no complicarnos la vida. Pero claro está, si estás leyendo esto es precisamente porque te gusta complicarte la vida y por eso queremos eliminar la siempre truculenta puerta serie y usar un display LCD de digamos 16×2 o quizás de 20×4 para mostrar la frecuencia de la radio.

Pero hete aquí que tenemos un problema, porque tanto el módulo de radio como el display LCD son I2C y esto de montar dos dispositivos I2C en el mismo bus es algo que genera múltiples consultas en los web e incontables terrores nocturnos a los novicios de Arduino.

Pero… un momento. El I2C es un bus pensado para incluir múltiples dispositivos compartiendo hilos y por tanto no tiene problema en manejar dos simples cacharritos. Por ello he querido aprovechar esta humilde sesión para mostrar un caso simple de cómo usar más de un dispositivo I2C con el mismo Arduino.

Pues estáis avisados. Vamos a ver como montamos una radio I2C junto con un display LCD i2C compartiendo el bus y sin problemas, faltaría más.

 

El bus I2C

 

Hemos hablado ya en estas páginas del bus I2C múltiples ocasiones por es un sistema de lo más cómodo de comunicar distintos dispositivos con nuestro Arduino y entre sí, pero creo que esta será la primera vez que tendremos 3 elementos conectados y así aprovechamos para ver como se hace y probar que no tiene dificultad.

Pero antes de empezar tenemos que recordar que el I2C comparte hilos de comunicación entre múltiples dispositivos a condición que cada uno de ellos tenga una dirección hexadecimal única y diferenciada del resto. Porque es precisamente el dirigir los comandos a una dirección concreta lo que nos permite compartir el bus sin que todos los nodos respondan a la vez.

En muchas ocasiones las librerías que usamos para manejar los módulos I2C suponen una dirección específica que es la que el fabricante pone por defecto a cada dispositivo. Este hecho es muy cómodo cuando solo tenemos un nodo además de nuestro Arduino porque la librería asume una dirección dada y se dirige a ella sin más.

El 90% de las veces funcionará, pero si el fabricante cambia esta dirección nos vamos a encontrar con un problema si no cambiamos la librería acorde con este cambio.

Si queremos usar varios nodos en el mismo bus (Como ahora) vamos a necesitar asegurarnos de que conocemos exactamente que direcciones tienen nuestros dispositivos para dirigirnos a ellos.

Normalmente los objetos definidos para el control de módulos I2C suponen esta dirección implícita sin necesidad que la especifiquemos (Por eso es implícita) pero siempre podemos detallar de forma explícita la dirección hexadecimal de cada módulo.

Imagínate que quieres poner 4 displays LCD que vienen por defecto con la misma dirección de fábrica. Tendremos que cambia la dirección de cada módulo para asegurarnos de que son diferentes y después tendremos que enviarles comandos con una dirección explicita, según queramos que cada uno muestre una cosa u otra.

 
  • El procedimiento para cambiar la dirección de fábrica de cada dispositivo depende del fabricante pero con bastante frecuencia basta con soldar o desoldar conexiones en el módulo para grabar un número hexadecimal que se suma a una dirección base del dispositivo.
  • Para el display LCD del que hablamos puedes jugar soldando las conexiones A1,A2 y A3 para modificar la dirección base:Detalle de pines para el cambio de direccion I2C 

El resumen de todo este rollo es que necesitas tener clara la dirección de cada módulo que conectes y para ello resulta muy útil un programa que ya usamos en su día: I2C scanner, que cuando lo ejecutas simplemente te da las direcciones hexadecimales de lo que hay enchufado al bus.

Por ejemplo voy a usar un display LCD 16×2 que si lo conecto me devuelve la dirección 0x3F hex y si añado (O quito el anterior y conecto este)  el módulo de radio TEA5767 me devuelve también la dirección de este 0x60 hex

Muestra la direccion I2C
ModuloDirección hexadecimal
Display LCD16020x3F
Radio TEA57670x60

 

Armados ya con algunos datos de valor vamos a ver como conectamos los dos módulos al I2C con nuestro amado Arduino.

 

Conectando dos nodos a nuestro I2C

 

Como siempre nos dicen que el I2C está en los puertos analógicos A5 y A4 de nuestro Arduino Uno, pensareis naturalmente que habrá que usar una protoboard externa para compartir los hilos, pero mira por donde, no. Si solo necesitamos dos hay truco usando más pines que nos proporciona nuestro Arduino y que tendemos a ignorar por razones poco claras. Fíjate en este esquema de pines:

Diagrama de pines Arduino UNO

Veras que rotula A5 y A4 como SCL y SDA para el I2C, pero quizás no te hayas fijado que hay otros dos pines con el mismo rótulo (Están conectados internamente) en la línea superior a la izquierda del pin D13 con los mismos rótulos y que normalmente hacemos como que no existen.

Por tanto, y por pura vagancia, vamos a usar estos pines para conecta el display LCD. Los que vienen a por nota se darán cuenta de que también hay que alimentar el display pero solo hay un pin de 5V en un Arduino UNO y necesitamos dos.

¿Tendremos después de todo que usar una protoboard? Pues va a ser que no. Al menos en mi caso, porque como estoy usando USB para alimentar mi Arduino puedo emplear el pin Vin que como corresponde a la tensión de entrada del USB estará en los 5V que necesitamos.

 
  • Ojo al Parche. Pocas bromas con las tensiones si no queréis quemar algo. Si alimentas tu Arduino por USB , el Vin estará a 5V pero no se te ocurra hacer esto si usas un alimentador externo porque aquí tendrás 9 o 12V y conseguirás quemar de inmediato el display o la radio ¿Vale?
  • Si usas alimentador externo tendrás que pasar por la protoboard sin remedio.

Veamos cómo podemos cablear la conexión del display y la radio a nuestro Arduino:

 

El programa de control

 

En la última sesión ya hablamos del programa para controlar la radio FM y partiendo de él, bastara con añadir unas líneas para incluir la gestión del display LCD.

Así pues, empecemos por los includes necesarios para el manejo de todo. Descárgate esta librería para el display LiquidCrystal_I2C-master y la añadimos a la cabecera:

#include <Wire.h>
#include <radio.h>
#include <TEA5767.h>
#include <LiquidCrystal_I2C.h>

Lo siguiente es definir la FM y frecuencia:

#define FIX_BAND RADIO_BAND_FM     // Sintonizamos FM

#define FIX_STATION 8950           // Los 40 de Bilbao 89.50 Mhz
// #define FIX_STATION 8850        // Cadena dial
// #define FIX_STATION 10370       // Cadena 100
//#define FIX_STATION 10790        // Hit FM

En cada sitio tendréis listas de frecuencia diferentes y bastará con una búsqueda rápida en Google para saber que emisoras tienes a tiro en tu área. Vamos a crear una instancia de los objetos de radio y LCD:

TEA5767 radio;    // Creamos una instancia de radio
LiquidCrystal_I2C lcd( 0x3F, 20, 4);  // Asignamos la dirección 0x3F al display
 
  • He usado 20,4 en el objeto para que también os sirva si usas un display de 20×4 en lugar de un 16×2. 

No hemos cambiado la primera línea con respecto al programa anterior, pero ¿Por qué no ponemos su dirección 0x60? Simplemente porque la librería asume esa dirección por defecto para el objeto radio.

 
  • Las librerías Arduino que instalas por tu cuenta se instala en Windows en \Documents\Arduino\libraries\ con un directorio por cada librería y directorios internos con el código fuente, los ejemplos etc.
  • Una búsqueda rápida por los programas fuente de la radio no devuelve enseguida que en \Documents\Arduino\libraries\Radio-master\src\ TEA5767.cpp hay una línea que explica el misterio: #define TEA5767_ADR 0x60 // I2C address of TEA5767
  • Si mañana el fabricante cambiase la dirección de base de la radio, bastaría con modificar esta línea y a otra cosa.
  • Entender las librerías no está siempre al alcance de la mayor parte de los aprendices de Arduino, pero en cuanto estés un poco suelto en programación os recomiendo que le echéis un vistazo porque se encuentran cosas de lo más curiosas y se aprende mucho.

La función setup() cambia poco:

void setup()
 {
 radio.init();        // Inicializar el objeto radio
 lcd.init();          // initialize the lcd
 radio.setBandFrequency(FIX_BAND, FIX_STATION);
 radio.setVolume(2);
 radio.setMono(false);
 }

Simplemente hemos eliminado las líneas para asignar la puerta serie (Usaremos el display en su lugar) y hemos añadido una línea para iniciar el LCD: lcd.init()

Y el loop() no es mucho más complicado, recogemos la frecuencia seleccionada en el chip de radio:

char s[12];
radio.formatFrequency(s, sizeof(s));

Y pasamos directamente a la gestión del display

  lcd.backlight();
  lcd.setCursor(3,0);
  lcd.print("Emisora: ");
  lcd.setCursor(2,1);
  lcd.print(s);

La primera línea enciende la luz de fondo, La segunda coloca el cursor en la primera línea y escribe emisora y la siguientes instrucciones saltan a la 2ª línea e imprime el valor de frecuencia.

Bastará ahora con ir volcando diferentes emisoras por programa (porque por ahora no hemos implementado ningún mecanismo para seleccionar diferentes emisoras)

Simplemente podemos ir desocmentando la frecuencia deseada y recompilar el programa para enviárselo a nuestro venerable Arduino UNO.

Evidentemente esto no es la situación ideal y en la próxima sesión montaremos un sistema para cambiar de emisora , quizás con un rotary encoder

De momento aquí tenéis un mini video con el resultado: