Problema em acionar um Rele

Boa Tarde pessoal

Estou com um problema grave em acionar um rele... fiz um código de batidas de sinal para a minha empresa... ou seja... a cada horário programado aciona uma sirene , buscando a hora via NTP do servidor da empresa... O problema é que a o acionar o rele o Arduíno parece que da um reset e a saída do rele acaba não acionando... se eu pegar o fio IN do rele e colocar diretamente na saida 5v ocorre o mesmo problema.

Parece que a fonte não tem forca para ligar o rele e acaba desligando todo o sistema.

abaixo segue o código
Apos o acionamento do rele tem um delay de 4 segundos e acontece um reset do Arduíno para efetuar uma nova busca de hora no servidor.
o modulo rele que estou usando e um JQC-3FF-S-Z


#include <SPI.h>
#include <Ethernet.h>
#include <EthernetUdp.h>

// Enter a MAC address for your controller below.
// Newer Ethernet shields have a MAC address printed on a sticker on the shield
byte mac[] = {
  0xAA, 0xFF, 0xAA, 0xEF, 0xFE, 0xED
};


unsigned int localPort = 8888;       // local port to listen for UDP packets

const char timeServer[] = "195.173.32.5"; // time.nist.gov NTP server

const int NTP_PACKET_SIZE = 48; // NTP time stamp is in the first 48 bytes of the message

byte packetBuffer[NTP_PACKET_SIZE]; //buffer to hold incoming and outgoing packets

// A UDP instance to let us send and receive packets over UDP
EthernetUDP Udp;

int led = 7;

void setup() {
   pinMode(led, OUTPUT);//Define o pino como saida.
  // You can use Ethernet.init(pin) to configure the CS pin
  //Ethernet.init(10);  // Most Arduino shields
  //Ethernet.init(5);   // MKR ETH shield
  //Ethernet.init(0);   // Teensy 2.0
  //Ethernet.init(20);  // Teensy++ 2.0
  //Ethernet.init(15);  // ESP8266 with Adafruit Featherwing Ethernet
  //Ethernet.init(33);  // ESP32 with Adafruit Featherwing Ethernet

  // Open serial communications and wait for port to open:
  Serial.begin(9600);

  
   digitalWrite(led, LOW);//Apaga o LED.
  
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }

  // start Ethernet and UDP
  if (Ethernet.begin(mac) == 0) {
    Serial.println("Failed to configure Ethernet using DHCP");
    // Check for Ethernet hardware present
   
    // no point in carrying on, so do nothing forevermore:
    while (true) {
      delay(1);
    }
  }
  Udp.begin(localPort);
}

String Hora;
String Min;
String Sec;
String Final;
long Zeromin ;
long Zerosec ;


long UTC = 3600;

void loop() {
  sendNTPpacket(timeServer); // send an NTP packet to a time server

  // wait to see if a reply is available
  delay(1000);
  if (Udp.parsePacket()) {
    // We've received a packet, read the data from it
    Udp.read(packetBuffer, NTP_PACKET_SIZE); // read the packet into the buffer

    // the timestamp starts at byte 40 of the received packet and is four bytes,
    // or two words, long. First, extract the two words:

    unsigned long highWord = word(packetBuffer[40], packetBuffer[41]);
    unsigned long lowWord = word(packetBuffer[42], packetBuffer[43]);
    // combine the four bytes (two words) into a long integer
    // this is NTP time (seconds since Jan 1 1900):
    unsigned long secsSince1900 = highWord << 16 | lowWord;
  //  Serial.print("Seconds since Jan 1 1900 = ");
  //  Serial.println(secsSince1900);

    // now convert NTP time into everyday time:

    // Unix time starts on Jan 1 1970. In seconds, that's 2208988800:
    const unsigned long seventyYears = 2208988800UL;
    // subtract seventy years:
    unsigned long epoch = secsSince1900 - seventyYears;
    // print Unix time:
// Serial.println(epoch);


    // print the hour, minute and second:
    //Serial.print("The UTC time is ");       // UTC is the time at Greenwich Meridian (GMT)
   //    Serial.print("Aqui --->");
       epoch = epoch - 10800;
  //  Serial.println(epoch);
   // Serial.print((epoch  % 86400L) / UTC); // print the hour (86400 equals secs per day)
  //  Serial.print(':');
  
    if (((epoch % UTC) / 60) < 10) {
      // In the first 10 minutes of each hour, we'll want a leading '0'
      Zeromin = 0;
    // Serial.print(Zeromin);
    }
    Min = (epoch  % UTC) / 60;
    
   // Serial.print(Min); // print the minute (3600 equals secs per minute)
   // Serial.print(':');
    
    if ((epoch % 60) < 10) {
      // In the first 10 seconds of each minute, we'll want a leading '0'
      Zerosec = 0;
  //  Serial.print(Zerosec);
       }
    Sec = epoch % 60 ;
  //  Serial.println(epoch % 60 ); // print the second
//      ############################################################################################
    Hora = ((epoch  % 86400L) / UTC)  ; 

 
 

    Final = Hora + ":" + Min + ":" + Sec ;

 Serial.println("O de baixo e o certo");
 Serial.println(Final);
       
   if (Final == "5:57:0" ) tocar(); 
   if (Final == "6:0:0" ) tocar(); 
   if (Final == "6:57:0" ) tocar(); 
   if (Final == "7:0:0" ) tocar(); 
   if (Final == "11:0:0" ) tocar(); 
   if (Final == "11:15:0" ) tocar(); 
   if (Final == "11:30:0" ) tocar(); 
   if (Final == "11:45:0" ) tocar(); 
   if (Final == "11:48:0" ) tocar(); 
   if (Final == "12:0:0" ) tocar(); 
   if (Final == "12:3:0" ) tocar(); 
   if (Final == "12:15:0" ) tocar(); 
   if (Final == "12:18:0" ) tocar(); 
   if (Final == "12:30:0" ) tocar(); 
   if (Final == "12:33:0" ) tocar(); 
   if (Final == "12:48:0" ) tocar(); 
   if (Final == "13:3:0" ) tocar(); 
   if (Final == "13:18:0" ) tocar(); 
   if (Final == "16:0:0" ) tocar(); 
   if (Final == "17:0:0" ) tocar(); 
  
  
  }
  
  // wait ten seconds before asking for the time again
 // delay(500);
  Ethernet.maintain();
}

// send an NTP request to the time server at the given address

void tocar()
{
 digitalWrite(led, HIGH);
 delay(4000);
 digitalWrite(led, LOW);
delay(1000);
 asm volatile ("  jmp 0");


  
}

void sendNTPpacket(const char * address) {
  // set all bytes in the buffer to 0
  memset(packetBuffer, 0, NTP_PACKET_SIZE);
  // Initialize values needed to form NTP request
  // (see URL above for details on the packets)
  packetBuffer[0] = 0b11100011;   // LI, Version, Mode
  packetBuffer[1] = 0;     // Stratum, or type of clock
  packetBuffer[2] = 6;     // Polling Interval
  packetBuffer[3] = 0xEC;  // Peer Clock Precision
  // 8 bytes of zero for Root Delay & Root Dispersion
  packetBuffer[12]  = 49;
  packetBuffer[13]  = 0x4E;
  packetBuffer[14]  = 49;
  packetBuffer[15]  = 52;

  // all NTP fields have been given values, now
  // you can send a packet requesting a timestamp:
  Udp.beginPacket(address, 123); // NTP requests are to port 123
  Udp.write(packetBuffer, NTP_PACKET_SIZE);
  Udp.endPacket();
}

Ja usei esse sistema por muito tempo... vez ou outra acontecia esse problema... mas agora esta acontecendo seguidamente

Boa tarde tiagocamana

O que pode estar ocorrendo é comum quando chaveamos cardas indutivas.
Provavelmente esta sirene tem um rotor para girar. E motor é carga indutiva.
Uma carga indutiva ao ligar ou desligar gera ruídos elétricos de alta frequência.
O arduino tem eletrônicos muito sensíveis a ruídos elétricos.

As soluções por ordem de maior importância são as seguintes.

  1. Colocaçõa de um "snubber " em paralelo aos contatos do rele que operam a sirene;

Snubber – Wikipédia, a enciclopédia livre.

  1. Definir todos ports do arduino que não está sendo usado como "OUTPUT", inclusive os analógicos.
  2. Colocar o arduino dentro de uma caixa metálica aterrada.

Depois conta se resolveu.

RV mineirin

Caro amigo ruilviana , Existe alguma outra forma mais simples??? se não qual os valores do capacitor e do resistor?? nao entendi muito bem aonde o snubber é ligado... e na saida do rele?? ou seja 220v???

Bom dia @tiagocamana
os valores do snubber devem ser calculados para cada projeto.
Nunca usei estas planilhas, mas acho que elas podem ajudar.

O recomendado é usar o snubber em paralelo com os contato do rele.

RV mineirin

Olá,

Qual é o Arduino, o Arduino Uno?

Como o Arduino liga à rede local? Através de um Ethernet Shield ou Wi-Fi?

Pelo que percebi a sirene funciona a 220 VAC. Qual a corrente que a sirene consome? Ou qual a potência em Watts? Este parâmetro deve estar indicado na sirene...

O snubber que o ruilviana mencionou pode resolver o problema. O snubber é colocado nos contactos do relé, por isso , os componentes do snubber têm de suportar os 220V...

Edit: Teste accionar o relé sem a sirene. Se o Arduino faz o reset antes do click do accionamento do relé, então o snubber não deve ter efeito...

Caso o snubber não resolva, o problema pode dever-se à queda de tensão no circuito de alimentação do Arduino no momento do accionamento do relé. O regulador de tensão do Arduino pode não conseguir manter a tensão nos 5V no momento do accionamento do relé. Se a tensão baixar muito pode resultar num reset. Nesse caso se o relé for alimentado à parte por outro adaptador, neste caso de 5V, pode resolver a situação

Algumas sugestões (não relacionadas com o problema).

Parece que o Arduino obtém o tempo acedendo a cada segundo ao servidor NTP. O ideal seria usar o servidor NTP apenas para acertar o relógio esporadicamente. A data e hora podem ser mantidas através de um RTC (Real Time Clock) por software, ou melhor ainda usando um módulo RTC por hardware.

No Arduino a função loop() é repetida, ciclicamente, ao terminar a última instrução. Não parece fazer muito sentido usar o "jump 0" para voltar ao início do código. O "jump 0" não faz um reset efectivo ao microcontrolador, apenas volta à primeira instrução do programa.

Se fosse eu, utilizaria um RTC (hardware ou software) e acertava o relógio ao iniciar o Arduino e a cada x dias de utilização. Depois a cada minuto o Arduino poderia verificar a hora/minuto e actuar a sirene caso coincida com uma das horas.

tinyelectr

Obrigado por sua colaboração

Sim e o Arduino UNO , Ligo via internet shield.
Informações da sirene:
Tensão: 220V
» Potência: 75W
» Frequência: 50/60 Hz
» Peso: 0,415 Kg

Vou tentar fazer esses testes que comentou...

Sei que meu código não esta correto que o certo seria o uso do RTC e sincronizar de tempos em tempos... mas usei por muito tempo dessa forma e funciona excepcionalmente bem, único empecilho e o problema relatado acima.

Grato

Efetuei o teste de acionar o rele sem estar a sirene na energia(220VAC) e o Arduíno trabalhou bem, não ocasionando mais o problema, retornei a ligar a sirene na tomada e voltou o problema...

Meu conhecimento em eletrônica e minimo, alguém pode me ajudar a dimensionar os componentes?

encontrei no mercadolivre

sera que é valido??

Bom, nesse caso o snubber deve resolver a situação.

Para dimensionar um snubber seria necessário conhecer a indutância da carga (o que pode ser complicado) e seria bom também ter a possibilidade de analisar a tensão nos contactos do relé ao accionar a carga (usando um osciloscópio com sondas adequadas).

Para a aplicação em questão esse snubber genérico deverá solucionar o problema. Parece tratar-se de um condensador de 100 nF com uma resistência em série de 220 Ohm, existindo ainda um varistor em paralelo com o snubber para suprimir os picos/transientes de tensão. À primeira vista, tudo adequado para 220 VAC. Nada como testar :slight_smile: