08 agosto 2013

Ligando uma lâmpada com relé e push button

Neste artigo anterior sobre como ligar uma lâmpada utilizando relé, eu mostrei como ligar um relé ao Arduino, utilizando transistor, diodo e resistor. O programa exemplo acionava o relé, aguardava 5 segundos, desligava o relé, aguardava mais 5 segundos, e repetia o processo.

Seguindo a sugestão de alguns leitores, vou usar o mesmo circuito como base, e mostrar o acionamento do relé via push button, ou seja, cada vez que o botão é pressionado, o estado do led é alterado, acendendo e apagando conforme o controle do usuário. Veja no vídeo abaixo o circuito em funcionamento :



Antes do circuito, vamos apenas recapitular a "lista de material" que utilizei anteriormente :

  • Rele 5v
  • 1 Diodo 1N4007 (ou similar)
  • 1 Transistor BC548 (ou equivalente NPN)
  • 2 resistores de 10 K
  • Led

e vamos acrescentar :

  • 1 push button
  • 1 resistor 330 ohms

Com o material em mãos, vamos ao circuito, que como citei anteriormente, é o mesmo do artigo anterior, agora com um push button ligado à porta 2 do Arduino :

Circuito Arduino Relé push button
Também usei o programa anterior como base, acrescentando uma rotina que inverte o estado do relé conforme o botão é pressionado :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
// Programa : Acionamento de rele utilizando push button
// Autor : Arduino e Cia

int sinalparaorele = 4; //define a porta para o acionamento do rele
int pinobotao = 2;    //Porta utilizada para o botão de acionamento
int leitura;          //Armazena informações sobre a leitura do botão
int estadorele = 0;   //Armazena o estado do relé (ligado/desligado)

void setup()
{
  //Define o pino como saida (sinal para o rele)
  pinMode(sinalparaorele, OUTPUT); 

  //Define o pino como entrada (Pino do botao)
  pinMode(pinobotao, INPUT);      
  // digitalWrite(sinalparaorele, 0);
}

void loop()
{
  leitura = digitalRead(pinobotao);
  if (leitura != 1)
  {
    while(digitalRead(pinobotao) != 1)
    {
      delay(100);
    }
    // Inverte o estado
    estadorele = !estadorele;
    digitalWrite(sinalparaorele, estadorele);  
  } 
}

E finalmente, se você precisar utilizar este mesmo esquema e programa para acionar uma lâmpada, use a ligação abaixo :

Circuito Arduino relé lâmpada
Essa é apenas uma opção de uso de botão para acionamento do relé. Conforme as suas necessidades, o botão pode ser facilmente substituído por uma chave, um sensor ou a entrada pode até mesmo ser acionada via bluetooth, como neste artigo, onde explico como utilizar um celular Android para controlar o Arduino, via bluetooth.


