Índice:

Protótipo de HUD de motocicleta inteligente (navegação passo a passo e muito mais): 9 etapas
Protótipo de HUD de motocicleta inteligente (navegação passo a passo e muito mais): 9 etapas

Vídeo: Protótipo de HUD de motocicleta inteligente (navegação passo a passo e muito mais): 9 etapas

Vídeo: Protótipo de HUD de motocicleta inteligente (navegação passo a passo e muito mais): 9 etapas
Vídeo: The Best Smart Helmets in The Market 2024, Julho
Anonim
Protótipo de HUD de motocicleta inteligente (navegação passo a passo e muito mais)
Protótipo de HUD de motocicleta inteligente (navegação passo a passo e muito mais)
Protótipo de HUD de motocicleta inteligente (navegação passo a passo e muito mais)
Protótipo de HUD de motocicleta inteligente (navegação passo a passo e muito mais)
Protótipo de HUD de motocicleta inteligente (navegação passo a passo e muito mais)
Protótipo de HUD de motocicleta inteligente (navegação passo a passo e muito mais)
Protótipo de HUD de motocicleta inteligente (navegação passo a passo e muito mais)
Protótipo de HUD de motocicleta inteligente (navegação passo a passo e muito mais)

Oi !

Este Instructables é a história de como projetei e construí uma plataforma HUD (Heads-Up Display) projetada para ser montada em capacetes de motociclistas. Foi escrito no contexto do concurso "mapas". Infelizmente, não consegui terminar totalmente este projeto a tempo para o prazo do concurso, mas ainda queria compartilhar meu progresso nele, bem como documentar todas as tentativas e erros que tive ao fazê-lo.

A ideia desse projeto me veio pela primeira vez há alguns anos, quando entrei no mercado de motocicletas e estava começando a pesquisar que equipamento precisaria comprar para tornar minhas viagens mais divertidas. Na época, fiquei perplexo que a melhor maneira de obter um pouco de navegação GPS básica enquanto andava era basicamente anexar seu smartphone ao guidão da bicicleta. Eu pensei para mim mesmo que certamente poderia haver uma maneira melhor de obter esse tipo de informação na hora.

Foi então que me dei conta: um display heads-up pode ser a maneira de obter navegação durante a condução, sem esvaziar a bateria do seu telefone e expondo-o às intempéries.

Com o tempo, essa ideia amadureceu em minha mente, e achei que ter um HUD à minha frente o tempo todo permitiria muitos outros usos do que a simples navegação. É por isso que meu plano é tornar a plataforma pública e modular, para que qualquer pessoa possa criar um módulo que exiba as informações de que precisa em seu próprio HUD

Embora existam produtos disponíveis comercialmente que cumpram essa tarefa, não existem produtos tão modulares quanto a minha plataforma, e também tendem a ser um pouco caros. De qualquer forma, seja bem-vindo a este projeto.

O que funciona a partir de agora

Como dito, este projeto ainda está em um estado de desenvolvimento, e é isso que está funcionando atualmente.

- Comunicação entre um smartphone e uma placa baseada em ESP32 (telefone ativado)

- Projeto óptico feito (pode precisar de pequenos ajustes a longo prazo)

- Aplicativo de navegação Android usando o SDK de navegação Mapbox:

- Capaz de calcular e exibir a posição do usuário em um mapa, bem como uma rota a partir dele até o destino

- Capaz de se conectar a um dispositivo Bluetooth (o endereço MAC do dispositivo está codificado a partir de agora)

- Capaz de navegação em tempo real, incluindo extrair e enviar as informações da próxima manobra por meio de Bluetooth serial (apenas suporta curvas por enquanto)

O que precisa ser trabalhado

Esta lista contém itens que são absolutamente necessários para o uso pretendido do HUD, mas ainda não estão prontos para serem implementados.

- Projeto geral (fixação do capacete, mecanismo de ajuste do ângulo do refletor,..)

- aplicativo Android:

- Implementar detecção e correção fora da rota

- Capacidade para o usuário inserir o endereço de destino

- Pontos de passagem?

- Ergonomia / Estética

Suprimentos:

Essenciais

- Uma placa de desenvolvimento baseada em esp32

- Qualquer smartphone Android relativamente recente (habilitado para Bluetooth)

- Um SSD1306 ou outra tela OLED de 96 "habilitada (a minha era de 128x64 pixels, consulte a parte" Os cérebros: Microcontrolador e tela ")

