Etiquetas: , ,

Neste projeto, vamos criar uma barreira automática utilizando um sensor de infravermelhos e um servomotor controlado pelo Arduino.

Objetivo

Utilizando um programa Arduino, vamos fazer com que a barreira automática suba quando um objeto passar e desça quando a passagem estiver livre.

Hardware

  • Computador
  • Arduino Nano
  • Escudo de expansão Nano
  • Sensor de infravermelhos GP2Y0A21
  • Cabo USB A macho

Instalar o software Arduino

Se ainda não o fez, certifique-se de que instala o software Arduino no seu computador seguindo este tutorial. Quando o software estiver instalado, pode verificar se a placa Arduino é reconhecida pelo computador.

Carregamento de código para o Arduino

Vamos agora verificar se podemos carregar código para o Arduino Nano.

Para o fazer, abra um novo ficheiro Arduino.

void setup() {
  // put your setup code here, to run once:

}

void loop() {
  // put your main code here, to run repeatedly:

}

No menu “Ferramentas”, seleccione o tipo de placa, o processador e a porta correspondente à sua placa.

Neste projeto, estamos a utilizar uma placa Nano compatível com Arduino com o driver CH340 e a utilizar o Bootloader antigo.

Assim, seleccionamos “Arduino Nano”, o processador: “Old Bootloader” e a porta utilizada. Aqui, “COM10”.

arduino-empty-board-configuration-1 Criação de uma barreira automática

Pode então clicar na seta (->) no canto superior esquerdo ou no menu “Sketch>Upload” para carregar o código no mapa. Se o software apresentar “Upload complete”, tudo está a funcionar corretamente.

Diagrama

Neste projeto, vamos ligar o sensor de infravermelhos ao pino analógico A0 e o servomotor ao pino 3. Como estamos a utilizar um shield de expansão, as ligações são fáceis de fazer. Certifique-se de que verifica a direção dos pinos para evitar danificar o hardware (SVG, sinal S, V- tensão de 5V, G- terra).

arduino-nano-exp-irsensor-servo Criação de uma barreira automática

Código para testar o sensor

Para determinar a distância entre o objeto e o sensor a partir da qual a barreira é levantada, vamos testar o funcionamento do sensor de infravermelhos. Carregue o código seguinte e, em seguida, coloque a mão em frente do sensor para definir os valores de limiar de disparo. Modifique os valores DETECT_VAL e CLEAR_VAL para obter o comportamento desejado.

//Parameters
#define DETECT_VAL 300
#define CLEAR_VAL 200

//Constants
const int gp2y0a21Pin  = A0;

//Variables
int gp2y0a21Val  = 0;
bool object=false,oldStatus=true;
String comment ="";

void setup() {
  //Init Serial USB
  Serial.begin(9600);
  Serial.println(F("Initialize System"));
  //Init ditance ir
  pinMode(gp2y0a21Pin, INPUT);
}

void loop() {
  readSensor();
  delay(500);
}

void readSensor() { /* function testGP2Y0A21 */
  ////Read distance sensor
  gp2y0a21Val = analogRead(gp2y0a21Pin);

  if (gp2y0a21Val > DETECT_VAL) {
    object=true;
    comment="Obstacle detected";
  } 
  if(gp2y0a21Val < CLEAR_VAL){
    object=false;
    comment="No obstacle";
  }

  if(oldStatus!=object){
    Serial.print(F("Valeur du capteur : "));Serial.print(gp2y0a21Val);
    Serial.print(F(" -> "));Serial.println(comment);
  }
  oldStatus=object;
}

Código para testar o atuador

Para descobrir as posições de subida e descida da barreira, vamos testar o atuador. Vamos enviar dois comandos ao atuador, um representando a posição “para cima” e o outro a posição “para baixo”. Modifique os valores UP e DOWN de acordo com a posição real observada.

//Librairie
#include <Servo.h>

//Déclaration des constantes
#define UPDATE_TIME 15
#define HAUT 180
#define BAS 90

//Déclaration des paramètres
int servoPin = 3;
//Déclaration des variables
Servo myServo;  // création d'un objet Servo

int pos=BAS;    // variable contenant la position du servomoteur

void setup() {
  Serial.begin(9600);
  myServo.attach(servoPin); 
}

void loop() {
  for (pos = BAS; pos <= HAUT; pos += 1) { 
    myServo.write(pos);              
    delay(UPDATE_TIME);                       
  }
  Serial.print(F("Servo position HAUT : "));Serial.println(HAUT);
  delay(500);
  for (pos = HAUT; pos >= BAS; pos -= 1) { 
    myServo.write(pos);             
    delay(UPDATE_TIME);                      
  }
  Serial.print(F("Servo position BAS : "));Serial.println(BAS);
  delay(500);
}

Código de barreira automático

Vamos combinar os dois códigos e fazer algumas alterações para obter o comportamento desejado. Vamos criar duas funções, fenceDown() e fenceUp(). Uma para baixar a barreira e a outra para a levantar. Quando a variável ‘object’ (obstáculo detectado) for verdadeira (1-True), chamamos a função fenceUp() e quando for falsa (0-False), chamamos fenceDown() para baixar a barreira.

//Librairie
#include <Servo.h>

//Parameters
#define DETECT_VAL 300
#define CLEAR_VAL 200
#define UPDATE_TIME 15
#define HAUT 180
#define BAS 90

//Constants
const int gp2y0a21Pin  = A0;
const int servoPin = 3;

//Variables
int gp2y0a21Val  = 0;
bool object=false,oldStatus=true;
String comment ="";
int pos=BAS;    // variable contenant la position du servomoteur

Servo myServo;  // création d'un objet Servo

void setup() {
  //Init Serial USB
  Serial.begin(9600);
  Serial.println(F("Initialize System"));
  pinMode(gp2y0a21Pin, INPUT);
  myServo.attach(servoPin); 

}

void loop() {
  readSensor();
}

void readSensor() { /* function testGP2Y0A21 */
  ////Read distance sensor
  gp2y0a21Val = analogRead(gp2y0a21Pin);
  if (gp2y0a21Val > DETECT_VAL) {
    object=true;
    comment="Obstacle detected";
  } 
  if(gp2y0a21Val < CLEAR_VAL){
    object=false;
    comment="No obstacle";
  }

  if(oldStatus!=object){
    Serial.print(F("Valeur du capteur : "));Serial.print(gp2y0a21Val);
    Serial.print(F(" -> "));Serial.println(comment);
    if(object==true){
      fenceUp();
    }else{
      fenceDown();
    }
  }
  oldStatus=object;
}

void fenceUp(){
    for (pos = pos; pos <= HAUT; pos += 1) { 
    myServo.write(pos);              
    delay(UPDATE_TIME);                       
  }
  Serial.print(F("Servo position HAUT : "));Serial.println(HAUT);
}

void fenceDown(){
  for (pos = pos; pos >= BAS; pos -= 1) { 
    myServo.write(pos);             
    delay(UPDATE_TIME);                      
  }
  Serial.print(F("Servo position BAS : "));Serial.println(BAS);
}

Próximas etapas

  • Acrescentar um dispositivo de segurança para que a barreira se levante quando estiver presente um objeto, mesmo que não tenha terminado a descida.
  • Acrescentar um semáforo à barreira
  • Adicionar um leitor de cartões RFID para abrir a barreira apenas com o crachá correto

Fontes