El día de San Valentín solemos regalar flores, tarjetas o dulces. Los pequeños regalos siempre quedan bien. Este año se nos ocurrió un pequeño proyecto para el que nuevamente usamos la pantalla de matriz de puntos de 8x32. Si quieres recrear a la novia de AZ para el Día de San Valentín, echa un vistazo a la Publicación de blog del año pasado.
Dado que el día de San Valentín tiene un gran significado para muchos enamorados y el amor también se basa en la cercanía, este año estamos usando un Sensor de Proximidad. Probablemente esté familiarizado con esto: se acerca mucho a alguien que es muy importante para usted, su pulso se eleva y se comienza a emocionar. Queremos simular eso con el proyecto de este año. Mostramos dos animaciones en la pantalla, que cambian cuando se acerca al sensor. El pulso se acelera y la luz roja de los LED representa el aumento del calor. Comencemos.
Lo que necesitamos
Número | Componente |
---|---|
1 | Módulo LED de matriz de puntos MAX7219 8x32 4 en 1 |
1 | Nano V3.0 100% compatible con Arduino o |
1 | ESP8266 D1 Mini o |
1 | ESP32 Devkit C V4 |
1 | Sensor de distancia ToF VL53L0X |
Cables de salto | |
Tablero de circuitos | |
PC con Arduino IDE y conexión a Internet |
Usted es libre de elegir el microcontrolador. El código fuente funciona en los UNO comunes, Nanos, ESP8266, ESP32. Solo tiene que prestar atención al pinout respectivo. Los pines a los que están conectados el sensor ToF y la pantalla de matriz se especifican mediante las interfaces I²C o SPI.
Nota: La pantalla matricial debe alimentarse con 5V. Algunos ESP32 no ofrecen una salida con este voltaje. Entonces necesitas un fuente de voltaje externao utilice otro microcontrolador.
Diagramas de circuitos
Microcontrolador Nano o UNO:
ESP8266 (aquí D1 Mini):
ESP32 (aquí Devkit C V4):
El sensor ToF se conecta de la siguiente manera:
VL53L0X |
Nano / UNO |
VIN |
5 V o 3,3 V |
GND |
GND |
SCL |
SCL (A5) |
SDA |
SDA (A4) |
GPIO1 |
- |
XSHUT |
- |
VL53L0X |
ESP8266 D1 Mini |
VIN |
5 V o 3,3 V |
GND |
GND |
SCL |
SCL (D1 / GPIO5) |
SDA |
SDA (D2 / GPIO4) |
GPIO1 |
- |
XSHUT |
- |
VL53L0X |
ESP32 |
VIN |
5 V o 3,3 V |
GND |
GND |
SCL |
SCL (GPIO 22) |
SDA |
SDA (GPIO 21) |
GPIO1 |
- |
XSHUT |
- |
La pantalla de matriz está conectada de la siguiente manera, por lo que el pin CS se puede seleccionar libremente. Sin embargo, el pin SS o MISO no debe usarse para esto (información del código fuente de la biblioteca LEDMatrixDriver):
Pantalla matricial MAX7219 |
Nano / UNO |
VCC |
5V |
GND |
GND |
ESTRUENDO |
MOSI (D11) |
CS |
D9 |
CLK |
SCK (D13) |
Pantalla de matriz MAX7219 |
ESP8266 D1 Mini |
VCC |
5V |
GND |
GND |
ESTRUENDO |
MOSI (D7, GPIO 13) |
CS |
D3 (GPIO 0) |
CLK |
SCK (D5, GPIO 14) |
Pantalla de matriz MAX7219 |
ESP32 |
VCC |
5V |
GND |
GND |
ESTRUENDO |
MOSI (GPIO 23) |
CS |
GPIO 32 |
CLK |
SCK (GPIO 18) |
Bibliotecas
Cómo utilizar el sensor ToF VL53L0X ya se describió en el serie de blogs correspondiente descrito. Como biblioteca utilizo el VL53L0X.h de Pololu:
Puede utilizar varias bibliotecas para controlar la visualización de la matriz. En el blog Mostrar caracteres individuales en la pantalla de matriz Albert Vu le muestra cómo hacer MD_Parola Biblioteca (resp. MD_MAX72xx) utilizar. Esto proporciona un arsenal muy extenso de códigos fuente de muestra. en el Patio de juegos Arduino se convierte en la biblioteca LEDControl descrito. Elegí la biblioteca LEDMatrixDriver decidió y usó el código de ejemplo del DrawSprites.ino usado:
Se necesita otra biblioteca debido a que los valores del sensor deben llevarse a una relación de valores diferente para el brillo de los LED y la velocidad de la animación. Por lo general, puede usar la función incluida para esto mapa (). Sin embargo, su ejecución es muy lenta. La biblioteca FastMap crea una solución:
Función de programa
Usamos una pantalla matricial que se compone de cuatro segmentos, cada uno con 8x8 LED (puntos). Se debe mostrar un corazón pulsante en el primer segmento. Los otros tres segmentos muestran un pico de EKG animado. Dependiendo de la distancia al sensor, el corazón comenzará a latir más rápido o más lento, los LED empezarán a iluminarse con más brillo o más oscuro y la punta del ECG también deberá funcionar más rápido o más lento.
Código fuente
Obtuve del ejemplo soltero la biblioteca de sensores ToF, el código de muestra DrawSprites.ino Se creó una base a partir de la biblioteca LEDMatrixDriver y el código de demostración FastMap para poder implementar un programa adecuado para nuestro proyecto.
En primer lugar, se necesitan mapas de bits para representar el corazón que late. También una imagen para la punta de EKG. Por supuesto, debido a la baja resolución de imagen de 8x8 píxeles, la calidad de las imágenes es limitada, pero apreciará lo que es.
en el Entrada de blog de Albert Vu encontrará una plantilla para crear matrices de mapas de bits. Tengo el generador en línea en este sitio web usado. Alternativamente, también hay este sitio web en adelante, puede crear varios mapas de bits y generarlos como una matriz. Haces clic en tus imágenes juntas y luego simplemente copias el código fuente.
Puede descargar el boceto terminado para el IDE de Arduino aquí: descarga directa
Descripción detallada del programa
En este punto, se va a dar un vistazo más de cerca al código fuente. Después de la inclusión de las bibliotecas se continúa con definir la configuración del sensor ToF. Dado que confiamos en altas velocidades en este proyecto, se utiliza el Modo ALTA VELOCIDAD. El rango de medición máximo se limita entonces a aproximadamente 60 cm. Pero eso se puede mejorar. El siguiente paso es verificar si el microcontrolador configurado (a través del menú Herramientas -> Tablero) es un AVR (UNO, Nano), ESP8266 o ESP32. También agregué los pines para la interfaz SPI (para la pantalla de matriz) como comentarios. El pin CS, que se puede seleccionar libremente, también se define aquí.
Luego se determina el tamaño de la pantalla. Usamos cuatro segmentos con 8 píxeles cada uno de ancho y alto. Estos valores luego se utilizan para la instancia de LEDMatrixDriver.
A esto le siguen las declaraciones y definiciones de los mapas de bits. Para una mejor legibilidad, lo he creado en forma binaria. La punta de EKG es una matriz de un solo byte. El corazón que late es una matriz de bytes bidimensional. Eso permite que sea más fácil iterar sobre él con un bucle. Así es como creamos la animación del corazón que late.
Las diversas variables siguen a continuación: intens_min y intens_max están determinados por la biblioteca LEDMatrixDriver. El brillo de los LED se puede ajustar en 10 niveles. Sin embargo, 0 no significa que un LED esté apagado. Solo representa el valor de brillo más bajo posible.
heartBeatDelayDefault Especifica la velocidad a la que la animación debe ejecutarse lentamente si no hay ningún objeto cerca. heartBeatDelayMin es la velocidad más rápida. Con HEART_ANIM_DELAY puede ajustar la velocidad del corazón que late.
Las dos instancias de objeto FastMap mapper_heartBeat y FastMap mapper_intensity convierta los valores del sensor entrante en la velocidad de la animación de ECG o el brillo del LED para nosotros.
Tomé la función drawSprite () del código fuente de ejemplo. Muestra el mapa de bits en la pantalla.
en el preparar() se inicializan la interfaz I²C, el sensor ToF y el fastMapper. Además, se establece el modo para el sensor ToF y el rango de valor máximo se define como una variable en base a esto. Entonces se activa la pantalla.
En el lazo () función se comprueba si hay un sensor ToF conectado. De lo contrario, la velocidad y el brillo de la animación cambiarán con los valores predeterminados. Entonces sería posible probar el programa sin un sensor. Si desea conectar un tipo diferente de sensor, debe cambiar o eliminar la consulta en este punto. ¿Hay un sensor (isToFpresent)?, esto se lee. Con el valor de distancia devuelto, se decide si se establece la velocidad estándar o una nueva velocidad de animación. Lo mismo ocurre con el brillo de los LED. A continuación, sigue la animación de la punta de ECG. Esto es ininterrumpido (sin retraso () función) programada. Por el principio, recomiendo el proyecto de muestra. Parpadeo sin demora. El bucle principal pasará sin cesar a la velocidad más rápida posible. A continuación, se detiene el tiempo y se compara con el que hemos fijado previamente. Si se alcanza, la parte del programa se ejecuta en la consulta if. Aquí se muestra la punta de ECG en la pantalla. Para que podamos ver el movimiento, el valor de X se incrementa, es decir, se cuenta. Entonces, nuestro símbolo se desplaza un píxel a la derecha con cada ejecución. Si se excede el ancho máximo de la pantalla, la posición X se restablece al valor inicial. También construí un interruptor en este punto que controla la animación de los latidos. Esto solo debe realizarse una vez. Luego se bloquea y solo se libera cuando la punta ha pasado. Entonces todo se comienza a repetir.
La animación del corazón que late funciona de manera similar. Aquí el tiempo entre los mapas de bits individuales (el corazón aparece, se vuelve más grande, luego se vuelve más pequeño y desaparece) es constante. Para que el corazón comience a latir más rápido (al mismo ritmo que el pico del ECG), esta animación se produce cuando también comienza el pico del ECG. De ahí el cambio en el anterior Si-Consulta. Sin esta implementación, el corazón seguiría latiendo. De esta forma conseguimos una animación fluida y así el corazón puede latir a distintas velocidades en función de la distancia al sensor.
Leer el sensor y todos los demás comandos requiere su tiempo. Dado que la animación en la pantalla depende de ello, el tiempo no debería ser demasiado largo. Por eso intenté optimizar el programa en términos de tiempo. Primero que nada, por supuesto, los tengo en Función retraso ()-Función prohibida en los ejemplos. De lo contrario, haría que el sensor se lea solo cuando haya expirado el tiempo. Tuve lugar largo- principalmente En tVariables porque el procesador puede procesarlas más rápidamente. En realidad, esto es un poco complicado, porque millis () Función realmente allí largo sin firmar espalda. Tengo el sensor ToF encendido ALTA VELOCIDAD ajustado, incluso si el rango de medición es más corto. Además, tengo que escalar los valores del sensor a la velocidad y el brillo en lugar del mapa ()- la fastMap ()-Función utilizada. Como resultado, aparece una animación muy útil en la pantalla. Cuando considera que solo un procesador puede hacer todo, eso es bastante bueno. Por supuesto, eso también depende del microcontrolador utilizado.
Echa un vistazo a cómo queda el proyecto Valentine montado al final en este breve vídeo:
Posibles extensiones
También es posible utilizar otros sensores de distancia como el Sensor ultrasónico HC-SR04 o utilizar un sensor de distancia por infrarrojos. Usted da los valores medidos al fastMap ()-Función. Puede que tenga que configurar los rangos de medición (minRange y rango máximo) ajustar.
Los valores escalados del sensor también se pueden invertir, de modo que la velocidad sea más lenta a una distancia pequeña o más rápida a una distancia mayor. Para hacer esto, puede conectar un interruptor a uno de los pines digitales, por ejemplo, para cambiar entre los dos modos "recién enamorado" y "casado durante 40 años". Sin un interruptor, solo necesita cambiar estas dos líneas para que las variables de destino se intercambien:
previamente:
mapper_heartBeat.init (minRange, maxRange, heartBeatDelayMin, heartBeatDelayDefault);
mapper_intensity.init (minRange, maxRange, intens_max, intens_min);
más tarde:
mapper_heartBeat.init (minRange, maxRange, heartBeatDelayDefault, heartBeatDelayMin);
mapper_intensity.init (minRange, maxRange, intens_min, intens_max);
Te deseamos un feliz San Valentín.
Andreas Wolter
para Blog AZ-Delivery
4 comentarios
Andreas Wolter
@Andy
@Florian
Thank you for your advice / Danke für Euren Hinweis.
(english below)
Für eine flüssigere Animation hatte ich die Variablen als “int” deklariert. Das ist etwas unsauber, denn millis() gibt unsigned long zurück. Wie Andy schon bemerkt hat, ist der Wertebereich wesentlich kleiner und somit kann die Zeit nicht mehr verglichen werden. Ich habe nun die Deklaration folgendermaßen geändert:
// millis for nonblocking Animation
unsigned long animZeit = 0;
unsigned long heartAnimZeit = 0;
Alle anderen Variablen bleiben int. Das ist immer noch unsauber, da kein ordentlicher Typecast durchgeführt wird. Das nehme ich in Kauf, damit die Animation flüssig bleibt. Die Arduino IDE hilft da ein wenig nach.
Es sollte nun funktionieren.
Ich wünsche einen schönen Valentinstag.
English:
For a smoother animation, I had declared the variables as “int”. This is a bit messy, because millis() returns unsigned long. As Andy has already noticed, the value range is much smaller and thus the time can no longer be compared. I have now changed the declaration as follows:
// millis for nonblocking animation
unsigned long animTime = 0;
unsigned long heartAnimTime = 0;
All other variables remain int. This is still messy, as no proper typecast is performed. I put up with this to keep the animation smoothly. The Arduino IDE helps a little.
It should work now. Have a nice Valentine’s Day.
Andreas
Florian
Hallo,
das gleiche Problem wie Andy schrieb habe ich auch: nach etwa 1 Minute läuft die Animation auf voller Geschwindigkeit. Die Helligkeit funktioniert wie vorher unverändert. Gibt es dafür eine Lösung?
Gruß
Florian
Andy
I love this and have made it for my wife on Valentines day, but it seems that after a minute of so the heartbeat animation always runs at full speed, this seems to correspond with the variables heartAnimZeit and animZeit exceeding 65535 and resetting to zero I have this happen after a longer period my making them unsigned long but I’d be grateful to see if it is possible to correct this somehow?
Angelo De Lucia
Molto bello il progetto, spiegato molto bene.
Complimenti , grande lavoro , grandissimi.