Novos redatores

Sistema de Coleta de Pó para Marcenaria

Eletrogate 5 de outubro de 2023

Introdução

O meu filho Alberto estudou e morou nos USA por 7 anos e observou que muitos americanos tinham, como hobby, o hábito de montar marcenarias nas garagens ou porões das suas casas. Ele acabou se interessando pelo hobby ao retornar para o Brasil e começou a estudar as diferentes automações que os americanos implementavam visando deixar o ambiente limpo sem esforço manual. Desde sistemas bastante manuais, com o uso de aspiradores que tinham que ser conduzidos nos quatro cantos do local para aspirar o pó, até sistemas com grau intermediário de automação, como, por exemplo, coleta centralizada do pó, porém com o acionamento manual do aspirador e abertura/fechamento dos BLAST GATES manualmente, etc.

Ele pesquisou também sistemas com Arduino usando teclado para acionar servos abrindo/fechando BLAST GATES e até sistemas usando detecção de corrente, porém para apenas um equipamento de entrada. A partir de tais exemplos, ele teve a ideia de especificar um projeto com as melhores práticas que ele observou, juntando tudo num projeto mais abrangente e híbrido, permitindo o máximo de decisão pelo próprio sistema, mas com certo grau de autonomia para o operador através do uso de IR para minimizar o deslocamento no ambiente. Daí, juntamos para dar sequência ao projeto…


Materiais Necessários para o Projeto Sistema de Coleta de Pó para Marcenaria

Componentes utilizados
1 x Nano V3.0 + Cabo Usb para Arduino (escolhido por questão de espaço, mas poderia ser um Arduino UNO)
1 x Módulo Regulador de Tensão Step Down LM2596 com Display
1 x Módulo PWM PCA9685 I2C – 16 Canais para Servo
1 x Controle Remoto Ir + Receptor Ir
3 x Módulo Sensor de Corrente 20A
1 x Módulo Relé 1 Canal 5v
1 x Fonte 12 V / 3 A
1 x Protoboard 400 Pontos
1 x WorkPlate de 400
1 x Caixa de acrílico de 20cm x 15cm x 7cm de altura com tampa removível para acomodar o circuito
3 x Servo TowerPro MG995 Metálico 180°
3 x Blast Gate 5,3 cm + mangueiras sanfonadas para interligação com o aspirador
1 x Buzzer Ativo 5v
1 x Ciclone para reter a maior parte do resíduo, facilitando o descarte e a economia de filtros do aspirador
1 x Jumpers – Macho/Femea – 20 Unidades de 20cm

Bibliotecas
Adafruit_PWMServoDriver ➔ instalada pelo gerenciador de bibliotecas
ACS712 ➔ instalada pelo gerenciador de bibliotecas
IRremote ➔ instalada pelo gerenciador de bibliotecas


Objetivos

Sistema para automatização da coleta de resíduos de madeira de uma marcenaria:

• São esperadas 3 entradas de equipamentos geradores de resíduo. A tomada elétrica de cada equipamento de entrada é dotada de um sensor de detecção de corrente, de forma evasiva, ligada ao Arduino nas portas analógicas.
• Os equipamentos de entrada são conectados com dutos até um duto central ligado ao aspirador central e fixo.
• Cada equipamento de entrada tem uma porta de comunicação com o duto central, com BLAST GATE (veja Figura 4 para definição) controlado por um SERVO para abrir/fechar a entrada.
• Somente um equipamento de entrada deve ser ativado por vez e apenas a sua porta de comunicação com a coleta deve estar aberta para não haver perda de eficiência na sucção pelo aspirador. Esta foi uma decisão de projeto, dadas as especificações do aspirador.
• A abertura da porta foi inicialmente pensada para ser decidida pelo operador através do uso de um controle remoto IR: 3 teclas, uma para cada porta, a 4a. tecla para fechar/abrir todas as 3 portas e a 5a. para ligar/desligar o relé. Posteriormente, modificamos para a abertura da porta ser decidida automaticamente pelo programa. Portanto, quando o operador liga o equipamento, a corrente é detectada na entrada, o programa abre o GATE correspondente, fecha os demais GATES e aciona o relé que liga o aspirador.
• Quando o equipamento é desligado, o sensor detecta a ausência de corrente e dá um delay para desligar o aspirador usando o relé. Logo após o delay, o programa verifica novamente se há a presença de corrente e, caso detectada, o programa deixa o GATE aberto e não desliga o relé. Isso dá a chance ao operador de desligar a entrada rapidamente para algum ajuste sem que tenha a necessidade de desligar a aspiração, otimizando o processo. No entanto, se após desligar a entrada o operador não religar dentro do tempo, o relé será desligado e o GATE fechado.