- Um refletor (qualquer pedaço de acrílico / vidro / plexiglass serve)

- Uma lente Fresnel (a minha tinha um comprimento F. de cerca de 13 cm, consulte a seção "Escolha da lente")

Ferramentas

- Ferro de solda

- breadboard

- Alguns cabos de ligação

- Serviço de impressora 3D / impressão 3D

Etapa 1: Como tudo funciona: Explicação das opções de design

Como tudo funciona: as opções de design explicadas
Como tudo funciona: as opções de design explicadas
Como tudo funciona: as opções de design explicadas
Como tudo funciona: as opções de design explicadas
Como tudo funciona: as opções de design explicadas
Como tudo funciona: as opções de design explicadas

A ideia básica de um Heads Up Display é exibir uma imagem na frente da visão de alguém, para que ela não tenha que desviar o olhar do que quer que esteja fazendo (seja pilotando um avião ou dirigindo uma motocicleta, que será o nosso caso de exemplo).

Óptica

Tecnicamente, isso pode ser conseguido colocando uma tela na frente dos olhos do usuário. No entanto, uma tela não é transparente e, portanto, prejudicaria a visão de seu usuário. Você poderia então colocar a tela na frente de uma superfície reflexiva, que espelharia o conteúdo da tela ao mesmo tempo em que seria transparente o suficiente para que o usuário pudesse ver o que está à sua frente.

No entanto, essa abordagem tem uma grande falha: a tela real geralmente está mais perto dos olhos do usuário do que aquilo em que o usuário realmente precisa se concentrar (por exemplo, a estrada à sua frente). Isso significa que, para ler o que está na superfície reflexiva, os olhos do usuário precisariam se adaptar à distância da tela de seus olhos (digamos 20 cm) e, então, precisariam se adaptar novamente para focar na estrada à frente (~ 2/5 metros). O tempo que toda essa operação leva é um tempo precioso que deve ser gasto olhando para a estrada, e a adaptação frequente pode ser desconfortável para o usuário após apenas alguns minutos.

É por isso que decidi adicionar uma lente entre a tela e o refletor. Essa lente, se escolhida com cuidado, deve permitir a criação de uma imagem virtual da tela (veja o esquema acima), que então pareceria estar mais longe dos olhos do usuário como realmente é, exigindo adaptações menos abruptas (ou nenhum, em um cenário perfeito). Este design permite ao usuário olhar rapidamente para o refletor, obter as informações de que precisa e, instantaneamente, olhar para a estrada.

O papel do smartphone

Como não era realista tentar implementar um aplicativo de navegação inteiro apenas no ESP32, decidi fazer um aplicativo para Android que cuidaria disso. O aplicativo então precisaria apenas dizer ao ESP32 o que o usuário deve fazer para chegar ao seu destino, e o ESP32 retransmite essa informação através do HUD (consulte a figura "Como o módulo funciona").

Etapa 2: Peças - o cérebro: microcontrolador e tela

Peças - o cérebro: microcontrolador e tela
Peças - o cérebro: microcontrolador e tela
Peças - o cérebro: microcontrolador e tela
Peças - o cérebro: microcontrolador e tela

Conforme declarado acima, planejei fazer com que meu módulo exibisse informações de navegação, embora não calculasse o posicionamento real, o rastreamento e a navegação em tempo real. o telefone do usuário se comunicaria com o módulo e enviaria a ele as informações para serem exibidas no HUD.

Para facilitar a comunicação entre o telefone do usuário e o módulo, optei por usar uma placa baseada em ESP32 para este projeto. Esta escolha foi devido a este módulo específico ter capacidades Bluetooth integradas, bem como algumas outras especificações interessantes (armazenamento não volátil fácil de usar, CPU dual-core, RAM suficiente para realmente conduzir o display OLED via I2C, …). É relativamente simples projetar PCBs baseados no ESP32, que levei em consideração. Também tenho experiência profissional no uso e design de circuitos com o ESP32, o que definitivamente influenciou minha escolha.

A escolha da tela basicamente se resumiu a qualquer coisa que eu achasse que seria brilhante o suficiente para uso, além de ser o menor possível. Não fiquei muito preocupado com a quantidade de pixels da tela, pois meu objetivo era ter uma IU bastante minimalista e simples.

Deve-se observar que o driver de tela deve ser suportado por uma biblioteca que permita o espelhamento de imagens. Isso ocorre porque a imagem exibida é invertida quando passa pela lente e aparece no refletor, e não ter que reverter manualmente o que é exibido é um grande peso sobre nossos ombros como construtores.

