Esse post sobre controle de vagas de estacionamento surgiu da pergunta de um leitor no post Medidor de distância com o sensor ultrassônico HC-SR04. Ele questionou se era possível controlar 2 sensores HC-SR04 usando a biblioteca Ultrasonic.h, uma das mais comuns para quem usa esse tipo de sensor.

Eu tive o mesmo problema ao montar um projeto de faculdade, que consistia em criar um controle de vagas de estacionamento como esses utilizados em shopping center, onde uma luz vermelha indica que a vaga está ocupada, e uma luz verde indica vaga livre.

Controle de vagas - Shopping

Embora a tecnologia utilizada nos shoppings seja muito mais complexa, fazendo uso até mesmo de câmeras para controlar as vagas, a ideia é a mesma e não tão difícil de implementar com o Arduino, como vocês poderão ver agora.

Meu (modesto) projeto controla 2 vagas de estacionamento, com os respectivos leds indicando vaga livre/vaga ocupada. Um display LCD mostra as informações sobre as vagas (total livres/ocupadas).

Em primeiro lugar, eu tentei usar a biblioteca Ultrasonic.h, sem sucesso. Talvez alguma alteração na biblioteca ou algum parâmetro que eu desconheço me ajudassem na tarefa, mas optei por procurar outra versão ou alguma outra biblioteca que fosse mais flexível.

Acabei encontrando a biblioteca NewPing, que torna possível o controle de até 15 sensores HC-SR04. Com essa biblioteca, o meu modesto projeto de apenas 2 vagas pode ser expandido. 😉

Circuito controle de estacionamento com Arduino

Utilizei um Arduino Mega para poder ligar todos os componentes, já que o LCD utiliza 6 portas, cada HC-SR04 mais 2 e os leds bicolores, mais 2. Com alguns ajustes, isso pode ser montado tranquilamente com um Arduino Uno.

Para a sinalização das vagas, utilizei no circuito 2 leds bicolores, que podem ser substituídos por 4 leds comuns. A ligação do display 16×2 segue o mesmo esquema deste artigo , que já usei em diversos projetos aqui no Arduino e Cia:

Circuito Controle de vagas sensor ultrasonico HC-SR04

Antes de carregar o programa, não esqueça de baixar a biblioteca NewPingnesse link. Descompacte e copie a pasta NewPing para dentro da pasta LIBRARIES, dentro da IDE do Arduino.

No início do programa são definidas as variáveis que irão armazenar o número de sensores utilizados (SONAR_NUM), a distância máxima de detecção (MAX_DISTANCE), e o intervalo entre as medições (PING_INTERVAL), que não pode ser muito baixo para que não haja conflito entre os sensores. Para este parâmetro, recomenda-se o valor mínimo de 29 ms.

Para definir os pinos que serão utilizados para cada sensor, utiliza-se o comando NewPing, que tem a seguinte sintaxe :

NewPing(Pino_Trigger, Pino_Echo, Distancia_Maxima)

No meu programa, utilizei apenas 2 sensores, então tenho apenas 2 comandos NewPing. Se você for utilizar mais sensores, inclua mais comandos NewPing. Não se esqueça de setar a variável SONAR_NUM, senão os demais sensores não serão detectados.

O loop do programa efetua a leitura de todos os sensores, e atualiza as variáveis referentes às vagas livres e vagas ocupadas, mostrando as informações no LCD. São utilizadas as subrotinas oneSensorCycle, que efetua a varredura nos sensores, e a echoCheck, que calcula a distância até o objeto detectado.

// Programa : Controle de vagas de estacionamento com o HC-SR04  
// Autor : Arduino e Cia  
   
//Inicializa as bibliotecas do sensor Ultrasonico e do Display  
#include <NewPing.h>  
#include <LiquidCrystal.h>   
   
#define SONAR_NUM   2 // Define o numero de sensores  
#define MAX_DISTANCE 10 // Distancia maxima  

// Milisegundos de intervalo entre medicoes (29ms e o tempo mínimo para 
// evitar conflito entre os sensores)  
#define PING_INTERVAL 33 
   
// Armazena a quantidade de vezes que a medicao deve ocorrer,para cada sensor  
unsigned long pingTimer[SONAR_NUM]; 

unsigned int cm[SONAR_NUM];     // Armazena o numero de medicoes  
uint8_t currentSensor = 0;     // Armazena o sensor que esta ativo  
   
int Pinoled1Verm = 20;  //Pino led1 - Vermelho  
int Pinoled1Verde = 19; //Pino led1 - Verde  
int Pinoled2Verm = 18;  //Pino led2 - Vermelho  
int Pinoled2Verde = 17; //Pino led2 - Verde  
int vagaslivres = 2;   //Contador de vagas livres  
int vagasocupadas = 0;  //Contador de vagas ocupadas  
int sensor1 = 0;    //Contador de vagas no sensor1  
int sensor2 = 0;     //Contador de vagas no sensor2  
   
//Define os pinos que serao ligados ao LCD  
LiquidCrystal lcd(12, 11, 5, 4, 3, 2); 
   
