Olá galera!

Estou trabalhando no Dimmer Digital utilizando Arduino, mas para sincronizar o disparo de um TRIAC com a forma de onda da rede elétrica utilizamos um circuito detector de passagem por zero volts, onde a cada passagem da onda por zero volts é gerada uma interrupção (INT0) no ATMEGA, ou seja, temos uma interrupção a cada 8,33 ms do ciclo da senoide. E é aí que está o problema, pois como pretendo utilizar também um controle remoto (IR) para aumentar ou diminuir o brilho da lâmpada então estou tendo conflito com a biblioteca IRremote.h, que também utiliza de interrupção para atender o "apertar do botão" do controle remoto.

Bem, minha dúvida é a seguinte como fazer para usar o dimmer acionado por um controle remoto se ambos utilizam interrupções no Arduino? Já testei utilizar uma interrupção por hardware e outra por software, mas também não funcionou.

Espero que alguém aqui da comunidade possa me dar um luz sobre como solucionar esse problema.

Grato

Hugney M. Ferreira

(61) 9962-7070

 

 

Exibições: 5881

Anexos

Responder esta

Respostas a este tópico

Voce nao precisa utilizar a interrupacao para capturar 60hz, um psimples pino do pic pega isso, na verdade voce ira capturar 120 pontos 0V, eu tb estou trabalhando em um projeto de um dimmer digital, o meu ja funcionou e nem usei interrupçao, usei porta analogica para pegar o 0V e da li em diante escolher o angulo de disparo. alex_sander_2011@hotmail.com.br add ai que a noite trocamos algumas informações importantes

Bem, meu circuito eletrônico já está definido e nele não estou utilizando PIC. Por isso preciso de uma solução no software e não no hardware.

Grato

Hugney M. Ferreira

(61) 9962-7070

Amigo veja a sua pergunta:

" Bem, minha dúvida é a seguinte como fazer para usar o dimmer acionado por um controle remoto se ambos utilizam interrupções no Arduino? Já testei utilizar uma interrupção por hardware e outra por software, mas também não funcionou."

Eu te respondi 

"Voce nao precisa utilizar a interrupacao para capturar 60hz", um simples pino do pic(microcontrolador) pega isso, na verdade voce ira capturar 120 pontos 0V(frequencia baixa nao necessita interrupcao externa), eu tb estou trabalhando em um projeto de um dimmer digital, o meu ja funcionou e nem usei interrupçao, usei porta analogica para pegar o 0V( neste trecho te falei que funciona 100%)e da li em diante escolher o angulo de disparo.(aqui é contigo)  alex_sander_2011@hotmail.com.br add  ai que a noite trocamos algumas informações importantes (me prontifiquei a ajudar e explicar se necessario);

Arduino e PIC muito parecidos.

Resumindo- leia o trecho entre asppas que voce vera a sua solucao, se o teu problema esta com as interrupcoes ja te falei, e ja fiz um dimmer com pic e tb com arduino em ambos utilizando porta analogica para captura do ponto zero, a parti dai e só programação, porta analogica != interrupção externa , interrupção foi feita para pegar frequencias rapidas na casa de 1khz, alguns ate na casa de 100khz , analogica pega nivel de tensao no pino , quando a analogica esta em 0 ali é o ponto, fica a dica.

"Por mais que na batalha se vença a um ou mais inimigos, a vitória sobre a si mesmo é a maior de todas as vitórias."

Ok Alex, peguei seu e-mail para conversarmos melhor à noite.

Grato

Hugney M. Ferreira

(61) 9962-7070

Alex poderia me passar algumas dicas e algum exemplo do dimmer que fez com PIC , foi no CCS? meu e-mail : ilgner_becheleni@hotmail.com

Algumas dicas que serão mais valiosas que o código funcionando...

Na hora que escrever o codigo, coloque uma descrição simples e concisa e em apenas uma linha à frente do código, isso ajuda a manter o código claro.

Antes do AttachInterrupt você escreve uma nota sobre o funcionamento da função, não faça isso, acaba tirando o o raciocinio logico do programa, imprima o artigo da função desejada e mantenha ao lado para consulta. 

Declare todos os dados no começo do sketch...   ex.: #define VolUP 2640455895 ou ainda unsigned long VolUP 2640455895

