(Resolvido) controlando dimmer com 2 lampadas

Ola

o que estou a fazer mal?? :slight_smile:

Estou a tentar controlar 2 lampadas com dimmer, tenho um opto 4N25 para fazer a detecção por zero e um MOC3021 a fazer o disparo do Triac (TIC246M). Assim com uma lampada funciona perfeitamente, quando duplico o MOC3021 e outro TRIAC (a deteção por Zero mantive o mesmo, penso k basta 1) nao consigo controlar a segunda lampada, ela tem o comportamento da primeira lampada.

Este é o codigo para 1 lampada e k funciona bem.

/*

 AC Light Dimmer - Inmojo 
 AC Voltage dimmer with Zero cross detection
 
 Author: Charith Fernanado http://www.inmojo.com charith@inmojo.com 
 License: Released under the Creative Commons Attribution Share-Alike 3.0 License. 
 http://creativecommons.org/licenses/by-sa/3.0
 Target:  Arduino
 
 Attach the Zero cross pin of the module to Arduino External Interrupt pin
 Select the correct Interrupt # from the below table

 Pin    |  Interrrupt # | Arduino Platform
 ---------------------------------------
 2      |  0            |  All
 3      |  1            |  All
 18     |  5            |  Arduino Mega Only
 19     |  4            |  Arduino Mega Only
 20     |  3            |  Arduino Mega Only
 21     |  2            |  Arduino Mega Only
 
 */

int AC_LOAD = 5;    // Output to Opto Triac pin
int dimming = 128;  // Dimming level (0-128)  0 = ON, 128 = OFF

void setup()
{
  pinMode(AC_LOAD, OUTPUT);	      // Set the AC Load as output
  attachInterrupt(0, zero_crosss_int, RISING);  // Choose the zero cross interrupt # from the table above
}

void zero_crosss_int()  // function to be fired at the zero crossing to dim the light
{
  // Firing angle calculation :: 50Hz-> 10ms (1/2 Cycle)
  // (10000us - 10us) / 128 = 75 (Approx)
  int dimtime = (75*dimming);      
  delayMicroseconds(dimtime);    // Off cycle
  digitalWrite(AC_LOAD, HIGH);   // triac firing
  delayMicroseconds(10);         // triac On propogation delay
  digitalWrite(AC_LOAD, LOW);    // triac Off
}

void loop()
{
  
  dimming = 100;  
  delay(1000);
  dimming = 75;  
  delay(1000);

}

Este é o codigo k fiz para a segunda lampada e k nao funciona

/*

 AC Light Dimmer - Inmojo 
 AC Voltage dimmer with Zero cross detection
 
 Author: Charith Fernanado http://www.inmojo.com charith@inmojo.com 
 License: Released under the Creative Commons Attribution Share-Alike 3.0 License. 
 http://creativecommons.org/licenses/by-sa/3.0
 Target:  Arduino
 
 Attach the Zero cross pin of the module to Arduino External Interrupt pin
 Select the correct Interrupt # from the below table

 Pin    |  Interrrupt # | Arduino Platform
 ---------------------------------------
 2      |  0            |  All
 3      |  1            |  All
 18     |  5            |  Arduino Mega Only
 19     |  4            |  Arduino Mega Only
 20     |  3            |  Arduino Mega Only
 21     |  2            |  Arduino Mega Only
 
 */

int AC_LOAD = 5;    // Output to Opto Triac pin
int AC_LOAD2 =6;
int dimming = 128;// Dimming level (0-128)  0 = ON, 128 = OFF
int dimming2 = 128;

void setup()
{
  pinMode(AC_LOAD, OUTPUT);	      // Set the AC Load as output
  pinMode(AC_LOAD2, OUTPUT);
  attachInterrupt(0, zero_crosss_int, RISING);  // Choose the zero cross interrupt # from the table above
}

void zero_crosss_int()  // function to be fired at the zero crossing to dim the light
{
  // Firing angle calculation :: 50Hz-> 10ms (1/2 Cycle)
  // (10000us - 10us) / 128 = 75 (Approx)
  int dimtime = (75*dimming);      
  delayMicroseconds(dimtime);    // Off cycle
  digitalWrite(AC_LOAD, HIGH);   // triac firing
    delayMicroseconds(10);         // triac On propogation delay
  digitalWrite(AC_LOAD, LOW);  // triac Off
  int dimtime2 = (75*dimming2);
  digitalWrite(AC_LOAD2, HIGH);
  delayMicroseconds(10);         // triac On propogation delay
  digitalWrite(AC_LOAD2, LOW);
}

