GPS de ultra-som

GPS ultra-sônico. Modelo conceitual


Antes de iniciar uma viagem tão longa, vale a pena verificar se tudo é realmente feito no joelho.

Sobre o que é este artigo: como criar de forma rápida e barata um GPS ultrassônico simples.

Lista de dispositivos necessários


  • HC-SR04 3 Pcs.
  • Arduino 1 Pcs.
  • Uma bobina de fios.

Conceito


imagem
Fig. 1 - Ideia geral do dispositivo

Nos cantos superiores da sala, está instalado o HC-SR04, que desempenha o papel de emissores, o terceiro está de cabeça para baixo no chão com o receptor e desempenha o papel de um receptor para nós.

Tudo isso está conectado de acordo com o esquema:

imagem
Fig. 2 - Diagrama de conexão do dispositivo

E é claro que você conecta o Arduino via USB a um computador.

Como tudo funciona:

  1. Meça a distância do receptor ao emissor 1
  2. Envie um sinal sobre o início da medição da distância para o receptor e o emissor 1 (puxe as pernas do Trig com ele).
  3. Aguarde até que o receptor nos dê o comprimento.
  4. Repita o mesmo para o emissor 2.
  5. Calcular coordenadas do receptor.

Lembre-se da geometria da escola


imagem
Fig. 3 - Representação geométrica do problema

Com base nesta figura, compomos as fórmulas para calcular as coordenadas:

imagem

A, F é a altura dos emissores em relação ao receptor;
C, E são os comprimentos obtidos medindo a distância dos emissores ao receptor;
G é a distância entre os emissores.

Prática


Instale dois radiadores sob o teto, a uma distância decente um do outro (3 metros), direcione-os com radiadores em um ponto, ao redor do qual sua área de trabalho será formada.

Monte o receptor em algo plano (por exemplo, um pedaço de uma placa) e enrole-o com fita adesiva, para que não produzamos ruído ultrassônico desnecessário na sala.
Conecte tudo de acordo com o esquema apresentado acima.

É assim que os fixadores dos emissores e o substrato do receptor podem ser:

imagem
Fig. 4 - Tipo de módulos

O programa


Considere as partes principais do código em mais detalhes.

Nós forçamos o emissor 1 e o receptor a começar a medir a distância movendo a entrada Trig desses dispositivos de baixo para alto, 10 microssegundos e de volta para baixo.

digitalWrite(trigPinRessiv, LOW); digitalWrite(trigPinTransmit1, LOW); delayMicroseconds(5); digitalWrite(trigPinRessiv, HIGH); digitalWrite(trigPinTransmit1, HIGH); delayMicroseconds(10); digitalWrite(trigPinRessiv, LOW); digitalWrite(trigPinTransmit1, LOW); 

Normalmente, esses dispositivos emitem um sinal de ultrassom e esperam até que seja refletido por alguma coisa e voltam a eles. Mas estamos enganando-os, no nosso caso, um envia e o outro recebe, aquele que recebeu pensa que é o seu sinal, embora seja um sinal de outro dispositivo, e nos dá a distância para esse outro dispositivo.

Esperamos até que o sensor comece a nos dizer a duração do vôo do sinal ultrassônico:

 while (digitalRead(echoPinRessiv) == LOW); 

Registre a hora de início do sinal:

 timeStartSignal = micros(); 

Esperamos até o sensor parar de nos dizer a hora do voo do sinal ultrassônico:

 while (digitalRead(echoPinRessiv) == HIGH); 

Escrevemos o tempo final:

  timeEndSignal = micros(); 

Usando uma fórmula simples, calculamos a distância do emissor ao receptor:

  lenC = ((timeEndSignal-timeStartSignal)/58.00)*10.00; 

Esperamos até que o ruído do ultrassom diminua na sala:

 delay(100); 

Vale a pena notar que o sensor nos indica a distância diminuindo a saída de eco para Baixa por um período diretamente proporcional à distância medida.