43 comentários:

  1. Muito bom o tópico, exatamente o que eu precisava. Os meu teste foram mais fáceis pois tenho um rele shield.
    Por curiosidade, por que vc usa o while, é para ter um efeito similar ao debouncig?

    ResponderExcluir
    Respostas
    1. Obrigado Murilo !

      Eu usei este while pois o acionamento do botão é muito instável, ou seja, ele pode mudar de estado várias vezes enquanto você está apertando ou desapertando o botão, e isso iria acender e apagar o led várias vezes no mesmo acionamento. Como eu queria que o botão mudasse o estado somente cada vez que é pressionado, eu coloquei o while para "lembrar" o estado do botão e evitar que o led acenda de forma errada. Espero não ter complicado. rs. Abraço !

      Excluir
  2. Muito bom o tutorial! Mas tenho uma pegunta,se eu quisesse acionar com uma tecla do meu pc ao invés do push button, como eu faria. Abraco

    ResponderExcluir
    Respostas
    1. Boa noite João,

      É perfeitamente possível. Você pode criar um programa que acesse a saída serial conectada ao Arduino e faça o envio e recebimento de informações. Eu já criei alguma coisa desse tipo, mas já faz algum tempo, e preciso retomar esse assunto.

      Abraço !

      Excluir
    2. E vc tem esse código criado pelo pc?

      Excluir
  3. Olá...

    Sou novo com o Arduino e se possível você poderia comentar o pedaço do código?
    Não entendi o uso do != 1
    void loop()
    {
    leitura = digitalRead(pinobotao);
    if (leitura != 1)
    {
    while(digitalRead(pinobotao) != 1)
    {
    delay(100);
    }
    estadorele = !estadorele;
    digitalWrite(sinalparaorele, estadorele);
    }
    }

    ResponderExcluir
    Respostas
    1. Boa noite,

      Esse pedaço do código, mais especificamente o "!=1" é um operador de comparação, que verifica se o botão foi pressionado e foi para o nível 0 / Low.

      O primeiro pedaço do código apenas verifica se o botão foi pressionado :

      if (leitura != 1)

      A linha com o while executa um loop enquanto o botão estiver pressionado, evitando que algum ruído durante o pressionamento do botão inverta o estado da saída sem necessidade :

      while(digitalRead(pinobotao) != 1)
      {
      delay(100);

      Espero ter ajudado. Qualquer dúvida, deixe msg, por favor.

      Abraço !

      Excluir
  4. mano o meu ide deu um erro na hora de copila no int pinobotao = 2; pq

    ResponderExcluir
  5. mano eu ão to conseguindo montar esse circuito pelo proteus me ajudem . por favor presciso muito aprender esse acionamento

    ResponderExcluir
    Respostas
    1. Bom dia Victor !

      Com qual parte você está tendo dificuldade ?

      Abraço.

      Excluir
  6. e no caso de eu querer ligar 3 leds e 3 push button, oque tem que alterar?

    ResponderExcluir
    Respostas
    1. Boa tarde Atila,

      No circuito, basta você replicar o circuito e ligar tanto o relé/transistor, led e botão em portas diferentes.

      No programa, basta você replicar a informação sobre variáveis, leitura de portas, etc, 3 vezes. Vai ficar mais ou menos assim :

      // Programa : Acionamento de rele utilizando push button
      // Autor : Arduino e Cia

      //Rele1
      int sinalparaorele1 = 4; //define a porta a ser utilizada para o acionamento do rele
      int pinobotao1 = 2; //Porta utilizada para o botão de acionamento
      int leitura1; //Armazena informações sobre a leitura do botão
      int estadorele1 = 0; //Armazena o estado do relé (ligado/desligado)

      //Rele2
      int sinalparaorele2 = 5; //define a porta a ser utilizada para o acionamento do rele
      int pinobotao2 = 3; //Porta utilizada para o botão de acionamento
      int leitura2; //Armazena informações sobre a leitura do botão
      int estadorele2 = 0; //Armazena o estado do relé (ligado/desligado)

      //Rele3
      int sinalparaorele3 = 6; //define a porta a ser utilizada para o acionamento do rele
      int pinobotao3 = 7; //Porta utilizada para o botão de acionamento
      int leitura3; //Armazena informações sobre a leitura do botão
      int estadorele3 = 0; //Armazena o estado do relé (ligado/desligado)

      void setup()
      {
      pinMode(sinalparaorele1, OUTPUT); //Define o pino como saida (sinal para o rele)
      pinMode(pinobotao1, INPUT); //Define o pino como entrada (Pino do botao)

      pinMode(sinalparaorele2, OUTPUT); //Define o pino como saida (sinal para o rele)
      pinMode(pinobotao2, INPUT); //Define o pino como entrada (Pino do botao)

      pinMode(sinalparaorele3, OUTPUT); //Define o pino como saida (sinal para o rele)
      pinMode(pinobotao3, INPUT); //Define o pino como entrada (Pino do botao)
      }

      void loop()
      {
      leitura1 = digitalRead(pinobotao1);
      if (leitura1 != 1)
      {
      while(digitalRead(pinobotao1) != 1)
      {
      delay(100);
      }
      estadorele1 = !estadorele1;
      digitalWrite(sinalparaorele1, estadorele1);
      }

      leitura2 = digitalRead(pinobotao2);
      if (leitura2 != 1)
      {
      while(digitalRead(pinobotao2) != 1)
      {
      delay(100);
      }
      estadorele2 = !estadorele2;
      digitalWrite(sinalparaorele2, estadorele2);
      }

      leitura3 = digitalRead(pinobotao3);
      if (leitura3 != 1)
      {
      while(digitalRead(pinobotao3) != 1)
      {
      delay(100);
      }
      estadorele3 = !estadorele3;
      digitalWrite(sinalparaorele3, estadorele3);
      }
      }

      Abraço !

      Excluir
  7. Mas eu preciso do codigo do programa de android para acionar e qual deveria ser

    ResponderExcluir
    Respostas
    1. Boa noite Thales,

      Por favor dê uma olhada neste artigo, creio que tem o que você precisa :

      http://www.arduinoecia.com.br/2013/03/acionando-portas-do-arduino-usando.html

      Abraço !

      Excluir
  8. Olá, gostaria de saber para que o diodo e o transistor estão no circuito, se pudesse me explicar a funcionalidade deles. Obrigado

    ResponderExcluir
    Respostas
    1. Boa tarde Otávio,

      Esses componentes formam o circuito de proteção, evitando danos ao Arduino. O transistor amplifica o sinal , que na porta do Arduino é de 50mA, evitando que o relé "puxe" mais corrente do que o necessário. O diodo, por sua vez, evita que sobrecargas de energia voltem para o Arduíno, danificando a porta.

      Em linhas gerais (e resumidas), é isso. Espero ter ajudado. abraço !

      Excluir
    2. Na verdade a função do diodo é de criar um curto-ciruito impedindo sobretensões geradas pela fem (força eletromotriz) induzida pela redução da corrente na bobina. Milhões de pessoas deterioram seus circuitos, principalmente relés, utilizando somente diodo. O correto é isolar a parte de comando com optoacopladores e colocar em oposição ao diodo, um diodo zener, de tal modo que a maxima tensão suportada por ele fique em função da maxima tensão suportada entre coletor e emissor do transistor que excita o relé.

      Excluir
  9. qual o motivo de usar a resistencia na chave, só como referencia 0 para arduino?
    usei sem ele e funciona enviando a tensão.
    Como estou usando rele de 12 V, não posso aproveitar a alimentação e enviar 12 V na porta do arduino?

    ResponderExcluir
    Respostas
    1. Boa tarde Ayres,

      Exatamente. O resistor na chave serve como referência 0.

      Quanto aos 12v, se você estiver falando das portas, não será possível ligar, pois o nível de tensão suportado pelo Arduino é de 5v.

      Se você estiver falando da porta de alimentação externa do Arduino, OK, você pode aproveitar esses 12v para alimentar a placa.

      Abraço !

      Excluir
  10. Como eu sei qual é o NO e o NC do meu relé ?

    ResponderExcluir
    Respostas
    1. Boa noite,

      Se você souber qual o pino C (comum), pode simplesmente testar com um led, como eu fiz no circuito, ou até mesmo com um multímetro.

      Abraço !

      Excluir
  11. Poderia explicar o motivo de vc ter colocado o resistor 330 omhs no push button? Não é a mesma coisa sem ele?

    ResponderExcluir
    Respostas
    1. Boa tarde,

      Não, se você não colocar o resistor, o valor da porta pode oscilar entre 0 e 1, gerando "falsos positivos", como se estivesse acionando o botão.

      O resistor está ligado ao GND, funcionando como um resistor pull-down, ou seja, quando o botão não está sendo pressionado, garantimos (ou forçamos) que o valor lido na porta do Arduino é 0.

      Abraço !

      Excluir
  12. Olá, como eu poderia fazer no codigo pra que uma pressionada no botao o circuito fique ligado e com outra pressionada ele desliga. Assim eu nao preciso ficar pressionando o botao para o circuito ficar ligando... abraço

    ResponderExcluir
  13. Como eu poderia mudar o codigo para que com um click no botao o circuito continuasse ligado ate eu dar outro click para desliga-lo? abraço

    ResponderExcluir
    Respostas
    1. Boa noite Gabriel,

      O circuito mostrado no post já faz isso.

      Abraço !

      Excluir
  14. Boa noite, como eu faço para que além do botão eu conseguisse controlar pelo monitor serial também? Obrigado.

    ResponderExcluir
    Respostas
    1. Bom dia,

      Veja este código de exemplo, que controla o LED da porta 13. L liga o led, e D apaga. Você pode adaptar esse programa para o seu projeto:

      // Programa: Controle de lampada pelo serial monitor
      // Autor: Arduino e Cia

      //Armazena o caracter recebido
      char buf;

      void setup()
      {
      //Define o pino 13 como saida
      pinMode(13, OUTPUT);
      Serial.begin(9600);
      Serial.println("Aguardando dados...");
      }

      void loop()
      {
      while(Serial.available() > 0)
      {
      buf = Serial.read();
      //Caso seja recebido o caracter L, acende o led
      if (buf == 'L')
      {
      digitalWrite(13, HIGH);
      Serial.println("Lampada acesa");
      }
      //Caso seja recebido o caracter D, apaga o led
      if (buf == 'D')
      {
      digitalWrite(13, LOW);
      Serial.println("Lampada apagada");
      }
      }
      }

      Abraço !

      Excluir
  15. Boa tarde, só consegui fazer funcionar de um modo ou de outro, segue código.

    // Programa : Acionamento de rele utilizando push button
    // Autor : Arduino e Cia

    int sinalparaorele = 5; //define a porta para o acionamento do rele
    int pinobotao = 2; //Porta utilizada para o botão de acionamento
    int leitura; //Armazena informações sobre a leitura do botão
    int estadorele = 0; //Armazena o estado do relé (ligado/desligado)
    char buf;

    void setup()
    {
    Serial.begin(9600);
    //Define o pino como saida (sinal para o rele)
    pinMode(sinalparaorele, OUTPUT);

    //Define o pino como entrada (Pino do botao)
    pinMode(pinobotao, INPUT);
    // digitalWrite(sinalparaorele, 0);
    Serial.println("Aguardando dados...");
    }

    void loop()
    {
    serial();
    botao();

    }

    void botao(){
    leitura = digitalRead(pinobotao);
    if (leitura != 1)
    {
    while(digitalRead(pinobotao) != 1)
    {
    delay(100);
    }
    // Inverte o estado
    estadorele = !estadorele;
    digitalWrite(sinalparaorele, estadorele);
    }
    }


    void serial() {
    while(Serial.available() > 0) {
    buf= Serial.read();
    if(buf=='a') {
    // Inverte o estado
    estadorele = !estadorele;
    digitalWrite(sinalparaorele, estadorele);
    Serial.println(estadorele);
    }
    }
    }

    ResponderExcluir
    Respostas
    1. Boa tarde,

      Antes de mais nada, parabéns por ter tentado. :-)

      Aqui também não funcionou, então fiz algumas alterações no programa. Dê uma olhada, que eu acho que agora ficou legal. Eu usei a porta 13 para testar o programa com o led:

      // Programa : Acionamento de rele utilizando push button
      // Autor : Arduino e Cia

      int sinalparaorele = 13; //define a porta para o acionamento do rele
      int pinobotao = 2; //Porta utilizada para o botão de acionamento
      int leitura; //Armazena informações sobre a leitura do botão
      int estadorele = 0; //Armazena o estado do relé (ligado/desligado)
      char buf;

      void setup()
      {
      Serial.begin(9600);
      //Define o pino como saida (sinal para o rele)
      pinMode(sinalparaorele, OUTPUT);

      //Define o pino como entrada (Pino do botao)
      pinMode(pinobotao, INPUT);
      // digitalWrite(sinalparaorele, 0);
      Serial.println("Aguardando dados...");
      }

      void loop()
      {
      leitura = digitalRead(pinobotao);
      if (leitura != 0)
      {
      while (digitalRead(pinobotao) != 0)
      {
      delay(100);
      }
      // Inverte o estado
      estadorele = !estadorele;
      digitalWrite(sinalparaorele, estadorele);
      }

      if (Serial.available()) {
      buf = Serial.read();
      if (buf == 'a') {
      // Inverte o estado
      estadorele = !estadorele;
      digitalWrite(sinalparaorele, estadorele);
      Serial.print("Estado rele: ");
      Serial.println(estadorele);
      }
      }
      }

      Excluir
    2. É isso ai, funcionou. Neste caso já podemos acender e apagar a lâmpada ( ou led) pelo botão ou pelo celular, esta é a melhor forma também para mostrar na tela do celular o status da lâmpada? mostrando o valor 0 ou 1.

      Excluir
    3. Boa tarde,

      Sim. Você só precisa arrumar uma maneira do celular receber esses dados (bluetooth, wifi, etc).

      Abraço !

      Excluir
  16. ola parabens pelo trabalho.
    tenho uma duvida.
    como consigo ligar e desligar a msm lampada com a msm letra!?
    ex. mandar a letra "a" ai liga e se mandar a letra "a" d novo ai desliga!!
    como consigo fazer isso!?
    mto obg desde ja.

    ResponderExcluir
    Respostas
    1. Oi Chris,

      Você quer fazer isso pela serial ?

      Abraços !

      Excluir
  17. Bom dia!

    Gostaria de saber como faço para ligar o rele com um botao e desligar com outro.

    não sei a programação.

    Obrigado por enquanto.

    ResponderExcluir
  18. Olá! Como ficaria o "código" utilizando um "IR Controle Remoto", para obter esse mesmo resultado? Preciso fazer um acionamento por "IR Controle Remoto", em que a carga só está em funcionamento enquanto o botão está pressionado. Obrigado!

    ResponderExcluir
  19. Olá! Em caso de falha no arduíno, continuarei tendo controle do acendimento da lampada pelo interruptor?

    ResponderExcluir
    Respostas
    1. Bom dia,

      Se você ligar o relé em paralelo com o interruptor, pode continuar usando normalmente.

      Abraço!

      Excluir
  20. OLA PARABÉNS PELO SEU TRABALHO, NO MEU TCC EU QUERO A HORA QUE APERTAR O BOTÃO ELE CONTE 5 MINUTOS E DESLIGUE, EU USEI SEU CÓDIGO PODE ME DIZER SE ESTÁ CORRETA A LÓGICA? DESDE JA AGRADEÇO

    //Porta ligada ao pino do modulo
    int porta_rele1 = 7;
    //Porta ligada ao botao 1
    int porta_botao1 = 2;


    //Armazena o estado do rele - 0 (LOW) ou 1 (HIGH)
    int estadorele1 = 1;
    //Armazena o valor lido do botão
    int leitura1 = 0;

    void setup()
    {
    //Define pino para o rele como saida
    pinMode(porta_rele1, OUTPUT);
    //Define pinos dos botoes como entrada
    pinMode(porta_botao1, INPUT);
    //Estado inicial do rele - desligados
    digitalWrite(porta_rele1, HIGH);
    }

    void loop()
    {
    //Verifica o acionamento do botao 1
    leitura1 = digitalRead(porta_botao1);
    if (leitura1 != 0)
    {
    while(digitalRead(porta_botao1) != 0)
    {
    delay(5000);
    digitalWrite(porta_rele1, LOW);
    }
    //Inverte o estado da porta
    estadorele1 = !estadorele1;
    //Comandos para o rele 1
    digitalWrite(porta_rele1, estadorele1);
    }
    }

    ResponderExcluir
  21. Amigo, fiz uma ligação via infra vermelho e queria ligar o relé pela mesma tecla, fiz o codigo porem com 2 teclas(uma para ligar e outra desligar). Como posso incrementar com esse codigo seu para ficar na mesma.

    Pika relativa do codigo:


    #include

    int RECV_PIN = 11;
    float armazenavalor;
    int pinoledvermelho = 5;
    int pinoledverde = 7;

    IRrecv irrecv(RECV_PIN);
    decode_results results;

    void setup()
    {
    pinMode(pinoledvermelho, OUTPUT);
    pinMode(pinoledverde, OUTPUT);
    Serial.begin(9600);
    irrecv.enableIRIn(); // Inicializa o receptor IR
    }

    void loop()
    {
    if (irrecv.decode(&results))
    {
    Serial.print("Valor lido : ");
    Serial.println(results.value, HEX);
    armazenavalor = (results.value);
    if (armazenavalor == 0xFF30CF) //Verifica se a tecla 1 foi acionada
    {
    digitalWrite(pinoledvermelho, HIGH); //Acende o led vermelho
    }
    if (armazenavalor == 0xFF18E7) //Verifica se a tecla 2 foi acionada
    {
    digitalWrite(pinoledvermelho, LOW); //Apaga o led vermelho
    }
    if (armazenavalor == 0xFF10EF) //Verifica se a tecla 4 foi acionada
    {
    digitalWrite(pinoledverde, HIGH); //Acende o led verde
    }
    if (armazenavalor == 0xFF38C7) //Verifica se a tecla 5 foi acionada
    {
    digitalWrite(pinoledverde, LOW); //Apaga o led verde
    }
    if (armazenavalor == 0xFF52AD) //Verifica se a tecla 9 foi acionada
    {
    digitalWrite(pinoledvermelho, LOW); //Apaga todos os leds
    digitalWrite(pinoledverde, LOW);
    }
    irrecv.resume(); //Le o próximo valor
    }
    }

    ResponderExcluir
  22. Olá, gostaria de saber se este circuito aceita a ligação de 2 relês de 5v no mesmo pino de saida do transistor??
    Eles irão ser acionado em conjunto por 15 minutos, 220v em 2 fases de 110v ??

    ResponderExcluir
    Respostas
    1. Boa tarde,

      Não fiz esse teste, mas eu recomendo um circuito para cada relé.

      Abraço!

      Excluir