void loop()
{
  
  dimming = 100;  
  dimming2 = 75;
  delay(1000);
  dimming = 75;
  dimming2 = 100;  
  delay(1000);

}

Agradeço desde já qualquer ajuda.

Abraços

quando duplico o MOC3021 e outro TRIAC (a deteção por Zero mantive o mesmo, penso k basta 1) nao consigo controlar a segunda lampada, ela tem o comportamento da primeira lampada.

Ou eu nao estou a entender bem mas se estas a usar a mesma interrupçao para controlar 1 lampada e duplicas-te o circuito nao é de esperar que a 2º lampada faça o mesmo?
Outra questao é usares delays dentro da rotina de interrupçao.Algo que nao deve ser feito

Note also that due to the fact that interrupts are blocked and timers are stopped during the ISR processing, inside the attached function, delay() won't work and the value returned by millis() will not increment. Serial data received while in the function may be lost. You should declare as volatile any variables that you modify within the attached function.

O sumo disto que que as variaveis usadas dentro da rotina de interrrupçao teem de ser declaradas como volatile e nao podes usar o delay.

Boas HugoPT

eu neste momento ja nao sei nada :slight_smile:

eu nao dupliquei o detector por zero, pk penso k basta um ... ou seja ... a passagem por zero vai ser sempre a mesma, agora dupliquei o MOC3021 e o triac para controlar a segundo triac com um angulo diferente do primeiro triac... e nao estou a ver como o fazer :frowning: penso k tem a ver com os tempos ... mas nao tou a lá chegar

em relação ao delay dentro da interrupção eu sei k nao se deve usar ... mas tá somente para simplificar.

detector por zero

Podes dizer melhor em que consiste este termo que utilizas?
Tens circuito disso para ver?
Acho que te devo um pedido de desculpas por uma informaçao errada que te dei quanto aos Delays.
Ha pouco fui ler melhor pois questionei me porque é que o autor do codigo que estas a tentar usar la usou a funçao delayMicroseconds()
Defacto esta funçao funciona dentro das interrupçoes :slight_smile:
Mas a funçao delay() nao pois depende inteiramente da funçao millis() que nao é incrementada devido a interrupçao estar desativada a quando dentro da rotina de interrupçao.
Assim podes usar delayMicroseconds() para provocar delays pequenos.
Comprovei isto com um analisador de Logica e está confirmado.
Se no entanto tentar usar a funçao delay() a funçao perde toda a logica temporal pois o que é reproduzido pela funçao delay nada tem a ver com o tempo que reflete no codigo.

Ola HugoPT, antes de mais obrigado pelo tempo k tem despendido a olhar para o meu problema

O Detector de Passagem por Zero ou Zero Crossing Detector é um circuito que produz um pulso positivo quando o sinal senoidal passa por zero Volt para saber quando fazer o "disparo" ao TRIAC.

Sei k utilização do Delay realmente nao é a correcta Hugo... No entanto este circuito está incompleto, entao reduzi o mais possivel na tentativa de resolver este problema, daí o delay estar no codigo, foi a forma mais rapida de o fazer. Mas no 1º codigo k publiquei aqui, em k está somente um MOC e um TRIAC o delay tá lá e o sistema funciona na perfeição. No entanto tb ja alterei o codigo o substitui o delay, mas ficou na mesma.

o circuito é este:

Tal como está neste circuito e com o primeiro codigo k postei funciona, depois dupliquei o MOC e o Triac e alterei o Codigo (o segundo codigo k postei) e é aí k nao funciona :frowning:

relembrando o k desejo fazer ... controlar o Dimmer de 2 lampadas de forma independente 1 da outra.

Para comprovar na rotina de interrupçao alterei a de forma a ela gerar um sinal que mude o tempo e medi-los

void zero_crosss_int()  // function to be fired at the zero crossing to dim the light
{
  digitalWrite(AC_LOAD, HIGH);   // triac firing
  delayMicroseconds(100);         // triac On propogation delay
  digitalWrite(AC_LOAD, LOW);    // triac Off
  delayMicroseconds(200);         // triac On propogation delay
  digitalWrite(AC_LOAD, HIGH);   // triac firing
  delayMicroseconds(300);         // triac On propogation delay
  digitalWrite(AC_LOAD, LOW);    // triac Off
}

void loop()
{

}

Aqui esta a prova:
Esta é uma daquelas liçoes praticas quem tenta ensinar acaba por aprender :slight_smile:

Tens isso ligado tal como no esquema ?
Esse 4n25SRV se inda nao morreu vai daqui a nada.
Sabes que la dentro tem um led e nao estas a limitar a corrente dele nem tao pouco a tensao.Vai entrar em curto ...
Quantos Volts saem apos a ponte retificadora??
O led interno do moc so gosta de tensoes de cerca de 3V !!!
Quando dizes que para uma lampada funciona como sabes?
Ou melhor consegues regular a intensidade dela como?

Tenho 2 resistencias de 100K em paralelo ao pino 1 do 4n25

o dimmer ta a funcionar pk a luz aumenta e diminui conforme o loop... agora ... é as 2 lampadas ao mesmo tempo :frowning:

void loop()
{

dimming = 100;
delay(1000);
dimming = 75;
delay(1000);

}

Boa noite. Eu sei que este post é antigo, porém gotaria de contribuir de alguma maneira. Quando você trabalha com mais de um dimmer ao mesmo tempo, não é possivel simplesmente encadear os retardos de tempo, é bem mais complicado. Isto acontece porque quando você implementa o primeiro retardo, O TEMPO JÁ AVAÇOU! Ou seja, suponha que você tenha dois dimmers, um com disparo no pino 4 e outro no pino 5. Suponha que o retardo do primeiro são 1000 microsegundos, e do segundo 300 microsegundos. Se o retardo de 1000 microsegundos for aplicado no pino 4, a lampada correspondente irá acender com uma certa luminosidade. Porém não esqueça que já se passaram 1000 microsegundos. Se você aplicar um delay de 300 microsegundos no segundo, do pino 5, na verdade você esta mandando um pulso com retardo real de 1000 + 300 = 1300 microsegundos! Para funcionar, você precisa fazer o seguinte: determine qual dos dois dimmers tem o retardo MENOR. No nosso caso, é o dimmer do pino 5:

retardo = 300us
Dimmer pino 5
retardo = 700us
Dimmer pino 4

O segredo é que sempre o segundo pulso, precisa descontar o valor do primeiro retardo. Se porém tivermos o seguinte: Pino 4 com 10uS e Pino 5 com 300uS, ficaria:

retardo = 10us
Dimmer pino 4
retardo = 290us
Dimmer pino 5

Portanto você precisa re-escrever o código, e bolar um função para determinar qual dos dois retardos é maior. A principal dificuldade é que a sequência de disparo não é fixa, ora você dispara primeiro o pino 4, ora é primeiro o pino 5. Se aumentar o numero de dimmers a dificuldade é maior, mas da para fazer. Já consegui disparar 10 dimmers ao mesmo tempo com o Arduino UNO.

Good night. I know this post is old, but wish to contribute in some way. When you work with more than one dimmer at the same time, it is not possible to simply chain the time delays, is much more complicated. This happens because when you implement the first delay, the TIME HAS GONE!
In other words, suppose you have two dimmers, with shooting 4 pin and another on pin 5. Suppose that the delay of the first are 1000 microseconds, and the second 300 microseconds. If the delay of 1000 microseconds on pin 4 is applied, the corresponding lamp will light with a certain brightness. But don't forget it's been 1000 microseconds. If you apply a delay of 300 microseconds in the second, 5 pin, you're actually sending a pulse with actual 1000 delay = 1300 300 microseconds. To work, you need to do the following: determine which of the two has the SMALLER retardation dimmers. In our case, is the dimmer 5 pin:
delay = 5 PIN
Dimmer= 300us
delay=4 PIN
Dimmer=700us
The secret is always the second pulse, you have to deduct the value of the first delay. If however we have the following: pin and 5 Pin 4 with 10uS with 300uS, would:
delay = 4 PIN
Dimmer= 10us
delay=5 PIN
Dimmer=290us
So you need to re-write the code and come up with a function to determine which of the two is greater delays. The main difficulty is that the firing sequence is not fixed, now you shoot first the 4 pin, it is first the PIN 5. To increase the number of dimmers difficulty is bigger, but to do. I've managed to shoot 10 dimmers at the same time with the Arduino UNO.