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”.
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).
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