A mesma coisa é repetida para o segundo emissor.

Usando as regras de um triângulo retângulo, projetamos a distância resultante no plano do piso (Fig. 3).

Implementamos a fórmula do software para a transição das coordenadas tridimensionais para o plano; a fórmula é apresentada acima:

 lenB = sqrt((lenC*2.00)*(lenC*2.00) - lenA*lenA); 

Infelizmente, temos erros e, para removê-los, criei uma fórmula tão experiente, exclua-a e veja o que você recebe.

  measurementError = 26.437 - 0.08*lenC/10; lenB = (lenB + measurementError*10)/10.00; 

Repita o mesmo para o sensor 2.

Calculamos as coordenadas no plano

Encontre o ângulo Alfa:

  alfa = acos(((lenG*lenG + lenD*lenD - lenB*lenB)*1.00) / ((2*lenE*lenG)*1.00)); 

Encontre as próprias coordenadas:

  koord_X = lenE*cos(1.57-alfa); koord_Y = lenE*cos(alfa); 

Se o valor das coordenadas for além do possível, substitua-o pelo valor anterior:

  if((koord_X > 0) && (koord_X < 500) && (koord_Y > 0) && (koord_Y < 500)) { oldKoord_X = koord_X; oldKoord_Y = koord_Y; }else{ koord_X = oldKoord_X; koord_Y = oldKoord_Y; } 

Fazemos um buffer para 6 valores de coordenadas e o mudamos constantemente:

  koord_X5 = koord_X4; koord_X4 = koord_X3; koord_X3 = koord_X2; koord_X2 = koord_X1; koord_X1 = koord_X; koord_Y5 = koord_Y4; koord_Y4 = koord_Y3; koord_Y3 = koord_Y2; koord_Y2 = koord_Y1; koord_Y1 = koord_Y; 

Obtemos o valor médio para as últimas 6 medições:

  averageKoord_X = (koord_X + koord_X1 + koord_X2 + koord_X3 + koord_X4 + koord_X5)/6; averageKoord_Y = (koord_Y + koord_Y1 + koord_Y2 + koord_Y3 + koord_Y4 + koord_Y5)/6; 

Envie as coordenadas para o PC:

  Serial.println(averageKoord_X); Serial.println(averageKoord_Y); 

Funções:

 float asin(float c) float acos(float c) float atan(float c) 

basta pegar e usar =)

Código inteiro:

 int trigPinRessiv = 8; int echoPinRessiv = 9; int trigPinTransmit1 = 2; int trigPinTransmit2 = 3; int i; long lenA = 2700; //sensor height in mm long lenG = 305; // distance between sensors in cm long koord_X, koord_Y; long koord_X1, koord_Y1; long koord_X2, koord_Y2; long koord_X3, koord_Y3; long koord_X4, koord_Y4; long koord_X5, koord_Y5; long oldKoord_X = 0, oldKoord_Y = 0; long averageKoord_X, averageKoord_Y; long measurementError; float alfa; long timeStartSignal, timeEndSignal; long lenC, lenE, lenB, lenD; void setup() { Serial.begin (115200); pinMode(trigPinRessiv, OUTPUT); pinMode(echoPinRessiv, INPUT); pinMode(trigPinTransmit1, OUTPUT); pinMode(trigPinTransmit2, OUTPUT); } void loop() { averageKoord_X = 0; averageKoord_Y = 0; digitalWrite(trigPinRessiv, LOW); digitalWrite(trigPinTransmit1, LOW); delayMicroseconds(5); digitalWrite(trigPinRessiv, HIGH); digitalWrite(trigPinTransmit1, HIGH); delayMicroseconds(10); digitalWrite(trigPinRessiv, LOW); digitalWrite(trigPinTransmit1, LOW); while (digitalRead(echoPinRessiv) == LOW); timeStartSignal = micros(); while (digitalRead(echoPinRessiv) == HIGH); timeEndSignal = micros(); lenC = ((timeEndSignal-timeStartSignal)/58.00)*10.00; delay(100); digitalWrite(trigPinRessiv, LOW); digitalWrite(trigPinTransmit2, LOW); delayMicroseconds(5); digitalWrite(trigPinRessiv, HIGH); digitalWrite(trigPinTransmit2, HIGH); delayMicroseconds(10); digitalWrite(trigPinRessiv, LOW); digitalWrite(trigPinTransmit2, LOW); while (digitalRead(echoPinRessiv) == LOW); timeStartSignal = micros(); while (digitalRead(echoPinRessiv) == HIGH); timeEndSignal = micros(); lenE = ((timeEndSignal-timeStartSignal)/58.00)*10.00; delay(100); lenB = sqrt((lenC*2.00)*(lenC*2.00) - lenA*lenA); measurementError = 26.437 - 0.08*lenC/10; lenB = (lenB + measurementError*10)/10.00; lenD = sqrt((lenE*2.00)*(lenE*2.00) - lenA*lenA); measurementError = 26.437 - 0.08*lenD/10; lenD = (lenD + measurementError*10)/10.00; alfa = acos(((lenG*lenG + lenD*lenD - lenB*lenB)*1.00)/((2*lenE*lenG)*1.00)); koord_X = lenE*cos(1.57-alfa); koord_Y = lenE*cos(alfa); if((koord_X > 0) && (koord_X < 500) && (koord_Y > 0) && (koord_Y < 500)) { oldKoord_X = koord_X; oldKoord_Y = koord_Y; }else{ koord_X = oldKoord_X; koord_Y = oldKoord_Y; } koord_X5 = koord_X4; koord_X4 = koord_X3; koord_X3 = koord_X2; koord_X2 = koord_X1; koord_X1 = koord_X; koord_Y5 = koord_Y4; koord_Y4 = koord_Y3; koord_Y3 = koord_Y2; koord_Y2 = koord_Y1; koord_Y1 = koord_Y; averageKoord_X = (koord_X + koord_X1 + koord_X2 + koord_X3 + koord_X4 + koord_X5)/6; averageKoord_Y = (koord_Y + koord_Y1 + koord_Y2 + koord_Y3 + koord_Y4 + koord_Y5)/6; } float asin(float c) { float out; out = ((c+(pow(c,3))/6+(3*pow(c,5))/40+(5*pow(c,7))/112 +(35*pow(c,9))/1152 +(0.022*pow(c,11))+(0.0173*pow(c,13))+(0.0139*pow(c,15)) + (0.0115*pow(c,17))+(0.01*pow(c,19)))); if(c >= .96 && c < .97) { out=1.287+(3.82*(c-.96)); } if(c>=.97 && c<.98) { out=(1.325+4.5*(c-.97)); } if(c>=.98 && c<.99) { out=(1.37+6*(c-.98)); } if(c>=.99 && c<=1) { out=(1.43+14*(c-.99)); } return out; } float acos(float c) { float out; out=asin(sqrt(1-c*c)); return out; } float atan(float c) { float out; out=asin(c/(sqrt(1+c*c))); return out; } 

Portanto, temos o sistema GPS ultrassônico mais simples, com um metro por metro de alcance, o vídeo mostra como tudo funciona.


A visualização da trajetória é feita no Matlab, vou escrever como fazer a mesma visualização no próximo artigo.

Em artigos futuros, considerarei mais profundamente as várias partes deste sistema e tentarei melhorá-las.

Ficarei feliz em ouvir suas opiniões e comentários sobre este tópico, o projeto ainda está ativo =)

Página do Projeto

Inspirado nas seguintes fontes:

Wikipedia
Um post no Habr "GPS" interno "com uma precisão de + -2cm"

Source: https://habr.com/ru/post/pt451408/


All Articles