Dê um passo de cada vez, primeiro faça o "engine" do dimmer funcionar redondo, depois adicione o potenciometro, depois o controle remoto...

Fazer o dimmer com interrupções + a biblioteca IRremote é possivel, você só tem que saber quais timers a biblioteca e o core do arduino usam, o que estiver ocioso.

No seu codigo dentro do loop, você compara o codigo recebido e depois manda o codigo como argumento para a função velocidade que dentro dela compara novamente o  mesmo codigo, Crie funções para cada tecla do controle remoto, e compare com um switch/case...

Dar o codigo pronto é complicado, não se aprende... o problema que não deixa funcionar o seu codigo é realmente o delay dentro da interrupção que literalmente pára o arduino...

[receita]

pegue um timer ocioso,

configure o prescaler do timer para que estoure acima de 9, mas o mais proximo possivel(dará mais resolução), mas deixe ele desligado.

calcule quantos ticks(do timer com prescaler) tem em 8.33ms

se o timer for de 8bits tire esse valor de 255 se for de 16bit tire de 65535 e guarde o resultado 

[continua amanhã pois estou indo embora do serviço]

 

Olá Fabio,

O motivo desse programa ter várias notas é porque utilizo ele para objetivos institucionais em nossos cursos, o que torna o programa um complemento da apostilha.

Quanto a dar uma passo de cada vez, isso também já foi feito. Na verdade meu Dimmer funciona perfeitamente somente com o potenciomentro. Porém eu estava exatamente querendo incrementá-lo deixado de fazer o controle do brilho da lâmpada através de um simples potenciometro e utilizar um controle remoto.

Não tenho nenhum problema de interrupção com esse meu código quando o utilizo apenas com o potenciometro, porém quando acrescento o IR começo a ter, haja visto que a biblioteca do IR também utiliza de interrupções, e é exatamente a solução desse caso que estou buscando aqui na Comunidade.

Grato

Hugney M. Ferreira

(61) 9962-7070 

"O motivo desse programa ter várias notas é porque utilizo ele para objetivos institucionais em nossos cursos, o que torna o programa um complemento da apostilha."

Eu sou hobbista em eletronica/programação, já fui novato, e te falo que quanto mais florido o código, maior o trabalho de assimilação do funcionamento do código e o que é necessário reter/relevar(isso confunde a cabeça de quem nunca viu um sketch)... Se o material é utilizado para aprendizado, deve-se aumentar a clareza do texto/código, o reference do arduino é um bom exemplo à seguir... 

"Quanto a dar uma passo de cada vez, isso também já foi feito. Na verdade meu Dimmer funciona perfeitamente somente com o potenciomentro. Porém eu estava exatamente querendo incrementá-lo deixado de fazer o controle do brilho da lâmpada através de um simples potenciometro e utilizar um controle remoto.

Não tenho nenhum problema de interrupção com esse meu código quando o utilizo apenas com o potenciometro, porém quando acrescento o IR começo a ter, haja visto que a biblioteca do IR também utiliza de interrupções, e é exatamente a solução desse caso que estou buscando aqui na Comunidade."

Hugney, esse sketch(do potenciometro) foi ajustado até funcionar, como uma obra de arte, qualquer outro acréscimo de material(codigo) tira a funcionalidade dele... ex: Se você fizesse uso do millis para contar tempo, ele seria mais longo que o normal pois o delay do de interrupções impede o tratamento de outras/consecutivas interrupções,  como a do millis a cada 1ms.

Esse sketch que postou nem compila por causa de resquícios de testes e variaveis indicando outros usos  e coisas como esta:

valorCodigo = resultados.value, DEC; //armazena o código

PS. Não se ofenda como a forma que expus a minha opinião, o que falo é tudo que funcionou/funciona comigo, e o mesmo talvez não será verdade para outros. Com relação ao tom da conversa, que o computador torna rispida e impessoal, para mim seria uma conversa numa mesa de bar com um chopinho do lado :)

   

  • Já testei varios sketchs que perambulam pela internet, inclusive com millis e nada de funcionar perfeitamente como esse que eu fiz

  • Eu mesmo fiz os cálculos da regra de detecção por passagem por zero e por isso tenho total controle sobre esse trecho do programa
  • Ou seja, com o Potenciometro o programa funciona como um brinco

  • Se o problema está no trecho do IR, então como posso enxugá-lo para não dar conflito com a interrupção já utilizada para detectar a passagem por zero da onda quando eu apertar a tecla do controle remoto?
  • Pois esse trecho do programa IR eu também já utilizei para controlar motores e também funcionou perfeitamente