NewPing sonar[SONAR_NUM] =   
{   
  // Armazena informacoes sobre a pinagem dos sensores  
  // Pino trigger, echo e distancia máxima, para cada sensor  
  NewPing(13, 10, MAX_DISTANCE), 
  NewPing(14, 15, MAX_DISTANCE),  
};  
   
void setup()   
{  
  Serial.begin(9600);  
  lcd.begin(16,2); //Inicializa LCD  
  lcd.clear();   //Limpa o LCD  
  pingTimer[0] = millis() + 75;      //Primeira medicao começa com 75ms  
  //Define o tempo de inicializacao de cada sensor
  for (uint8_t i = 1; i < SONAR_NUM; i++)   
   pingTimer[i] = pingTimer[i - 1] + PING_INTERVAL;  
  pinMode(Pinoled1Verm, OUTPUT);  //Define o Pino vermelho do led1 como saida  
  pinMode(Pinoled1Verde, OUTPUT); //Define o Pino verde do led1 como saida  
  pinMode(Pinoled2Verm, OUTPUT);  //Define o Pino vermelho do led2 como saida  
  pinMode(Pinoled2Verde, OUTPUT); //Define o Pino verde do led2 como saida  
 }  
   
void loop() 
{  
  // Loop entre todos os sensores 
  for (uint8_t i = 0; i < SONAR_NUM; i++) {  
   if (millis() >= pingTimer[i]) {
    //Define o tempo que o proximo sensor sera acionado
    pingTimer[i] += PING_INTERVAL * SONAR_NUM;   
    // Ciclo do sensor completo  
    if (i == 0 && currentSensor == SONAR_NUM - 1) oneSensorCycle(); 
    // Reseta o timer antes de ler o proximo sensor  
    sonar[currentSensor].timer_stop();     
    // Número do sensor sendo acionado
    currentSensor = i;               
    // Se nao houver eco do sensor, seta a distância como zero   
    cm[currentSensor] = 0;           
    sonar[currentSensor].ping_timer(echoCheck);  
   }  
 }  
    
 //Calcula a quantidade de vagas disponiveis e ocupadas, e imprime no display  
 vagasocupadas = sensor1 + sensor2;  
 vagaslivres = 2 - vagasocupadas;  
 lcd.setCursor(0,0);  
 lcd.print("Vagas livres = ");  
 lcd.print(vagaslivres);  
 lcd.setCursor(0,1);  
 lcd.print("Vagas ocup. = ");  
 lcd.print(vagasocupadas);  
}  
   
void echoCheck() { //Se receber um sinal (eco), calcula a distancia  
  if (sonar[currentSensor].check_timer())  
   cm[currentSensor] = sonar[currentSensor].ping_result / US_ROUNDTRIP_CM;  
 }  
   
void oneSensorCycle() { // Ciclo de leitura do sensor  
  for (uint8_t i = 0; i < SONAR_NUM; i++) {  
   //Se for detectado objeto entre 0 e 50 cm do sensor1, acende o led1 vermelho
   if (cm[0] > 1 && cm[0] < 50)   
   {  
     digitalWrite(Pinoled1Verm, 1);  
     digitalWrite(Pinoled1Verde, 0);  
     sensor1 = 1; //Incrementa o número de vagas ocupadas na vaga1  
   }  
   else //Se não for detectado objeto no sensor 1, mantém o led1 verde aceso  
   {  
     digitalWrite(Pinoled1Verm, 0);  
     digitalWrite(Pinoled1Verde, 1);  
     sensor1 = 0; //Marca a vaga 1 como livre  
   }   
   
   //Se for detectado objeto entre 0 e 50 cm do sensor2, acende o led2 vermelho  
   if (cm[1] > 1 && cm[1] < 50) 
   {  
     digitalWrite(Pinoled2Verm, 1);  
     digitalWrite(Pinoled2Verde, 0);  
     sensor2 = 1; //Incrementa o número de vagas ocupadas na vaga2  
   }  
   else //Se não for detectado objeto no sensor 2, mantém o led2 verde aceso  
   {  
     digitalWrite(Pinoled2Verm, 0);  
     digitalWrite(Pinoled2Verde, 1);  
     sensor2 = 0; //Marca a vaga 2 como livre  
   }   

   //Imprime os valores lidos no monitor serial, para fins de acompanhamento  
   Serial.print("Sensor : "); 
   Serial.print(i);   
   Serial.print(" = ");  
   Serial.print(cm[i]);  
   Serial.print(" cm - ");  
  }  
  Serial.println();  
}  

No vídeo abaixo você confere este projeto em funcionamento.

A biblioteca NewPing tem vários recursos e é relativamente fácil de usar. Consulte a documentação nesse link (em inglês) para obter maiores informações.

Atualizado: Veja também como montar um pequeno sensor de estacionamento/ré usando o sensor HC-SR04 no post Sensor de estacionamento/ré com o Arduino e sensor HC-SR04.

5/5 - (2 votes)