Etapa 3: Peças - Óptica: Encontrando um Compromisso

Peças - Óptica: Encontrando um Compromisso
Peças - Óptica: Encontrando um Compromisso
Peças - Óptica: Encontrando um Compromisso
Peças - Óptica: Encontrando um Compromisso
Peças - Óptica: Encontrando um Compromisso
Peças - Óptica: Encontrando um Compromisso

A ótica para este projeto foi bastante difícil de abordar, pois eu não tinha ideia do que estava procurando quando comecei este projeto. Depois de alguma pesquisa, entendi que o que eu queria fazer era criar uma "imagem virtual" da minha tela OLED, que parecesse estar mais longe do olho do que realmente está. A distância ideal para a formação desta imagem virtual seria de cerca de 2 a 5 metros à frente do motorista, esta parece ser a distância aos objetos que focalizamos ao dirigir (outros carros, solavancos na estrada, etc …)

Para atingir esse objetivo, optei por usar uma lente de Fresnel, por serem muito grandes, baratas, pareciam oferecer uma distância focal boa o suficiente para o meu projeto, e podem ser cortadas com uma tesoura simples (o que não é o caso para lentes de vidro redondas mais refinadas). As lentes Fresnel podem ter nomes como "lupa de bolso" ou "lupa de cartão de leitura", pois são muito apropriadas para ajudar pessoas com problemas de visão a ler.

Basicamente, o truque aqui era encontrar o meio-termo certo entre:

- Ter uma distância de imagem virtual razoável (ou seja, a que distância o HUD parecerá estar para o usuário, ou a que distância o usuário terá que ajustar seus olhos para ver o que está no HUD)

- Ter o texto na tela não muito ampliado pela lente (que é basicamente uma lupa)

- Ter uma distância razoável entre a tela OLED e a lente, o que, de outra forma, levaria a um módulo muito volumoso

Eu pessoalmente encomendei algumas lentes diferentes na Amazon e determinei suas respectivas distâncias focais, antes de escolher uma com um comprimento F. de cerca de 13 cm. Eu descobri que esse comprimento F., com uma distância de lente OLED de 9 cm, me deu uma imagem satisfatória no meu refletor (veja as últimas imagens acima).

Como você verá nas minhas ilustrações, para focar corretamente no texto exibido, a câmera usada para tirar essas fotos tem que se ajustar como se estivesse focando em um objeto distante, o que faz com que tudo no mesmo plano do refletor pareça borrado. Isso é exatamente o que queremos para nosso HUD.

Você pode encontrar os arquivos 3D para o suporte da lente aqui.

Etapa 4: Peças - um recipiente para mantê-las todas

Peças - um recipiente para mantê-los todos
Peças - um recipiente para mantê-los todos
Peças - um recipiente para mantê-los todos
Peças - um recipiente para mantê-los todos

Enquanto escrevo estes Instructables, o contêiner real que conterá todas as peças do heads-up display ainda não foi projetado. No entanto, tenho algumas idéias sobre sua forma geral e sobre como abordar certos problemas (como como segurar um refletor e fazê-lo resistir a ventos de mais de 100 km / h). Este ainda é um trabalho em andamento.

Etapa 5: Criando um protocolo para o nosso módulo

Para enviar as instruções de navegação do telefone para a placa de desenvolvimento, tive que criar um protocolo de comunicação próprio que me permitisse enviar facilmente os dados solicitados do telefone, ao mesmo tempo que facilitaria o seu processamento uma vez recebidos.

No momento em que este manual de instruções foi escrito, as informações que precisavam ser transmitidas do telefone para navegar com o módulo eram:

- O tipo de manobra seguinte (curva simples, rotunda, junção com outra estrada, …)

- As instruções precisas da próxima manobra (dependendo do tipo de manobra: direita / esquerda para uma curva; qual saída tomar para uma rotatória, …)

- A distância restante antes da próxima manobra (em metros por agora)

Decidi organizar esses dados usando a seguinte estrutura de quadros:

: tipo.instruções, distância;

Apesar de não ser uma solução bonita, esta nos permite separar e distinguir facilmente cada campo do nosso protocolo, o que facilitou a codificação no lado do ESP32.

É importante ter em mente que, para recursos futuros, outras informações podem precisar ser adicionadas a este protocolo (como o dia e hora exatos, ou a música que está sendo reproduzida no telefone do usuário), o que seria facilmente viável usando o mesmo construção de lógica como agora.