Para dar prosseguimento ao assunto, fiz um codigo em cima do que passou, não tenho à mão o MOC3021 para testar, aqui compilou sem nenhum erro, mas creio que ainda carece de ajustes...

#include <IRremote.h>
#include <avr/interrupt.h>

#define VolDOWN 2640488535 //codigo tecla controle remoto
#define VolUP 2640455895 //codigo tecla controle remoto

int rIR = 11; //pino do sensor IR
int triac = 13; //pino Triac
unsigned int maxTimer = 65235; //65535 - (150e-6 / ( 62.5e-9 x 8 )) / o tempo para estouro do timer em 150us / comeco semiciclo
unsigned int minTimer = 48575; //65535 - ((8.33e-3+150e-6) / (62.5e-9 x 8)) // tempo para estouro do timer 150us +8.33ms // final semciclo 
unsigned int incremento = 150; //o dimmer terá uma resolução de 65235 - 48575 : mais de 16000 pontos, com incremento de 150 resulta em 120 niveis de luz...
volatile unsigned int timer = minTimer; //quando a variavel será utilizada em interupções, deve ser "volatile" para garantir a leitura correta... 
IRrecv receptorIr(rIR);
decode_results resultados;

void setup()//configurações iniciais...

Serial.begin(19200); 
receptorIr.enableIRIn(); 
pinMode(triac, OUTPUT);
pinMode(2, INPUT);//pino passagem zero
digitalWrite(2,HIGH);//liga o pullup
digitalWrite(triac,LOW);
digitalWrite(rIR, HIGH);
attachInterrupt(0, passagemzero, RISING); 
TCCR1B=0; //timer desligado
TIMSK1 = 1 TOIE1;//habilita interrupção por estouro do timer1
}

void loop()
{
if (receptorIr.decode(&resultados)) //se houve uma decodificação válida
{
switch (resultados.value) {//testa as teclas...
case VolUP:
timer +=incremento;//aumenta o valor de inicio do contador, diminuindo o tempo para estouro do timer, indo em direção ao inicio do semiciclo
if (timer > maxTimer){//proteção para o timer não sair da faixa 
timer = maxTimer;
}
Serial.print(millis());
Serial.println(".VolUP");
break;
case VolDOWN: 
timer -=incremento;//diminui o valor de inicio do contador, aumentando o tempo para estouro d timer, indo em direção ao fim do semiciclo...

if (timer < minTimer){
timer = minTimer;
}
Serial.print(millis());
Serial.println(".VolDOWN");
break;

default:
break; 
}
delay(30);//atrasa o recebimento de novos comandos tornando mais suave o dimmer
receptorIr.resume(); 
}
}

void passagemzero()
{
digitalWrite(triac,LOW);//desliga triac
TCNT1=timer;//carrega contador
TCCR1B=2; //liga timer com prescaler de 8
}

ISR(TIMER1_OVF_vect)//interrupção do timer1 
{
TCCR1B=0; // desliga timer1
digitalWrite(triac,HIGH); //liga triac
}

Esse codigo que passei nem compila porque falta simbolos que a formatação tira, agora que eu vi como upar arquivos, ai está 

Anexos

Fabio Henrique segue abaixo algumas perguntas de leigo no uso de interrupções:

  1. O que é prescaler?
  2. Por que vc está usando esse índice divisor: 62.5e-9 x 8 ?
  3. O que significa as siglas:
    1. TCCR1B
    2. TIMSK1
    3. TOIE1
    4. ISR
    5. TIMER1_OVF_vect

Por fim estou entendendo que com esse seu programa eu não preciso mais utilizar o 4N25 do meu circuito em anexo, bastando ligar a pino 1 do meu MOC3021 no pino 13 do Arduino, correto?

RSS

© 2024   Criado por Marcelo Rodrigues.   Ativado por

Badges  |  Relatar um incidente  |  Termos de serviço