Portanto, existem dois delays:

1) O primeiro antes de ligar a aspiração (ex: 2000 ms)
2) O segundo depois do desligamento da entrada para desligar o relé e fechar o GATE (ex: 5000 ms).

Neste segundo delay, há a chance de o operador religar rapidamente, antes do fim do tempo, para seguir em funcionamento.

Blog-Eletrogate-ResumoEsquematicodoProjeto

Figura 1 – Resumo Esquemático do Projeto

Figura 2 – Diagrama do Projeto


Vídeo demonstrativo

A demonstração é conferida em https://youtu.be/cufE_NUeAPA.

Versão V1.6 Ago/2023


Observações

1) Duas fontes de alimentação foram previstas para evitar interferências: uma fonte externa alimenta o Arduino (5VDC/1A) e a segunda o regulador de tensão garantindo 12VDC/3A regulando para 5 VDC para os servos exclusivamente. Opcionalmente, a tensão de saída pode ser ajustada para 6V para permitir o torque máximo dos servos. Obs.: A parte lógica da controladora de servos é alimentada pela porta de 5V do Arduino.
2) Tivemos certa dificuldade com a precisão das leituras do sensor ACS712. Às vezes detectávamos leituras altas sem haver uma corrente de entrada. Para contornar esse problema, adotamos um valor residual para a corrente. Somente valores acima são considerados, uma vez que os equipamentos usados consomem uma corrente muito maior. A tratativa do ACS712 é que ocasionou as várias versões do programa pois tivemos que experimentar diferentes bibliotecas e até mesmo a leitura direta das portas analógicas.
3) Na versão 6, passamos a usar um receptor IR com teclado remoto para permitir dar comandos ao sistema. A seguir, estão os valores que a variável atual_IR pode ter:

-1 ➔ nenhum botão pressionado
0 | 1 | 2 ➔ botão que foi pressionado correspondente ao GATE e às teclas 1, 2 ou 3 do controle remoto
3 ➔ botão para acionar os 3 GATES simultaneamente e correspondente à tecla “*” do controle
4 ➔ botão para acionar o Relé e correspondente à tecla # do controle

A varredura dos ACS712 é feita por “polling” respeitando um tempo de delay para os sensores retornando os seguintes valores:

-1 ➔ se nenhum sensor c/ corrente
1 | 2 | 3 ➔ se ligou sensor 1 ou 2 ou 3
-1 |-2 |-3 ➔ se desligou sensor 1 ou 2 ou 3

Blog-Eletrogate-Prototipo

Figura 3 – Protótipo em bancada

Blog-Eletrogate-Blastgate e Servomotor

Figura 4 – Detalhe do Blast Gate X Servo


Código

