Tabla de contenido:
- Paso 1: Cómo funciona todo: Explicación de las opciones de diseño
- Paso 2: Partes: el cerebro: microcontrolador y pantalla
- Paso 3: Piezas - Óptica: Encontrar un compromiso
- Paso 4: Piezas: un contenedor para contenerlas todas
- Paso 5: creación de un protocolo para nuestro módulo
- Paso 6: El código: ESP32 Side
- Paso 7: el código: lado de Android
- Paso 8: ¿Qué sigue?
- Paso 9: Conclusión y agradecimiento especial
Video: Prototipo de HUD de motocicleta inteligente (navegación paso a paso y mucho más): 9 pasos
2024 Autor: John Day | [email protected]. Última modificación: 2024-01-30 08:40
Hola !
Este Instructables es la historia de cómo diseñé y construí una plataforma HUD (Heads-Up Display) diseñada para montarse en cascos de motocicleta. Fue escrito en el contexto del concurso de "mapas". Lamentablemente, no pude terminar completamente este proyecto a tiempo para la fecha límite del concurso, pero aún quería compartir mi progreso en él, así como documentar todas las pruebas y errores que obtuve al hacerlo.
La idea de este proyecto se me ocurrió por primera vez hace unos años, cuando me metí en las motocicletas, y estaba empezando a buscar qué equipo necesitaría comprar para que mis viajes fueran más agradables. En ese momento, me desconcertó que la mejor manera de obtener un poco de navegación GPS básica mientras conducía era básicamente conectar su teléfono inteligente al manillar de su bicicleta. Pensé para mí mismo que seguramente, podría haber una mejor manera de obtener ese tipo de información sobre la marcha.
Ahí fue cuando me di cuenta: una pantalla de visualización frontal podría ser la forma de obtener navegación mientras conduce, sin vaciar la batería de su teléfono y exponerlo a los elementos.
Con el tiempo, esta idea maduró en mi mente, y pensé que tener un HUD frente a mí en todo momento permitiría muchos más usos que la simple navegación. Es por eso que mi plan es hacer que la plataforma sea pública y modular, para que cualquiera pueda crear un módulo que muestre la información que necesita en su propio HUD.
Aunque existen productos disponibles comercialmente que cumplen con esta tarea, no hay ninguno que sea tan modular como mi plataforma, y también suelen ser un poco caros. De todos modos, bienvenido a este proyecto.
Que funciona a partir de ahora
Como se dijo, este proyecto aún se encuentra en un estado de desarrollo, y esto es lo que está funcionando actualmente.
- Comunicación entre un teléfono inteligente y una placa basada en ESP32 (teléfono activo)
- Diseño óptico hecho (puede necesitar pequeños ajustes a largo plazo)
- Aplicación de navegación para Android que utiliza el SDK de navegación Mapbox:
- Capaz de calcular y mostrar la posición del usuario en un mapa, así como una ruta desde este hasta el destino
- Capaz de conectarse a un dispositivo Bluetooth (la dirección MAC del dispositivo está codificada a partir de ahora)
- Capaz de navegación en tiempo real, incluida la extracción y el envío de la información de la próxima maniobra a través de Bluetooth en serie (solo admite giros por ahora)
Que necesita trabajo
Esta lista contiene elementos que son absolutamente necesarios para el uso previsto del HUD, pero que aún no están listos para implementarse.
- Diseño general (accesorio de casco, mecanismo de ajuste del ángulo del reflector,..)
- Aplicación Android:
- Implementar detección y corrección fuera de ruta
- Capacidad para que el usuario ingrese la dirección de destino
- ¿Waypoints?
- Ergonomía / Estética
Suministros:
Esenciales
- Una placa de desarrollo basada en esp32
- Cualquier teléfono inteligente Android algo reciente (habilitado para Bluetooth)
- Un SSD1306 u otra pantalla OLED de 96 "habilitada (la mía era de 128x64 píxeles, consulte la parte" El cerebro: microcontrolador y pantalla ")
- Un reflector (cualquier pieza de acrílico / vidrio / plexiglás servirá)
- Una lente Fresnel (la mía tenía una longitud F. de aproximadamente 13 cm, consulte la sección "Elección de la lente")
Instrumentos
- Soldador
- Tablero de pruebas
- Algunos cables de puente
- Impresora 3d / servicio de impresión 3d
Paso 1: Cómo funciona todo: Explicación de las opciones de diseño
La idea básica de un Heads Up Display es mostrar una imagen frente a la visión de alguien, para que no tenga que apartar la mirada de lo que sea que esté haciendo (ya sea pilotar un avión o conducir una motocicleta, que será nuestra caso de ejemplo).
Óptica
Técnicamente, esto podría lograrse colocando directamente una pantalla frente a los ojos del usuario. Sin embargo, una pantalla no es transparente y, por lo tanto, dificultaría la visión del usuario. Luego, podría colocar la pantalla frente a una superficie reflectante, que reflejaría el contenido de la pantalla y al mismo tiempo sería lo suficientemente transparente como para que el usuario pudiera ver lo que está frente a él.
Sin embargo, este enfoque tiene un gran defecto: la pantalla real suele estar más cerca de los ojos del usuario de lo que el usuario realmente tiene que enfocar (por ejemplo, la carretera que tiene por delante). Esto significa que, para leer lo que hay en la superficie reflectante, los ojos del usuario tendrían que adaptarse a la distancia de la pantalla a sus ojos (digamos 20 cm), y luego tendrían que adaptarse nuevamente para poder enfocarse en la carretera por delante. (~ 2/5 metros). El tiempo que lleva toda esta operación es un tiempo precioso que debe dedicarse a mirar la carretera, y adaptarse con frecuencia puede resultar incómodo para el usuario después de unos minutos.
Por eso decidí agregar una lente entre la pantalla y el reflector. Esta lente, si se elige con cuidado, debería permitir la creación de una imagen virtual de la pantalla (ver el esquema de arriba), que luego parecería estar más lejos de los ojos del usuario como realmente es, requiriendo adaptaciones menos abruptas (o ninguno en absoluto, en un escenario perfecto). Este diseño permite al usuario echar un vistazo rápidamente al reflector, obtener la información que necesita y mirar instantáneamente hacia la carretera.
El papel del teléfono inteligente
Debido a que no era realista intentar implementar una aplicación de navegación completa solo en el ESP32, decidí hacer una aplicación para Android que se encargara de esto. La aplicación solo necesitaría decirle al ESP32 qué tiene que hacer el usuario para llegar a su destino, y el ESP32 transmite esa información a través del HUD (consulte la figura "Cómo funciona el módulo").
Paso 2: Partes: el cerebro: microcontrolador y pantalla
Como se indicó anteriormente, planeé que mi módulo muestre información de navegación, sin que en realidad calcule el posicionamiento real, el seguimiento y la navegación en tiempo real. En cambio, el teléfono del usuario se comunicaría con el módulo y le enviaría la información para que luego se muestre en el HUD.
Para facilitar la comunicación entre el teléfono del usuario y el módulo, elegí usar una placa basada en ESP32 para este proyecto. Esta elección se debió a que este módulo específico tenía capacidades Bluetooth integradas, así como algunas otras especificaciones interesantes (almacenamiento no volátil fácil de usar, CPU de doble núcleo, suficiente RAM para manejar la pantalla OLED a través de I2C,…). Es relativamente simple diseñar PCB basados en el ESP32, lo cual sí tomé en cuenta. También tengo experiencia profesional en el uso y diseño de circuitos con el ESP32, lo que definitivamente influyó en mi elección.
La elección de la pantalla básicamente se redujo a lo que pude encontrar y que, en mi opinión, sería lo suficientemente brillante para su uso y, al mismo tiempo, lo más pequeño posible. No estaba muy preocupado por la cantidad de píxeles de la pantalla, ya que mi objetivo era tener una interfaz de usuario muy minimalista y simple.
Cabe señalar que el controlador de pantalla debe ser compatible con una biblioteca que permita la duplicación de imágenes. Esto se debe a que la imagen mostrada se voltea cuando pasa a través de la lente y aparece en el reflector, y no tener que invertir manualmente lo que se muestra es un gran peso de nuestros hombros como constructores.
Paso 3: Piezas - Óptica: Encontrar un compromiso
La óptica de este proyecto fue bastante difícil de abordar, ya que no tenía ni idea de lo que estaba buscando cuando comencé este proyecto. Después de investigar un poco, comprendí que lo que quería hacer era crear una "imagen virtual" de mi pantalla OLED, que parecería estar más lejos del ojo de lo que realmente está. La distancia ideal para que se forme esta imagen virtual sería alrededor de 2-5 metros por delante del conductor, una parece ser la distancia a los objetos en los que nos enfocamos cuando conducimos (otros coches, baches en la carretera, etc …).
Para lograr ese objetivo, elegí usar una lente Fresnel, ya que son bastante grandes, baratas, parecen ofrecer una distancia focal lo suficientemente buena para mi proyecto y se pueden cortar con simples tijeras (que no es el caso de lentes de vidrio de forma redonda más refinadas). Las lentes de Fresnel se pueden encontrar con nombres como "lupa de bolsillo" o "lupa de lectura de tarjetas", ya que son muy apropiadas para ayudar a las personas con mala vista a leer.
Básicamente, el truco aquí consistía en encontrar el compromiso correcto entre:
- Tener una distancia de imagen virtual razonable (es decir, qué tan lejos le parecerá el HUD al usuario, o qué tan lejos tendrá que ajustar sus ojos para ver lo que hay en el HUD)
- Hacer que el texto en la pantalla no sea demasiado ampliado por la lente (que es básicamente una lupa)
- Tener una distancia razonable entre la pantalla OLED y la lente, que de otro modo daría lugar a un módulo muy voluminoso
Personalmente pedí algunas lentes diferentes en Amazon y determiné sus respectivas distancias focales, antes de elegir una con una longitud F. de aproximadamente 13 cm. Encontré que esta longitud F., con una distancia de lente OLED de 9 cm, me dio una imagen satisfactoria en mi reflector (vea las últimas imágenes arriba).
Como verás en mis ilustraciones, para poder enfocar correctamente el texto mostrado, la cámara utilizada para tomar estas fotos tiene que ajustarse como si estuviera enfocando un objeto lejano, lo que hace que todo en el mismo plano que el reflector parezca borroso.. Esto es exactamente lo que queremos para nuestro HUD.
Puede encontrar los archivos 3d para el soporte de la lente aquí.
Paso 4: Piezas: un contenedor para contenerlas todas
Mientras escribo este Instructables, el contenedor real que contendrá cada pieza de la pantalla de visualización frontal no está del todo diseñado. Sin embargo, tengo algunas ideas sobre su forma general y sobre cómo abordar ciertos problemas (como cómo mantener quieto un reflector y hacer que resista vientos de más de 100 km / h). Esto todavía es un trabajo en progreso.
Paso 5: creación de un protocolo para nuestro módulo
Para enviar las instrucciones de navegación desde el teléfono a la placa de desarrollo, tuve que idear un protocolo de comunicación propio que me permitiera enviar fácilmente los datos requeridos desde el teléfono, al mismo tiempo que facilitaba su procesamiento una vez recibidos.
Al momento de escribir este Instructables, la información que se necesitaba transmitir desde el teléfono para poder navegar con el módulo era:
- El tipo de la próxima maniobra (giro simple, rotonda, incorporarse a otra carretera,…)
- Las instrucciones precisas de la próxima maniobra (dependiendo del tipo de maniobra: derecha / izquierda para girar; qué salida tomar para una rotonda,…)
- La distancia restante antes de la próxima maniobra (en metros por ahora)
Decidí organizar estos datos usando la siguiente estructura de marco:
: tipo.instrucciones, distancia;
Si bien no es una solución hermosa, esta nos permite separar y distinguir fácilmente cada campo de nuestro protocolo, lo que facilitó la codificación en el lado ESP32.
Es importante tener en cuenta que, para funciones futuras, es posible que se deba agregar otra información a este protocolo (como el día y la hora exactos, o la música que se reproduce en el teléfono del usuario), lo que sería fácilmente factible usando el mismo construyendo lógica como ahora.
Paso 6: El código: ESP32 Side
Actualmente, el código del ESP32 es bastante simple. Utiliza la biblioteca U8g2lib, que permite un fácil control de la pantalla OLED (al mismo tiempo que permite la duplicación de la imagen mostrada).
Básicamente, todo lo que hace el ESP32 es recibir datos en serie a través de Bluetooth cuando la aplicación los envía, analizarlos y mostrar estos datos o imágenes en función de estos datos (es decir, mostrar una flecha en lugar de la frase "girar a la izquierda / derecha"). Aquí está el código:
/ * Programa para controlar un HUD desde una aplicación de Android a través de bluetooth en serie * / # include "BluetoothSerial.h" // Archivo de encabezado para Bluetooth en serie, se agregará de forma predeterminada en Arduino # include #include #ifdef U8X8_HAVE_HW_SPI # include # endif # ifdef U8X8_HAVE_HW_I2C # include # endif // Constructor de biblioteca OLED, debe cambiarse de acuerdo con su pantallaU8G2_SSD1306_128X64_ALT0_F_HW_I2C u8g2 (U8G2_MIRROR, / * reset = * / U8X8_PIN_NONE); // Estado de la máquina de valores de campo_detectado + variable # definir maniobraField 1 # definir campo de instrucciones 2 # definir campo de distancia 3 # definir endOfFrame 4int campo_detectado = endOfFrame; BluetoothSerial serialBT; // Objeto para Bluetoothchar. = 0; int nbr_char_distance = 0; boolean fullsentence = false; void setup () {Serial.begin (9600); // Iniciar el monitor serial en 9600 baudios u8g2.begin (); // Iniciar control OLED serialBT.begin ("ESP32_BT"); // Nombre del retardo de la señal Bluetooth (20); Serial.println ("El dispositivo Bluetooth está listo para emparejarse");} void loop () {if (serialBT.available () &&! Fullsentence) // Caracteres que se reciben a través de Bluetooth serial {entrante_char = serialBT.read (); Serial.print ("Recibido:"); Serial.println (entrante_char); } switch (campo_detectado) {caso maniobraField: Serial.println ("Campo detectado: maniobra"); if (entrante_char == '.') // Siguiente campo detectado {campo_detectado = campo_instrucciones; } else {// Completa el tipo de maniobra info array maniobra [nbr_char_maneuver] = entrante_char; nbr_char_maneuver ++; } rotura; case instructionsField: Serial.println ("Campo detectado: instrucciones"); if (entrante_char == ',') // Siguiente campo detectado {campo_detectado = campode distancia; } else {// Llena la matriz de instrucciones de instrucciones. instrucciones [nbr_char_instructions] = entrante_char; nbr_char_instructions ++; } rotura; case distanceField: Serial.println ("Campo detectado: distancia"); if (entrante_char == ';') // Fin de la trama detectado {campo_detectado = endOfFrame; Serial.print ("maniobra:"); Serial.println (maniobra); Serial.print ("instrucciones:"); Serial.println (instrucciones); Serial.print ("distancia:"); Serial.println (distancia); fullsentence = verdadero; update_Display (); // Cuadro completo recibido, analizarlo y mostrar los datos del receptor} else {// Completar la matriz de información de distancia distancia [nbr_char_distance] = entrante_char; nbr_char_distance ++; } rotura; case endOfFrame: if (entrante_char == ':') campo_detectado = campo_de_ maniobra; // Nueva trama detectada ruptura; default: // No hacer nada romper; } delay (20);} void update_Display () {// Almacene en caché cada matriz de caracteres para evitar posibles conflictos memcpy (tempManeuver, maniouver, nbr_char_maneuver); memcpy (tempInstructions, instrucciones, nbr_char_instructions); memcpy (tempDistance, distancia, nbr_char_distance); parseCache (); // Analizar y procesar matrices de caracteres fullsentence = false; // Sentencia procesada, lista para la siguiente} void parseCache () {u8g2.clearBuffer (); // borra la memoria interna u8g2.setFont (u8g2_font_ncenB10_tr); // elige una fuente adecuada // matrices de caracteres -> cadena obligatoria para usar la función substring () String maniobraString = tempManeuver; String instruccionesString = tempInstructions; // Implementando el protocolo aquí. Solo admite giros por ahora. if (maneuverString.substring (0, 4) == "turn") {// Verifica el tipo de maniobra Serial.print ("TURN DETECTED"); if (instructionsString.substring (0, 5) == "right") {// Verifique las instrucciones específicas y visualice en consecuencia u8g2.drawStr (5, 15, "-"); } else if (instructionsString.substring (0, 4) == "left") {// Verifique las instrucciones específicas y visualice en consecuencia u8g2.drawStr (5, 15, "<---"); } else u8g2.drawStr (5, 15, "Err."); // Campo de instrucciones no válido} / * Implementar otros tipos de maniobras (rotondas, etc.) * else if (tempManeuver == "rdbt") {* *] * / u8g2.drawStr (5, 30, tempDistance); // Muestra la distancia restante u8g2.sendBuffer (); // transferir la memoria interna a la pantalla // Restablecer todas las matrices de caracteres antes de la siguiente lectura memset (maniobra, 0, 10); memset (instrucciones, 0, 10); memset (distancia, 0, 10); memset (tempManeuver, 0, 10); memset (tempInstructions, 0, 10); memset (tempDistance, 0, 10); // Restablecer el número de elementos en las matrices nbr_char_distance = 0; nbr_char_instructions = 0; nbr_char_maneuver = 0;}
Paso 7: el código: lado de Android
Para la aplicación de teléfono inteligente, decidí usar el SDK de navegación de Mapbox, ya que ofrece muchas funciones útiles cuando se trata de crear un mapa de navegación desde cero. También permite el uso de muchos oyentes útiles, que definitivamente ayudan a que este módulo funcione. También utilicé la biblioteca android-bluetooth-serial de harry1453 para Android, ya que hizo que la comunicación en serie Bluetooth fuera mucho más fácil de armar.
Si desea crear esta aplicación en casa, deberá obtener un token de acceso Mapbox, que es gratuito hasta una cierta cantidad de solicitudes por mes. Tendrá que poner este token en el código y crear la aplicación de su lado. También deberá codificar la dirección MAC de Bluetooth de su propio ESP32.
Tal como está, la aplicación puede guiarlo desde su ubicación actual a cualquier ubicación en la que pueda hacer clic en el mapa. Sin embargo, como se mencionó en la introducción, no admite ninguna otra maniobra que no sean giros y aún no maneja fuera de ruta.
Puedes encontrar el código fuente completo en mi github.
Paso 8: ¿Qué sigue?
Ahora que la aplicación es lo suficientemente funcional como para guiar a su usuario en una ruta establecida (si no hay desviaciones de la ruta establecida), mi enfoque principal será mejorar la aplicación del teléfono inteligente e implementar las pocas capacidades que harían que el módulo sea un dispositivo de navegación viable. Esto incluye habilitar la comunicación Bluetooth desde el teléfono incluso cuando la pantalla está apagada, así como el soporte para otro tipo de maniobras (rotondas, fusiones,…). También implementaré una función de redireccionamiento si el usuario se desvía de la ruta original.
Cuando todo esto esté hecho, mejoraré el contenedor y su mecanismo de fijación, lo imprimiré en 3D e intentaré llevar el módulo para una primera ejecución.
Si todo va bien, mi objetivo a largo plazo es diseñar una PCB personalizada para la electrónica integrada de este proyecto, lo que ahorraría mucho espacio en el producto final.
También podría agregar algunas otras funciones a este módulo en el futuro, incluida una visualización de la hora, así como una alarma de notificación telefónica, que podría hacer que aparezca un icono cuando el usuario recibe un mensaje de texto o una llamada. Finalmente, me encantaría agregar las capacidades de Spotify a este módulo, como un gran fanático de la música. Sin embargo, en este momento, es bueno tenerlo.
Paso 9: Conclusión y agradecimiento especial
Como se indica en la introducción, aunque este proyecto está lejos de estar terminado, tenía muchas ganas de compartirlo con el mundo, con la esperanza de que pudiera inspirar a alguien más. También quería documentar mi investigación sobre este tema, ya que realmente no hay mucho interés de los aficionados en AR y HUD, lo cual creo que es una pena.
Quiero agradecer enormemente a Awall99 y Danel Quintana, cuyo respectivo proyecto de realidad aumentada me inspiró mucho en la realización de este módulo.
Gracias a todos por su atención, me aseguraré de publicar una actualización cuando este proyecto mejore en un futuro próximo. Mientras tanto, ¡nos vemos más tarde!
Recomendado:
Motor paso a paso controlado por motor paso a paso sin microcontrolador: 6 pasos
¡Motor paso a paso controlado por motor paso a paso sin microcontrolador !: En este Instructable rápido, haremos un controlador de motor paso a paso simple usando un motor paso a paso. Este proyecto no requiere circuitos complejos ni un microcontrolador. Así que sin más preámbulos, ¡comencemos
Motor paso a paso controlado por motor paso a paso sin microcontrolador (V2): 9 pasos (con imágenes)
Motor paso a paso controlado por motor paso a paso sin microcontrolador (V2): En uno de mis Instructables anteriores, le mostré cómo controlar un motor paso a paso usando un motor paso a paso sin un microcontrolador. Fue un proyecto rápido y divertido, pero vino con dos problemas que se resolverán en este Instructable. Entonces, ingenio
Modelo de locomotora controlada por motor paso a paso - Motor paso a paso como codificador rotatorio: 11 pasos (con imágenes)
Locomotora modelo controlada por motor paso a paso | Motor paso a paso como codificador rotatorio: en uno de los Instructables anteriores, aprendimos cómo usar un motor paso a paso como codificador rotatorio. En este proyecto, ahora usaremos ese motor paso a paso convertido en codificador rotatorio para controlar un modelo de locomotora usando un microcontrolador Arduino. Entonces, sin fu
Impresionante invernadero con riego automático, conexión a Internet y mucho más: 7 pasos (con imágenes)
Impresionante invernadero con riego automático, conexión a Internet y mucho más: Bienvenido a este Instructables. A principios de marzo, estaba en una tienda de jardinería y vi algunos invernaderos. Y como quería hacer un proyecto con plantas y electrónica desde hace mucho tiempo, seguí adelante y compré uno: https://www.instagram.com/p
Motor paso a paso controlado por motor - Motor paso a paso como codificador rotatorio: 11 pasos (con imágenes)
Motor paso a paso controlado por motor paso a paso | Motor paso a paso como codificador rotatorio: ¿Tiene un par de motores paso a paso por ahí y quiere hacer algo? En este Instructable, usemos un motor paso a paso como codificador rotatorio para controlar la posición de otro motor paso a paso usando un microcontrolador Arduino. Así que sin más preámbulos, vamos a