Interrupção do dimmer interferindo no envio de sinal IR

Pessoal, saudações. Estou tentando combinar em um mesmo projeto de automação residencial um dimmer e um controle remoto IR. Separadamente ambos funcionam sem problemas, mas ao ativar a interrupção do zero cross, o sinal do IR, quando enviado, sai todo embaralhado e sem padrão (no caso utilizo o NEC e o RC6). Creio que o problema resida no fato de o envio do sinal de IR ser uma sequência de "marks" e "spaces" na ordem de milisegundos e a interrupção do dimmer interferir por ser ativada várias vezes durante o envio do sinal de IR. Se no momento de enviar o código IR a interrupção for desligada e ligada logo em seguida ao envio, funciona, mas ai o dimmer "pisca". Exemplo:

if (bufferSerial == "A"){detachInterrupt(0);irsend.send(1,0x2FD48B7,32); attachInterrupt(0, zero_crosss_int, RISING); enviou =1; delay(5);} // código NEC(1) TV para ligar

Estou utilizando a biblioteca IRLib que é baseada na IRRemote para envio do IR. Esta biblioteca utiliza o Timer 2 no pino 3 como padrão e o Timer 1 no pino 9 opcionalmente, para enviar o sinal para o led IR. Alguém tem alguma sugestão de como posso resolver este problema?

  

Exibições: 463

Responder esta

Respostas a este tópico

Caro Fernando. Eu gostaria de pelo menos entender seu problema mas sem ver as rotinas de interrupção fica difícil. Uma regra eu sei: NÃO UTILIZE I/Os dentro delas, por exemplo, Serial.print, etc.

Almir, bom dia.

Seguem as rotinas. Anexei também o esquema da PCI com os componentes.

Se a linha do setup() que ativa a interrupção for comentada, o IR funciona normalmente.

Se nas linhas de envio for desativada a interrupção do dimmer também funciona:

Exemplo: if (bufferSerial == "A"){detachInterrupt(0);irsend.send(1,0x2FD48B7,32); attachInterrupt(0, zero_crosss_int, RISING); enviou =1; delay(5);} // código NEC(1) TV para ligar

A conexão serial com a placa é feita pelo modulo BT HC-05.

Grato pelo interesse.

#include <IRLib.h>
#include <IRLibMatch.h>
#include <IRLibRData.h>
#include <IRLibTimer.h>


//definições dimmer
int ZERO = 2; // pino de interrupção do zero cross
int AC_LOAD = 10; // Output para o Triac
volatile int dimming = 100; // Dimming level (0-128) 0 = ON, 128 = OFF
String ValorDimmer;

//definições do Receptor IR
IRsend irsend; //instância para enviar IR
const int led = 8; // pino do led de indicação de envio IR
const int ledIR = 3; //pino do emissor IR


//variaveis do temporizador para temperatura
int savedTime;
int totalTime = 0;

//variaveis leitura serial
String bufferSerial = "";
int numero; //contador para alterar a potencia do dimmer
int enviou; //flag para indicar que foi enviado codigo IR

void setup()
{
Serial.begin(9600);

//ir
pinMode(led, OUTPUT); // saida led
pinMode(ledIR ,OUTPUT); // saída do infravermelho

//dimmer
pinMode(ZERO, INPUT);
pinMode(AC_LOAD, OUTPUT);// Set AC Load pin as output
attachInterrupt(0, zero_crosss_int, RISING); //zero-crossing - interrupção
numero = dimming; //inicializa a leitura da serial com o mesmo valor do dimming

//inicia temporizador que atualiza temperatura
savedTime = millis();
delay(100);

}


