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!