//------------------------------------------------------------------------------------------------------------------------
// Componentes : 1) Placa Arduino Nano (escolhido por questão de espaço mas poderia ser um UNO)
//               2) 1 x Regulador de Tensão LM2596
//               3) 1 x Controlador de Servos 16 Canais PCA9685
//               4) 1 x Receptor IR + 1 x Controle Remoto
//               5) 3 x Sensores de corrente ACS712 20 A
//               6) 1 x Relé, 1 Canal, 5 V para acionar uma carga de 15 A / 127 V  ou 10 A / 220 V
//               7) 1 x Fonte 12 V / 3 A
//               8) 1 x Protoboard 400 pontos
//               9) 1 x WorkPlate de 400
//              10) 3 x Servos MG-995 (13 Kg/cm de torque)
//              11) 3 x Blast Gate 5,3 cm + mangueiras articuladas para interligação com o aspirador
//              12) 1 x Buzzer para sinalizar/alarmar situações da operação
//              13) 1 x Ciclone para reter a maior parte do resíduo, facilitando o descarte e a economia de filtros do aspirador
//              14) Jumpers
//
// Bibliotecas : Adafruit_PWMServoDriver   => instalada pelo gerenciador de bibliotecas
//               ACS712                    => instalada pelo gerenciador de bibliotecas
//               IRremote                  => instalada pelo gerenciador de bibliotecas
//                
// Fontes      : Consultamos diversos vídeos/artigos/documentações na Internet sobre Servos, uso do ACS712, 
//               sobre interrupções, receptor RF e ideias de como transformar o torque do servo para abrir
//               e fechar os BLAST GATES. O ChatGPT também foi consultado em algumas situações, dicas de 
//               erros, sintaxes, dicas de bibliotecas, etc. 
//      
// Motivação   : O meu filho Alberto estudou e morou nos USA por 7 anos e observou que muitos
//               americamos tinham, como o hobby, o hábito de montar marcenarias nas garagens ou porões das
//               suas casas. Ele acabou se interessando pelo hobby e começou a estudar as diferentes
//               automações que os americanos implementavam visando deixar o ambiente limpo sem 
//               esforço manual. Desde de sistemas bastante manuais, com o uso de aspiradores que tinham
//               que ser conduzidos nos quatro cantos do local para aspirar o pó, até sistemas com grau
//               intermediário de automação, como por exemplo, coleta centralizada do pó, porém com o 
//               acionamento manual do aspirador e abertura/fechamento dos BLAST GATES manualmente, etc. 
//               Ele pesquisou também sistemas com arduino usando teclado para acionar servos abrindo/fechando 
//               BLAST GATES e até sistemas usando detecção de corrente, porém para apenas um equipamento de entrada. 
//               A partir de tais exemplos, ele teve a ideia de especificar um projeto com as melhores práticas que 
//               ele observou juntando tudo num projeto mais abrangente e híbrido, permitindo o máximo de decisão 
//               pelo próprio sistema, mas com certo grau de automomia para o operador através do uso de RF para
//               minimizar o deslocamento no ambiente e sem restrições de distâncias por causa do maior alcance do RF. 
//               Daí, juntamos para dar sequência ao projeto...  
//                            
// Objetivos   : Sistema para automatização da coleta de resíduos de madeira de uma marcenaria:
//                  . São esperadas 3 entradas de equipamentos geradores de resíduo. A tomada elétrica
//                    de cada equipamento de entrada é dotada de um sensor de detecção de corrente ligada ao 
//                    arduino nas portas analógicas.
//                  . Os equipamentos de entrada são conectados com dutos até um duto central ligado ao aspirador 
//                    central e fixo. 
//                  . Cada equipamento de entrada tem uma porta de comunicação com o duto central, 
//                    com BLAST GATE contrololado por um SERVO para abrir/fechar a entrada.
//                  . Somente um equipamento de entrada deve ser ativado por vez e apenas a sua porta
//                    de comunicação com a coleta deve estar aberta para não haver perda de eficiência
//                    na sucção pelo aspirador. Esta foi uma decisão de projeto, dadas as especificações do aspirador.
//                  . A abertura da porta foi inicialmente pensada para ser decidida pelo operador através do uso de um
//                    controle remoto IR : 3x teclas para abrir/fechar cada porta, 4a. tecla para fechar/abrir todas a  
//                    3x portas e a 5a. tecla para ligar/desligar o Relé. Posteriormente, modificamos para a abertura 
//                    da porta ser decidida automaticamente pelo programa. Portanto, quanto a corrente é detectada
//                    na entrada (o operador liga o equipamento), o programa abre o GATE correspondente, fecha os demais
//                    GATES e aciona o relé. 
//                  . Quanto o equipamento é desligado, o sensor detecta a ausência de corrente e dá um 
//                    delay para desligar o aspirador usando o relé. Logo após o delay, o programa verifica 
//                    novamente se há a presença de corrente e, caso detectada, o programa deixa o GATE aberto e 
//                    não desliga o relé. Isso dá a chance ao operador de desligar a entrada rapidamente 
//                    para algum ajuste antes de desligar a aspiração, otimizando o processo. No entanto,
//                    se após desligar a entrada o operador não religar dentro do tempo, o relé será desligado
//                    e o GATE fechado definitivamente.
//                  . Portanto, existem dois delays: 
//                 
//                    1) o primeiro antes de ligar a aspiração(ex: 2000 ms)
//                    2) o segundo depois do desligamento da entrada para desligar o relé e fechar o GATE (ex: 5000 ms).
//                       Neste segundo delay, há a chance do operador religar rapidamente, antes da fim do tempo, para
//                       seguir em funcionamento.
//  
// Observações  : 1) Duas fontes de alimentação foram previstas para evitar interferências: uma fonte externa alimenta o 
//                   arduíno (5VDC/1A) e a segunda o regulador de tensão garantindo 12VDC/3A regulando para 5 VDC 
//                   para os servos exclusivamente. Opcionalmente, a tensão de saída pode ser ajustada para 6 V para 
//                   permitir o torque máximo dos servos. 
//                   Obs: A parte lógica da controladora de servos é alimentada pela porta de 5V do arduino.
//                2) Na versão 6, passamos a usar um receptor IR para permitir dar comandos ao sistema.
//                   A seguir, estão os valores que a variável Atual_IR, pode ter:
//
//                   -1             => nenhum botão pressionado
//                    0 | 1 | 2     => botão que foi pressionado correspondente ao GATE e às teclas 1, 2, 3 do controle remoto
//                    3             => botão para acionar os 3 GATES simultaneamente e correspondente à tecla * do controle
//                    4             => botão para acionar o Relé, correspondente à tecla # do controle
//
//                3) A varredura dos ACS712 é feita por polling respeitando um tempo de delay para os sensores retornando os
//                   seguintes valores:
//
//                   -1             => se nenhum sensor c/ corrente
//                    1 | 2 | 3     => se ligou sensor 1 ou 2 ou 3
//                   -1 |-2 |-3     => se desligou sensor 1 ou 2 ou 3 
//
// Autores       : Alberto de Almeida Menezes
//                 Dailton de Oliveira Menezes
//
// Versão        : V1.6 Ago/2023   
//------------------------------------------------------------------------------------------------------------------------

// Inclusão de Bibliotecas

#include <Wire.h>                        // Biblioteca usada pelo Servo
#include <Adafruit_PWMServoDriver.h>     // Bibliotreca para os servos 
#include "ACS712.h"                      // Biblioteca para o ACS712
#include <IRremote.h>                    // Biblioteca para o Receptor IR

// Definição de Pinagem

#define pinRele        7                  // Pino do Relé
#define pinIR          11                 // Pino do receptor IR
#define pinBuzzer      12                 // Pino do Buzzer ativo

// Definições de Constantes

//#define DEBUG                           // Para debugar mensagens na console
#define NUM_GATES      3                  // Número de Gates (Servos)
#define intervalo      100                // Define um intervalo de 100 msec entre acionamentos Motores
#define Ciclo          2000               // Intervalo em mseg para a varredura ACS712
#define alarmeBreve    20                 // Define 20 mseg para alarme breve
#define alarmeLeve     200                // Define 200 mseg para alarme leve
#define alarmeGrave    1000               // Define 1000 mseg para alarme grave 
#define rangePorta     1024               // Range da porta Analógica de 10 bits
#define RELE_ON_DELAY  2000               // Delay antes de ligar o relé
#define RELE_OFF_DELAY 5000               // Delay antes de desligar o relé
#define ReleOFF        HIGH               // Define o nível para desligar o Relé
#define ReleON         LOW                // Define o nível para ligar o Relé
#define Max_Leituras   500                // N. de leituras para detectar a corrente no ACS712

// Definições das teclas do teclado do IR

#define tecla_1        0xBA45FF00         // Abre/fecha Servo_1
#define tecla_2        0xB946FF00         // Abre/fecha Servo_2
#define tecla_3        0xB847FF00         // Abre/fecha Servo_3
#define tecla_ast      0xE916FF00         // Abre/fecha todos gates
#define tecla_tag      0xF20DFF00         // Liga/Desliga Relé

// Definição do receptor IR

IRrecv irrecv(pinIR);                     // Objeto para tratar o IR 

// Definição do controlador de servos usados para abrir/fechar os BlastGates

Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver(); // Controlador dos servos

// Definição dos ACS712's  => último parãmtero pode ser: para 5A=185, 20A=100, 30A=66