Etapa 6: O Código: Lado ESP32

O Código: ESP32 Side
O Código: ESP32 Side
O Código: ESP32 Side
O Código: ESP32 Side

O código para o ESP32 atualmente é bastante simples. Ele usa a biblioteca U8g2lib, que permite fácil controle da tela OLED (enquanto permite o espelhamento da imagem exibida).

Basicamente, tudo o que o ESP32 faz é receber dados seriais por Bluetooth quando o aplicativo os envia, analisa-os e exibe esses dados ou imagens com base nesses dados (ou seja, exibir uma seta em vez da frase "virar à esquerda / direita"). Aqui está o código:

/ * Programa para controlar um HUD de um aplicativo Android via bluetooth serial * / # include "BluetoothSerial.h" // Arquivo de cabeçalho para Bluetooth Serial, será adicionado por padrão ao Arduino # include #include #ifdef U8X8_HAVE_HW_SPI # include # endif # ifdef U8X8_HAVE_HW_I2C # include # endif // construtor da biblioteca OLED, precisa ser alterado de acordo com sua telaU8G2_SSD1306_128X64_ALT0_F_HW_I2C u8g2 (U8G2_MIRROR, / * reset = * / U8X8_PIN_NONE); // Máquina de estado detectado_field valores + variável # define maneuverField 1 # define instruçõesField 2 # define distanceField 3 # define endOfFrame 4intected_field = endOfFrame; BluetoothSerial serialBT; // Objeto para Bluetoothchar entry_char; char maneuver [10]; char instruções [10]; char distance [10]; char tempManeuver [10]; char tempInstructions [10]; char tempDistance [10]; int nbr_char_maneuver = 0; int nbr_char_instructions = 0; int nbr_char_distance = 0; boolean fullsentence = false; void setup () {Serial.begin (9600); // Inicia o monitor serial em 9600 bauds u8g2.begin (); // Controle de inicialização OLED serialBT.begin ("ESP32_BT"); // Nome do atraso do sinal Bluetooth (20); Serial.println ("Dispositivo Bluetooth está pronto para emparelhar");} void loop () {if (serialBT.available () &&! Fullsentence) // Caracteres sendo recebidos via Bluetooth serial {Entry_char = serialBT.read (); Serial.print ("Recebido:"); Serial.println (entrando_char); } switch (detectado_field) {case maneuverField: Serial.println ("Detected field: maneuver"); if (coming_char == '.') // Próximo campo detectado {ected_field = extensionsField; } else {// Preencha a matriz de informações do tipo de manobra maneuver [nbr_char_maneuver] = coming_char; nbr_char_maneuver ++; } pausa; case instruçõesCampo: Serial.println ("Campo detectado: instruções"); if (coming_char == ',') // Próximo campo detectado {ected_field = distanceField; } else {// Preencha as instruções da matriz de informações de instruções [nbr_char_instructions] = entrando_char; nbr_char_instructions ++; } pausa; case distanceField: Serial.println ("Campo detectado: distância"); if (incoming_char == ';') // Fim do quadro detectado {ected_field = endOfFrame; Serial.print ("manobra:"); Serial.println (manobra); Serial.print ("instruções:"); Serial.println (instruções); Serial.print ("distância:"); Serial.println (distância); fullsentence = true; update_Display (); // Quadro completo recebido, analisa-o e exibe os dados de recuperação} else {// Preencher a distância do array de informações de distância [nbr_char_distance] = coming_char; nbr_char_distance ++; } pausa; case endOfFrame: if (coming_char == ':') associated_field = maneuverField; // Novo quadro detectado quebra; padrão: // Não interromper nada; } delay (20);} void update_Display () {// Cache cada array de char para evitar possíveis conflitos memcpy (tempManeuver, maneuver, nbr_char_maneuver); memcpy (tempInstructions, instruções, nbr_char_instructions); memcpy (tempDistance, distance, nbr_char_distance); parseCache (); // Analisa e processa matrizes de caracteres fullsentence = false; // Sentença processada, pronta para a próxima} void parseCache () {u8g2.clearBuffer (); // limpar a memória interna u8g2.setFont (u8g2_font_ncenB10_tr); // escolha uma fonte adequada // matrizes de caracteres -> string obrigatório para usar a função substring () String maneuverString = tempManeuver; String instruçõesString = tempInstructions; // Implementando protocolo aqui. Apenas suporta voltas por enquanto. if (maneuverString.substring (0, 4) == "turn") {// Verifique o tipo de manobra Serial.print ("TURN DETECTED"); if (instruçõesString.substring (0, 5) == "right") {// Verifique as instruções específicas e exiba de acordo u8g2.drawStr (5, 15, "-"); } else if (InstructionsString.substring (0, 4) == "left") {// Verifique as instruções específicas e exiba de acordo u8g2.drawStr (5, 15, "<---"); } else u8g2.drawStr (5, 15, "Err."); // Campo de instruções inválido} / * Implementar outros tipos de manobra (rotatórias, etc.) * else if (tempManeuver == "rdbt") {* *] * / u8g2.drawStr (5, 30, tempDistance); // Mostra a distância restante u8g2.sendBuffer (); // transfere a memória interna para o display // Reinicia todas as matrizes de caracteres antes da próxima leitura memset (maneuver, 0, 10); memset (instruções, 0, 10); memset (distância, 0, 10); memset (tempManeuver, 0, 10); memset (instruções temp, 0, 10); memset (tempDistance, 0, 10); // Redefine o número de elementos em matrizes nbr_char_distance = 0; nbr_char_instructions = 0; nbr_char_maneuver = 0;}

