Para quem dirige, estacionar um carro em uma vaga de garagem é uma tarefa corriqueira, mas que pode apresentar um desafio e prejuízos. Quem nunca “estacionou de ouvido”, colidindo com a parede no fundo, podendo causar danos a esta e ao veículo? Pensando nisso, as montadoras instalaram sensores de estacionamento na traseira dos carros para auxiliar durante o estacionamento. Porém, nem todos os carros possuem este dispositivo. Além disso, dependendo da geometria da sua garagem (ex.: canos), mesmo os carros com estes sensores podem não ser eficazes para evitar a colisão.
Neste artigo, mostraremos uma solução que funciona a partir de um sensor ultrassônico colocado na garagem, ao invés de no veículo. LEDs nas cores verde, amarelo e vermelho e um buzzer indicam ao motorista a situação.
Para executar este projeto numa protoboard, precisaremos dos seguintes materiais:
Nosso assistente funcionará da seguinte forma: suponha uma garagem genérica, onde definimos distâncias conforme a figura abaixo:
Nosso assistente se ativa ao detectar movimento. Quando for identificado um veículo dentro da garagem, ele acenderá o LED da cor apropriada com base na cor da zona da figura acima. Caso o veículo entre na zona roxa, além de acender o LED vermelho, será acionado, também, um alarme sonoro (buzzer).
A detecção de distância se faz através de um sensor ultrassônico. A ausência de variação de distância em um intervalo de tempo (ex: 5 seg) é tida como indicativo de veículo parado, desativando a sinalização.
O circuito deste artigo é didático, usando uma protoboard e uma Arduino Uno R3. Mais à frente, abordaremos opções para uma montagem prática definitiva.
O diagrama do circuito pode ser visto na figura abaixo, assim como sua montagem na protoboard.
Basicamente, nosso circuito contém uma Arduino tendo uma entrada com o sensor ultrassônico HC-SR04 e 3 saídas com LEDs de cores diferentes (verde, amarelo e vermelho) em série com resistores de 330 Ohms e um buzzer em série com um resistor de 100 ohms.
O sensor ultrassônico HC-SR04 funciona através da emissão de um pulso ultrassônico de 10 us (pino Trig), permitindo medir o tempo de retorno do eco deste pulso em algum obstáculo à frente (pino Echo). Ele permite medir distâncias entre 2 cm a 4 m.
Abaixo, vídeo demonstrando o funcionamento em miniatura:
O circuito é idêntico ao vídeo de referência. Porém, a programação foi refeita para efeitos de clareza, didática e experimentação.
O primeiro ponto a entendermos é o funcionamento do sensor de distância. Para medirmos a distância, precisamos enviar um pulso de 10 us e, depois, verificar o tempo de retorno do eco para indicar a distância. Este tempo é obtido a partir do comando pulseIn(), que mede o tempo do pulso no pino Echo do HC-SR04.
Nosso programa utiliza a função MedeDistancia(). O que ela faz é chamar a função DisparaPulsoUltrassonico(), que envia o pulso, obtém o tempo do pulso do HC-SR04 e usa a função CalculaDistancia() para obter a distância em metros, retornando a distância em centímetros (x100). O cálculo é feito com base no trajeto (ida e volta) e a velocidade do som no ar. Para efeitos práticos, desconsideramos o fato do emissor e receptor estarem a uma certa distância, o que geraria um caminho triangular do pulso sonoro.
// Mede a distância do sensor ultrassônico float MedeDistancia() { float TempoEcho = 0; // variável tempo do eco DisparaPulsoUltrassonico(); // dispara pulso ultrassonico TempoEcho = pulseIn(PinEcho, HIGH); // mede duração do pulso HIGH de eco em micro seg return CalculaDistancia(TempoEcho) * 100; // retorna distância em cm }
// Envia um pulso de 10 us void DisparaPulsoUltrassonico() { digitalWrite(PinTrigger, HIGH); // pulso alto de Trigger delayMicroseconds(10); // atraso de 10 microsegundos digitalWrite(PinTrigger, LOW); // pulso baixo de Trigger }
// Calcula a distância com base no tempo do pulso float CalculaDistancia(float tempo_us) { return ((tempo_us * velocidadeSom_mpus) / 2); // calcula distancia em metros }
O Loop principal inicialmente mede a distância. Com base nela, o programa verifica se o veículo está parado. Caso não esteja, ele verifica as faixas de distância, começando da mais perto para a mais longe, chamando as funções Sinaliza(faixa) ou desligaSinais(), caso esteja fora da garagem. Estas duas últimas ligam ou desligam os LEDs e buzzer como desejado.
Como exemplo, para ligar o LED verde usamos um comando digitalWrite(PinLEDverde, HIGH);
Para acionar o buzzer usamos o comando tone(PinBuzzer, 500);
Para efeito de debug, usamos o comando Serial.print()/Serial.println() para enviar ao PC dados sobre a distância medida.
Para efeito didático e de experimentação, foram criadas algumas constantes e variáveis. Elas foram úteis para ajustar o funcionamento do circuito com uma miniatura.
As constantes de limite (ex.: limite verde) contêm os valores, em centímetros, entre o sensor e o limite da faixa em questão. No programa, estes valores estão ajustados para uma miniatura. Porém, podem ser alterados para indicar da forma que for desejado na sua aplicação, em especial.
A constante atraso tem a ver com o delay() no loop principal. Em debug, usando os comandos seriais para o PC, este tempo pode ser de 200–500 ms. Na versão final, os comandos seriais podem ser removidos e o atraso reduzido. A constante Maxcontador funciona em conjunto para definir um tempo de 5s para detectar a parada do veículo.
A constante tolerância pode ser utilizada para calibrar a detecção de parada de veículo. Como as leituras do HC-SR04 podem indicar pequenas variações, aumentar a tolerância reduz o impacto de “ruídos” na leitura da distância (ver função estaParado).
O programa completo pode ser visto abaixo.
/* Programa de assistente de garagem com Sensor de Distância Ultrassônico Blog Eletrogate - https://blog.eletrogate.com/ Arduino Uno - LCD 16/2 azul - IDE 2.1.0 Mauro Vianna 27/junho/2023 */ // Pinos do arduino utilizados int PinTrigger = 5; // pino usado para disparar os pulsos do sensor int PinEcho = 6; // pino usado para ler a saida do sensor int PinLEDvermelho = 2; // pino usado pelo LED vermelho int PinLEDamarelo = 3; // pino usado pelo LED amarelo int PinLEDverde = 4; // pino usado pelo LED verde int PinBuzzer = A0; // pino usado pelo buzzer // Variaveis e constantes para controle de distancia const int atraso = 200; // tempo de espera do loop const int MaxContador = 5000/atraso; // número de iterações para considerar parado (5s) const float tolerancia = 1.0; // tolerancia para detecção de movimento const float velocidadeSom_mps = 340; // em metros por segundo const float velocidadeSom_mpus = 0.000340; // em metros por microsegundo float Distancia = 0; // Distancia medida float DistanciaAnterior = 0; // Distancia anterior medida (detecção de movimento) int contador = 0; // contador de tempo para detecçaõ de movimento // Valores limites das faixas de sinalização const int LimiteVerde = 29; const int LimiteAmarelo = 17; const int LimiteVermelho = 10; const int LimiteBuzzer = 8; // Comandos de sinalização const int Verde = 1; const int Amarelo = 2; const int Vermelho = 3; const int Buzzer = 4; // Inicialização void setup() { pinMode(PinTrigger, OUTPUT); // configura pino Trigger como saída digitalWrite(PinTrigger, LOW); // pino trigger - nível baixo pinMode(PinEcho, INPUT); // configura pino ECHO como entrada pinMode(PinLEDvermelho, OUTPUT); // configura pino LED vermelho como saída pinMode(PinLEDamarelo, OUTPUT); // configura pino LED amarelo como saída pinMode(PinLEDverde, OUTPUT); // configura pino LED verde como saída pinMode(PinBuzzer, OUTPUT); // configura pino Buzzer como saída Serial.begin(9600); // inicializa monitor serial 9600 Bps (debug) delay(100); // atraso de 100 milisegundos Distancia = MedeDistancia(); DistanciaAnterior = Distancia; desligaSinais(); } // Loop principal void loop() { Distancia = MedeDistancia(); if (estaParado()) { desligaSinais(); } else if (Distancia <= LimiteBuzzer) { Sinaliza(Buzzer); } else if (Distancia <= LimiteVermelho) { Sinaliza(Vermelho); } else if (Distancia <= LimiteAmarelo) { Sinaliza(Amarelo); } else if (Distancia <= LimiteVerde) {Sinaliza(Verde); } else { desligaSinais();} Serial.print("Distancia em centimentros: "); // mostra no monitor serial Serial.print(Distancia); // mostra o calculo de distancia em metros Serial.println(); delay(atraso); // tempo de atraso } // Envia um pulso de 10 us void DisparaPulsoUltrassonico() { digitalWrite(PinTrigger, HIGH); // pulso alto de Trigger delayMicroseconds(10); // atraso de 10 microsegundos digitalWrite(PinTrigger, LOW); // pulso baixo de Trigger } // Calcula a distância com base no tempo do pulso float CalculaDistancia(float tempo_us) { return ((tempo_us * velocidadeSom_mpus) / 2); // calcula distancia em metros } // Mede a distância do sensor ultrassônico float MedeDistancia() { float TempoEcho = 0; // variável tempo do eco DisparaPulsoUltrassonico(); // dispara pulso ultrassonico TempoEcho = pulseIn(PinEcho, HIGH); // mede duração do pulso HIGH de eco em micro seg return CalculaDistancia(TempoEcho) * 100; // retorna distância em cm } // Sinaliza a faixa apropriada void Sinaliza(int faixa) { desligaSinais(); if (faixa == Verde) { digitalWrite(PinLEDverde, HIGH); } else if (faixa == Amarelo) { digitalWrite(PinLEDamarelo, HIGH); } else if (faixa == Vermelho) { digitalWrite(PinLEDvermelho, HIGH); } else if (faixa == Buzzer) { digitalWrite(PinLEDvermelho, HIGH); tone(PinBuzzer, 500); } } // Desliga a sinalização void desligaSinais() { digitalWrite(PinLEDverde, LOW); digitalWrite(PinLEDamarelo, LOW); digitalWrite(PinLEDvermelho, LOW); noTone(PinBuzzer); } // verifica se está parado byte estaParado() { byte parado; if (sq(Distancia - DistanciaAnterior) <= tolerancia) { if (contador >= MaxContador) { Serial.println("Sem movimento. Desligando sinais..."); parado = 1; } else { contador++; parado = 0; } } else { contador = 0; parado = 0; } DistanciaAnterior = Distancia; return parado; }
Nosso circuito atende bem ao teste de bancada em protoboard. Mas, e se quisermos realmente montá-lo na garagem? Na referência, temos a página do site instructables do Youtuber detalhando como montar o circuito final para a garagem. Cabe aqui algumas observações para entender as diferenças.
A primeira diferença foi a separação do circuito em 2 partes: A primeira contém os LEDS indicadores, conectados por um cabo de 4 vias (GND, 3x LEDs) a primeira parte, com o arduino e Buzzer. O módulo com os LEDS deve ser posicionado em altura visível (nível do para-brisa e retrovisor) e o módulo com o sensor deve ser posicionado na altura do porta-malas.
A segunda diferença foi o uso de uma Arduino Nano, mais adequada para soldagem em placa. Esta é alimentado por uma fonte de 5 V com o plug USB apropriado.
A Nano tem as mesmas funcionalidades da Uno R3, inclusive uma entrada USB para alimentação e comunicação com o PC. Porém, não tem o segundo conector para fonte externa com plug P4.
Algumas possibilidades de melhoria ou alteração do projeto, a critério do leitor:
Vimos, neste artigo, um circuito simples, mas com uma boa aplicação prática. É um exemplo de como problemas cotidianos podem ser resolvidos de forma descomplicada, facilitando nossa vida e evitando danos. Além disso, aprendemos um pouco mais sobre eletrônica e programação, no processo.
|
A Eletrogate é uma loja virtual de componentes eletrônicos do Brasil e possui diversos produtos relacionados à Arduino, Automação, Robótica e Eletrônica em geral.
Conheça a Metodologia Eletrogate e Lecione um Curso de Robótica nas Escolas da sua Região!