ACS712 ACS[NUM_GATES] = { 
                           ACS712(A0, 5.0, 1023, 100), 
                           ACS712(A1, 5.0, 1023, 100), 
                           ACS712(A2, 5.0, 1023, 100)
                        };

// Definição de Variáveis Globais

int atual_Sensor=0;                       // Atual Sensor com corrente => 0, 1 ou 3
int atual_IR;                             // Atual tecla IR pressionada
bool estado_IR[5] = {LOW, LOW, LOW, LOW, LOW}; // Estado das teclas do controle IR
int angle[] = {179,0};                    // Angulo de giro do Servo
int estadoRele = ReleOFF;                 // Estado inicial do Relé (desligado)
float correnteResidual = 236;             // Corrente a ser desprezada equivalente a um equipamento de 30 W (P=0,236*127)
float lastCorrente[] = {0.0,0.0,0.0};     // corrente nos ACS712's
int tensao = 127;                         // Tensão nominal da rede AC 127 volts
uint32_t start_time;                      // Primeiro momento da varredura
long lastVarredura=0;                     // Última varredura dos ACS712 

// Prototipação de Funções

void writeServos(int posicao, int tempo); // função para movimentar um servo unitário
void beginServos();                       // inicialiação do controlador de servos
void atualizaServo(int posicao);          // movimenta um servo e fecha os demais
int checkSensores();                      // verifica se ligou algum equipamento na entrada
void alarme(int tempo);                   // Soa o alarme (buzzer)
float getCorrente(int porta);             // Pega a corrente do sensor 
void varreduraIR();                       // Faz a varredura da RF e toma a decisão sobre o comando recebido

//-----------------------------------------------
// Inicialização da Aplicação
//-----------------------------------------------

void setup() 
{

  // Inicialização da Serial
  
  Serial.begin(115200);
  while (!Serial);  

  // Inicializa o IR

  irrecv.enableIRIn();

  // Hello na Console
  
  Serial.println("Dust Collection V1.6 Ago/2023");
  
  #ifdef DEBUG
  Serial.println(__FILE__);
  Serial.print("ACS712_LIB_VERSION: ");
  Serial.println(ACS712_LIB_VERSION);  
  #endif
  
  Serial.print("Corrente Residual (mA) : ");
  Serial.println(correnteResidual);
  Serial.print("Número de Gates : ");
  Serial.println(NUM_GATES);

  // Inicializa ACS712's

  for (int ind=0;ind<NUM_GATES;ind++)
  {
    ACS[ind].autoMidPoint(); 
  }
  
  // Inicializa o Relé 

  pinMode(pinRele, OUTPUT);           // Porta de saída
  digitalWrite(pinRele, estadoRele);  // Relé inicialmente DESLIGADO 

  // Inicializa os servos

  beginServos();  // Inicializa o gerenciador de servos

  // Seta a posição inicial do servo
  
  for (int ind=0;ind<NUM_GATES;ind++)
  {
     writeServos(4*ind,angle[estado_IR[ind]]);  
  }  

  // Inicializa o Buzzer 

  pinMode(pinBuzzer, OUTPUT);         // Porta do Buzzer

  // Soa o alarme para avisar que o setup completou
  
  alarme(alarmeLeve);                 // Avisa o início  

  // Inicializa lastVarredura para forçar esperar um ciclo antes de ler os sensores ACS712

  lastVarredura = millis();  

}

//-----------------------------------------------
// Loop Principal da Aplicação
//-----------------------------------------------