Etapa 7: o código: lado Android

O código: lado Android
O código: lado Android
O código: lado Android
O código: lado Android
O código: lado Android
O código: lado Android

Para o aplicativo de smartphone, decidi usar o SDK de navegação do Mapbox, pois ele oferece muitos recursos úteis quando se trata de construir um mapa de navegação do zero. Também permite o uso de muitos ouvintes úteis, que definitivamente ajudam a fazer este módulo funcionar. Eu também usei a biblioteca serial android-bluetooth de harry1453 para o Android, pois tornou a comunicação serial Bluetooth muito mais fácil de montar.

Se você deseja construir este aplicativo em casa, você precisará obter um token de acesso Mapbox, que é gratuito até um determinado número de solicitações por mês. Você terá que colocar esse token no código e construir o aplicativo do seu lado. Você também precisará codificar o endereço MAC Bluetooth do seu próprio ESP32.

Da forma como está, o aplicativo pode guiá-lo de sua localização atual para qualquer local em que você clicar no mapa. Como mencionado na introdução, no entanto, ele não oferece suporte a nenhuma outra manobra além de curvas e ainda não lida com desvios de rota.

Você pode encontrar o código-fonte completo no meu github.

Etapa 8: o que vem a seguir?

Agora que o aplicativo é funcional o suficiente para realmente guiar seu usuário em uma rota definida (se não houver desvios da rota definida), meu foco principal será melhorar o aplicativo para smartphone e implementar os poucos recursos que tornariam o módulo um dispositivo de navegação viável. Isso inclui habilitar a comunicação Bluetooth do telefone, mesmo quando a tela está desligada, bem como suporte para outros tipos de manobras (rotundas, fusões, …). Também implementarei um recurso de redirecionamento se o usuário se desviar da rota original.

Quando tudo isso estiver feito, vou melhorar o contêiner e seu mecanismo de anexo, imprimi-lo em 3D e tentar levar o módulo para uma primeira execução.

Se tudo correr bem, meu objetivo de longo prazo é projetar um PCB personalizado para a eletrônica embarcada deste projeto, o que economizaria muito espaço no produto final.

Eu também posso adicionar alguns outros recursos a este módulo no futuro, incluindo uma exibição de tempo, bem como um alarme de notificação por telefone, que pode fazer um ícone aparecer quando o usuário receber uma mensagem de texto ou uma chamada. Finalmente, eu adoraria adicionar recursos do Spotify a este módulo, como um grande fã de música. No entanto, neste momento, isso é apenas bom de se ter.

Etapa 9: Conclusão e agradecimento especial

Conclusão e agradecimento especial!
Conclusão e agradecimento especial!

Conforme declarado na introdução, embora este projeto esteja longe de ser concluído, eu realmente queria compartilhá-lo com o mundo, na esperança de inspirar outra pessoa. Eu também queria documentar minha pesquisa sobre este assunto, já que não há realmente muito interesse de amadores em AR e HUDs, o que eu acho uma pena.

Quero deixar um grande agradecimento ao Awall99 e Danel Quintana, cujo respectivo projeto de realidade aumentada me inspirou muito na confecção deste módulo.

Obrigado a todos pela atenção, com certeza postarei uma atualização quando este projeto for aprimorado em um futuro próximo. Enquanto isso, vejo vocês mais tarde!

Recomendado: