bclose

Display de 8 digitos, 7 segmentos con MAX7219

Representando números en un display de 7 segmentos

Sensor BME280

 

 

    • Vamos a usar un display con MAX7219 con 8 digitos de 7 segmentos.
    • Para ello escribiremos una función que imprima enteros en el display otra que imprima float.
    • Desarrollaremos un generador aleatorio de numeros float de diferentes longitudes y decimales.
    • Veremos el resultado final bailando en el display.
 

 

Material requerido.

 

 Tienda EspañaTienda Mexico
Imagen de Arduino UNO

Arduino Uno o compatible

Arduino Uno o compatible

 Digitos BCD Display 8 digitos 7 segmentos.

 

MAX7219 y display BCD de 8 dígitos

 

Andaba yo por casa buscando un display de buena visibilidad y al menos 6 0 7 dígitos, para una sesión que estoy preparando (Y que espero pueda ver la luz en breve) y sin pretenderlo me encontré con la caja de cosas raras, a la espera de que un día tenga ganas y tiempo de ponerme a ver qué puedo hacer con todo eso, cuando de repente me encontré con una tanda de estos displays.

Display BCD 8 digit

No recuerdo ni haber comprado, y me había olvidado por completo, pero que me venían de perlas para lo estaba pensando y además no me iba a costar 15 días que me llegara de cualquier proveedor más o menos lejano. Tenia muy buena pinta. 8 dígitos LED de 7 segmentos y conectores por delante y por detrás para poder conectarlos en cascada por si necesito mas dígitos. Bien, bien. Esto marcha.

Usa un chip MAX 7219 que es estándar para el manejo de esto tipo de displays, pero un poco latazo para andar controlando a pelo y ni puñetera idea de como manejarlo. Así que aplique la regla de oro cuando no tienes ni idea de como poner en marcha algo: Le pregunte a Google quien había hecho una librería para este chisme.

 
  • Afortunadamente en el mundo Arduino siempre hay un alma caritativa que se curra lo que sea y lo pone a nuestra disposición. ¡¡Gracias, Gracias!!   

Enseguida encontré la página de Arduino Learning   que tenía un tutorial sobre este chisme y que usaba una librería para manejarlo, de forma cómoda esperaba yo. Me puse a estudiar el tema y aunque me daba todas las claves para manejarlo incluida la librería, ésta no ayudaba mucho a la hora de disponer de alguna función del tipo print (“83456.2”) y solo disponía de funciones rudimentarias para imprimir digito a digito. Bien, pues me toca currarme las funciones que impriman algo en el display de la forma que a mi me gusta, para vagos, y de eso va la sesión de hoy. Porque la verdad es que son unos displays de lo más útil si el tamaño del display LCD de 2 líneas se te queda corto y necesitas 8 dígitos (O más)

 

Conectando el display a nuestro Arduino

 

La conexión es trivial. El display cuenta con 5 pines para el control de lo que muestra, y la conexión se debe hacer algo así:

 

DisplayVCCGNDDINCISCLK
Arduino5VGND121011
Esquema de conexion

Aunque en esta sesión solo vamos a usar uno de estos displays, podríamos conectar en cascada hasta 8 de estas unidades sin tocar la librería, sin mas que unir los pines de salida de uno del display al siguiente (Aunque no se ve muy claro en la imagen de arriba, a la derecha del display están repetidos los conectores de entrada para hacer la conexión en cadena)

 

Programando el display

 

Empezaremos descargando la librería pertinente en Github: wayoda/LedControl , Y para los que tengan interés, aquí está la documentación de la libreríaEn líneas generales las funciones del display son bastante sencillas. Empezamos con:

#include "LedControl.h"
LedControl lc=LedControl(12,11,10,1); 
// (DIN, CLK, CS, Numero de displays en cascada)

La primera incluye la librería y la segunda crea una instancia del display, Indicando los pines Arduino a los que van los del display en que está conectado y el numero de displays en línea.

En el setup(), encendemos el display, fijamos el brillo y borramos el contenido.

void setup()
  { Serial.begin(115200);
    // the zero refers to the MAX7219 number, it is zero for 1 chip
    lc.shutdown(0,false);      // Apaga el ahorro de energia
    lc.setIntensity(0,5);      // Pone el brillo a  (0~15 possible values)
    lc.clearDisplay(0);        // clear screen
  }

Si queremos mostrar un número entero en el display, resulta que no disponemos de funciones para ello, sino que parece que solo disponemos de una función:

lc.setDigit(disp,pos,valor,false);