void loop()
{
//atualiza temperatura no intervalo de "totaltime"
int passedTime = millis() - savedTime;
if (passedTime > totalTime)
{
//temperatura LM35
int sum=0;
for (int i = 0; i < 50; i++) sum += analogRead(A5);
int media = (sum * 0.48875855) / 50;
savedTime = millis(); //
totalTime = 5000; //Seta para 5seg
}

bufferSerial = "";
while (Serial.available()>0)
{
enviou = 0;
char c = Serial.read(); // Lê byte do buffer serial;
bufferSerial.concat(c); // Concatena valores
delay(5);
if (c == '@') break; // se leu o caracter @ sai do loop. Este caracter é enviado pela rotina do celular
}

if (bufferSerial.length()>0 && bufferSerial.length()<2 && !enviou) { //verifica se informação que chegou esta entre 1 e 2 caracteres (para futuras implementações)

digitalWrite(led, HIGH); //acende o led indicador de envio de IR / comando

if (bufferSerial == "A"){irsend.send(1,0x2FD48B7,32); enviou =1; delay(5);} // código NEC(1) TV para ligar
if (bufferSerial == "B"){irsend.send(1,0x2FD7887,32); enviou =1; delay(5);} // código NEC(1) TV para diminuir o volume
if (bufferSerial == "C"){irsend.send(1,0x2FD58A7,32); enviou =1; delay(5);}// código NEC(1) TV para aumentar o volume
if (bufferSerial == "D"){irsend.send(1,0x2FDA857,32); enviou =1; delay(5);}// código NEC(1) TV para timer
if (bufferSerial == "E"){irsend.send(1,0x2FD08F7,32); enviou =1; delay(5);}// código NEC(1) TV para mute
if (bufferSerial == "M"){irsend.send(7,0x34347887,32);enviou =1; delay(5);} // código NECx(7) HTLG para ligar/desligar
if (bufferSerial == "N"){irsend.send(7,0x34346897,32);enviou =1; delay(5);} // código NECx(7) HTLG para baixar o volume
if (bufferSerial == "O"){irsend.send(7,0x3434e817,32);enviou =1; delay(5);}// código NECx(7) HTLG para aumentar o volume
if (bufferSerial == "P"){irsend.send(7,0x343451AE,32);enviou =1; delay(5);}// código NECx(7) HTLG para selecionar o source
if (bufferSerial == "Q"){irsend.send(7,0x343459A6,32);enviou =1; delay(5);}// código NECx(7) HTLG para abrir o deck
if (bufferSerial == "R"){irsend.send(7,0x343415EA,32);enviou =1; delay(5);} // código NECx(7) HTLG para mudar de estação / seleção -
if (bufferSerial == "S"){irsend.send(7,0x3434956A,32);enviou =1; delay(5);} // código NECx(7) HTLG para mudar de estação / seleção +
if (bufferSerial == "T"){irsend.send(7,0x343455AA,32);enviou =1; delay(5);}// código NECx(7) HTLG como enter
if (bufferSerial == "U"){irsend.send(7,0x343420DF,32);enviou =1; delay(5);}// código NECx(7) HTLG como play
if (bufferSerial == "V"){irsend.send(7,0x3434F20D,32);enviou =1; delay(5);}// código NECx(7) HTLG como pause
if (bufferSerial == "X"){irsend.send(7,0x3434609F,32);enviou =1; delay(5);} // código NECx(7) HTLG como skip -
if (bufferSerial == "Y"){irsend.send(7,0x3434E01F,32);enviou =1; delay(5);}// código NECx(7) HTLG como skip +
}

//se o comando possui mais de 2 caracteres então é para o dimmer
if (bufferSerial.length()>2){
bufferSerial.trim(); //elimina possiveis espaços
if (bufferSerial.substring(0,2) == "#L") numero = numero+5; //incrementa contador do dimmer para diminuir potencia
if (bufferSerial.substring(0,2) == "#H") numero = numero-5; //decrementa contador do dimmer para aumentar potencia
if (numero >= 15 && numero <= 128) //se contador estiver abaixo ou acima dos limites do dimmer mantém a ultima leitura
dimming=numero; else dimming=dimming;
}
digitalWrite(led, LOW); //apaga o led indicador de envio de IR / comando
}

// função disparada pelo zero-crossing
void zero_crosss_int()
{
int dimtime = (65*dimming); // For 60Hz =>65
delayMicroseconds(dimtime); // Off cycle
digitalWrite(AC_LOAD, HIGH); // triac firing
delayMicroseconds(8.33); // triac On propogation delay 10ms for 60Hz use 8.33)
digitalWrite(AC_LOAD, LOW); // triac Off
}

Anexos

RSS

© 2024   Criado por Marcelo Rodrigues.   Ativado por

Badges  |  Relatar um incidente  |  Termos de serviço