void loop() 
{

  // Faz a varredura IR para saber se alguma tecla foi pressionada e executar a função

  varreduraIR();

  // verifica se está no clico de varredura dos ACS712

  if (millis()-lastVarredura>Ciclo)
  {
  
    // Verifica os sensores de corrente

    atual_Sensor = checkSensores();
    
    if (atual_Sensor != 0) 
    {
       #ifdef DEBUG
       Serial.print("atual_Sensor: ");
       Serial.println(atual_Sensor);
       #endif 
   
       // Trata o sensor detectado ligado(+) ou desligado(-)
  
       if (atual_Sensor < 0)
       {
          // Desligou, procede o desligamento do relé
          
          estadoRele = ReleOFF;
          digitalWrite(pinRele, estadoRele);  // Relé desligado 
  
          // Avisa na console independente do modo DEBUG e fecha o GATE 

          atual_IR = abs(atual_Sensor)-1;    
            
          Serial.print("Relé desligado, GATE[");  
          Serial.print(atual_IR);
          Serial.println("] fechado");   
          estado_IR[atual_IR]=LOW;  
          writeServos(4*atual_IR,angle[estado_IR[atual_IR]]);
         
       }
       else
       {
          // Vamos abrir o Gate correspondente e fechar os demais

          atual_IR = abs(atual_Sensor)-1; 
          
          estado_IR[atual_IR]=HIGH;  
          atualizaServo(atual_IR);
   
          // Podemos acionar o Relé para ligar o aspirador antes dando um tempo para o equipamento
             
          delay(RELE_ON_DELAY);
          estadoRele = ReleON;
          digitalWrite(pinRele, estadoRele);  // Relé ligado
  
          // Avisa na console independente do modo DEBUG
          
          Serial.print("Relé ligado, GATE[");  
          Serial.print(atual_IR);
          Serial.println("] aberto");    
  
       }
      
    }

    lastVarredura = millis();

  }

}

//-----------------------------------------------
// Função para posicionar um servo específico
//-----------------------------------------------

void writeServos(int nServo, int posicao) {
#define SERVOMIN  80                      // VALOR PARA UM PULSO MAIOR QUE 1 mS
#define SERVOMAX  470                     // VALOR PARA UM PULSO MENOR QUE 2 mS

  int pos = map ( posicao , 0 , 180 , SERVOMIN, SERVOMAX);
  pwm.setPWM(nServo , 0, pos);

  #ifdef DEBUG
  Serial.print("N.Servo: ");
  Serial.print(nServo);
  Serial.print("\tAngle:");
  Serial.println(posicao);
  #endif
  
}

//-----------------------------------------------
// Função para inicialização do objeto PVM
//-----------------------------------------------

void beginServos() {

#define Frequencia 50                     // VALOR DA FREQUENCIA DO SERVO 

  pwm.begin();                            // INICIA O OBJETO PWM
  pwm.setPWMFreq(Frequencia);             // DEFINE A FREQUENCIA DE TRABALHO DO SERVO
}

//-----------------------------------------------
// Movimenta um servo e recolhe os demais
//-----------------------------------------------

void atualizaServo(int posicao)
{
   for (int ind=0;ind<NUM_GATES;ind++)
   {
      if (ind!=posicao)
      {
          estado_IR[ind] = !estado_IR[posicao];       // inverte o estado
          writeServos(4*ind,angle[estado_IR[ind]]);   // controle PWM do servo (1 por banco de 4) 
          #ifdef DEBUG
          Serial.print("Desativando Servo ");       // imprime Servo desativado
          Serial.println(ind);                      // imprime o id do servo 
          #endif
          delay(intervalo);                         // Dá um break           
      }
   }

   writeServos(4*posicao,angle[estado_IR[posicao]]);  // controle PWM do servo 
   #ifdef DEBUG
   Serial.print("Atualizando Servo ");                // imprime Servo atualizado
   Serial.println(posicao+1);                         // imprime o id do servo
   #endif 
 
}

//---------------------------------------------------
// Verifica se algum equipamento foi ligado
//---------------------------------------------------
// Retorna: -1         se nenhum sensor c/ corrente
//           1 | 2 | 3 se ligou sensor 1 ou 2 ou 3
//          -1 |-2 |-3 se desligou sensor 1 ou 2 ou 3
//---------------------------------------------------

int checkSensores()
{
  
   // Inicializações para a varredura

   float atualCorrente[NUM_GATES];
   int result = 0;

   // Obtém as correntes nos 3 sensores

   for (int ind=0;ind<NUM_GATES;ind++)
   {
     atualCorrente[ind] = getCorrente(ind); 
     #ifdef DEBUG
     Serial.print("A"); Serial.print(ind); Serial.print("=");Serial.print(atualCorrente[ind]); Serial.print(" ");
     #endif      
   }

   #ifdef DEBUG
   Serial.println();
   #endif 
   
   // Procura a primeira entrada que mudou de estado para retornar 
   // Supondo que somente uma entrada será ligada de cada vez pelo operador

   for (int ind=0;ind<NUM_GATES;ind++)
   {

      if (lastCorrente[ind] != 0.0 && atualCorrente[ind] == 0.0) 
      {
         result = -(ind+1);     // desligou
         Serial.print("Corrente Anterior (mA): ");
         Serial.println(lastCorrente[ind],3);    

         // Vamos aguardar um tempo para ver se o operador vai voltar a ligar a corrente para evitar desligar o Relé
         // Isso otimiza o desligamento do Relé e da permanência do Gate aberto (consume tempo) e permite ao 
         // operador desligar rapidamente a entrada, ajustar algo e religar sem afetar o Gate e o relé.

         for (start_time = millis();millis()-start_time<RELE_OFF_DELAY;);

         // Depois do tempo, volta a pegar a corrente do sensor

         atualCorrente[ind] = getCorrente(ind);

         // Verifica se há corrente
         
         if (atualCorrente[ind]!=0.0) 
         {
            // Voltou a ligar num intervalo pequeno, logo vamos permanecer ligados (Relé+Gate aberto)
            result = 0;
         }
         
         break;
      }
      else if (lastCorrente[ind] == 0.0 && atualCorrente[ind] != 0.0) 
      {
         result = ind+1;      // ligou
         Serial.print("Corrente Atual (mA): ");
         Serial.println(atualCorrente[ind],3);  
         break;
      }
      else result = 0;       // continua ligado ou desligado => não mudou de estado

   }

   // Mostra as leituras das correntes nas entradas e salva 

   for (int ind=0;ind<NUM_GATES;ind++)
   {
      // Mostra a Corrente

      #ifdef DEBUG
      Serial.print("Corrente[");
      Serial.print(ind);
      Serial.print("] : ");
      Serial.print(atualCorrente[ind], 3);
      Serial.print(" A ");  
      #endif 
    
      // Mostra o valor da potência

      #ifdef DEBUG
      Serial.print(" Potência[");
      Serial.print(ind);
      Serial.print("] : ");
      Serial.print(atualCorrente[ind] * tensao / 1000);
      Serial.println(" Watts ");
      #endif

      // Guarda como última leitura

      lastCorrente[ind] = atualCorrente[ind];

   }

   return result;
}

//-----------------------------------------------
// Soa o buzzer por um tempo fornecido
//-----------------------------------------------

void alarme(int tempo)
{
   digitalWrite(pinBuzzer,HIGH);
   delay(tempo);
   digitalWrite(pinBuzzer,LOW);  
}

//----------------------------------------------------
// Obtém a corrente no sensor da porta fornecida em mA
// Porta: índice da porta: 0, 1, 2, ...
//----------------------------------------------------

float getCorrente(int porta)
{

   float result = ACS[porta].mA_AC();
   return result <= correnteResidual ? 0.0 : result;
   
}

//----------------------------------------------------
// Faz a varredura do IR e trata comando recebido
//----------------------------------------------------

void varreduraIR()
{

  // Varredura do Receptor IR

  #ifdef DEBUG
  Serial.println("Varreura IR");
  #endif  

  if (irrecv.decode())                                          // se algum código for recebido
  {
      
      uint32_t tecla = irrecv.decodedIRData.decodedRawData;     // recupera a tecla pressionada no IR
      
      switch(tecla)
      {
        case tecla_1   : alarme(alarmeBreve);
                         atual_IR = 0;
                         break;
        case tecla_2   : alarme(alarmeBreve);
                         atual_IR = 1;
                         break; 
        case tecla_3   : alarme(alarmeBreve);
                         atual_IR = 2;
                         break;  
        case tecla_ast : alarme(alarmeBreve);
                         atual_IR = 3;
                         break;                                                      
        case tecla_tag : alarme(alarmeBreve);
                         atual_IR = 4;
                         break;                      
        default        : atual_IR = -1;
                         break; 
      } 
      irrecv.resume();                                           // reinicializa o receptor
  }  
  else atual_IR = -1;

  // Trata o botão selecionado

  switch(atual_IR)
  {
     case -1 : // não selecionou nada
        break;
     case  4 : // selecionou a tecla # ligar/desligar o Relé manualmente
        estadoRele = !estadoRele;
        estado_IR[atual_IR]=estadoRele;
        digitalWrite(pinRele, estadoRele);
        Serial.print("Relé: ");
        Serial.println(estadoRele == ReleOFF ? "desligado" : "ligado");        
        alarme(alarmeLeve); // soa o alarme só para atentar o operador
        break;
     case  3 : // selecionou a tecla * abrir/fechar todos os servos
        if (estadoRele==ReleOFF)
        {
           estado_IR[atual_IR]=!estado_IR[atual_IR];
           writeServos(0,angle[estado_IR[atual_IR]]); 
           estado_IR[0] = estado_IR[atual_IR];
           writeServos(4,angle[estado_IR[atual_IR]]);
           estado_IR[1] = estado_IR[atual_IR];
           writeServos(8,angle[estado_IR[atual_IR]]);
           estado_IR[2] = estado_IR[atual_IR];
           Serial.print("Gates: ");
           Serial.println(estado_IR[atual_IR] ? "abertos" : "fechados");           
        }
        else 
        {
           alarme(alarmeGrave); // só pode abrir/fechar os BlastGates antes de ligar a entrada
           Serial.println("Erro: o Relé/Aspirador deve estar desligado para acionar os GATEs");
        }
        break;        
     default: // selecinou as teclas 1, 2 ou 3 do controle
        estado_IR[atual_IR] = !estado_IR[atual_IR];
        if (estadoRele==ReleOFF)
        {
           writeServos(4*atual_IR,angle[estado_IR[atual_IR]]);
           Serial.print("Gate[");
           Serial.print(atual_IR);
           Serial.print("] ");
           Serial.println(estado_IR[atual_IR] ? "aberto" : "fechado");
        } 
        else 
        {
           alarme(alarmeGrave); // só pode abrir/fechar o BlastGate antes de ligar a entrada
           Serial.println("Erro: o Relé/Aspirador deve estar desligado para acionar o GATE");
        }
        break;
  }

}

Fontes

Consultamos diversos vídeos/artigos/documentações na Internet sobre servos, Relés, uso do ACS712, sobre interrupções, receptor RF e ideias de como transformar o torque do servo para abrir e fechar os BLAST GATES. O ChatGPT também foi consultado em algumas situações, dicas de erros, sintaxes, dicas de bibliotecas etc.

Seguem algumas das fontes que utilizamos:

Assunto: ACS712
How To Make A Simple Switch To Automatically Turn On Shop Vac
Como usar o sensor de corrente ACS712 com Arduino
Projeto 35 – Sensor de Corrente ACS712 com ESP32-DOIT – Projetos Jetsons
Current measurement – ESP32 using acs712 give wrong values – Electrical Engineering Stack Exchange
Interface ACS712 with ESP32 and ADS1115.
ACS712 Current Sensor Tutorial with Arduino (Sensing DC and AC Current)

Assunto: Relé
DIY Smart Switch – Part 2 Motion Activated Relay
Control AC Devices with Arduino SAFELY – Relays & Solid State Switches
Ponte H com relés: Como montar – Blog Eletrogate
Módulo Relé para Automação Residencial com Arduino – Blog Eletrogate

Assunto: Servo
How to Connect Multiple Servo Motor With Microcontroller – Instructables

Assunto: Dust Collection
Dust Collection for Newbies: Introduction to Dust Collection
Fully Automated Dust Collection powered by Arduino // How To | I Like To Make Stuff
How to control your dust collection with an Arduino (it’s easy) | I Like To Make Stuff

Assunto: IR
Guia Completo do Controle Remoto IR + Receptor IR para Arduino – Blog Eletrogate


Sobre os Autores


Alberto de Almeida Menezes
tinho.menezes@gmail.com

Bacharel em Engenharia de Áudio e Produção Musical pela Berklee College of Music.


Dailton de Oliveira Menezes
dailton.menezes@gmail.com

Bacharel em Ciência da Computação pela Universidade Federal de Minas Gerais.


Eletrogate

5 de outubro de 2023

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.

Tenha a Metodologia Eletrogate dentro da sua Escola! Conheça nosso Programa de Robótica nas Escolas!

Eletrogate Robô

Cadastre-se e fique por
dentro de novidades!