Donde disp es el número de orden del display en la cadena con 0 para el primero, nuestro caso. Pos representa el número de dígito que queremos imprimir con 0 el mas a la derecha (Las unidades), después valor representa el dígito a mostrar ( de 0 a 9) y por ultimo el false es que el display este encendido. Así, por ejemplo, para mostrar un dígito 7 en la tercera posición (Los miles):

lc.setDigit(0,3,7,false);

Como todo esto es un poco rollo, pensé que sería más cómodo (Pero que mucho más cómodo) hacer un par de funciones que se puedan usar de forma similar al print y a cascarla. Por eso vamos a escribir una función que imprima números enteros en el display.

¿Cómo podemos hacer una función, del tipo displayInt( long N) a la que pasamos un entero long y se encargue de toda la mandanga de descomponer el numero en sus dígitos y posicionarlo en el display? Piensa un poco. ¿Cómo lo harías? Estas a tiempo antes de seguir leyendo.

 

 Procedimiento para calcular los dígitos de un numero entero  

El truco básico puede ser calcular el resultado entero (Despreciando decimales) de un número dividido por 10, lo que nos da todas las cifras menos la primera y a su vez, la primera cifra es el resto de esa misma división. UUUUUyyyy , que lio!!! Tranquilos, es una tontería. Imagina un número como el 34279. Hagamos un ejemplo.

34.279 / 10 --> 3.427 Despreciando los decimales
 34.279 % 10 --> 9    El dígito de las unidades

Si escribimos esto e C++ podría quedar así:

 long r, n = N ;    // Long es un entero de doble tamaño
 int pos = 0 ;
 r = n % 10 ;
 n = n / 10

Con esto habremos guardado el dígito de las unidades en r y en n conservamos la división entera entre 10. Si hacemos un bucle que continúe mientras n> 0 (Mientras queden dígitos) obtendremos una función como esta:

void displayInt( long N)
   {  long r, n = N ;
      int pos = 0 ;
      lc.clearDisplay(0);// clear screen
      while ( n >0 )
        { r = n % 10 ; 
          n = n / 10 ;
          lc.setDigit(0,pos++,r,false);
        }
   }

La única línea nueva es la imprime cada dígito en secuencia:

lc.setDigit(0,pos++,r,false);

La variable pos empieza con valor cero, apuntando a la posición de las unidades, la más a la derecha del display, imprime el valor en r (Unidades en la primera iteración), después incrementamos pos (con pos++) con lo que en la próxima vuelta apuntamos al segundo digito (Las decenas) y así sucesivamente. Tampoco era para tanto,

Podemos hacer una pequeña prueba con este programa: displayInt 

Salida a consola arduino

Parece que va todo bien. Descompone los números de menor a mayor peso, que es el orden en el que los iremos imprimiendo (De derecha a izquierda en lugar del orden normal al escribir)

 

Calculando los dígitos de un numero con decimales 

 

Descomponer un entero es un poco más fácil que descomponer un número float con decimales, porque necesitamos separar la parte entera (Que ya sabemos como imprimir en el display) de la parte con decimales tras la coma.

Además, lo lógico en un número con decimales (Para mi otro proyecto) es que pueda elegir el numero de dígitos que necesitemos tras la coma. Por eso la nueva función displayFloat() debería recibir dos parámetros. Primero el numero en cuestión a representar y un segundo valor con el numero de decimales requeridos. Podemos intentar algo así: Calculamos un entero k, como la potencia de 10 del número de decimales que nos piden (10^2 para dos, 10^3 para tres… etc). De este modo, si tomamos el numero dado N y lo multiplicamos por k lo hemos convertido en un entero, cuyas últimas cifras son los decimales que queremos. Si hacemos la división entera(Sin decimales) de (N * k )/k, tendremos los dígitos antes de la coma. A su vez (N-p)*k será un entero que representa las cifras tras la coma.

Y si hacemos (N – p) *k conseguiremos un entero de la parte tras la coma como número entero. Hagamos una prueba con un número, por ejemplo 256,8354, para tres decimales tendríamos:

La parte entera p= 256,8354 * 1000) / 1000 = (256835,4/1000)1000 = 256.835,4 /1000

La división entera de 256.83,54 /1000 sale 256 que corresponden a los números antes de la coma.  Para calcular la parte decimal como un entero: (256,8354 – 256) * 1000 = 835,4 y su parte entera será 835. Es mucho más largo explicarlo en palabras que hacerlo en código C++:

Contenido solo disponible para suscriptores. ¡Accede al contenido!

      

Aquí os dejo un mini video con el resultado y usando el generador aleatorio de la puerta analógica:

https://youtu.be/UXl7VViHjLk

 

 

IMAGEN DE MARCA