# TRIAC (BTA41-600) and optocoupler (MOC3041) not working with load

#### lucasperesm

Joined Jun 23, 2021
2
Hey guys, it's my first post here, so I'm sorry if I'm doing it in the wrong place and I really hope you can help me!

I'm developing a dimmer with ESP8266 and I'm having trouble with the TRIAC circuit. I have a zero cross detector developed and it works fine, but when I try to send the signal to the triac, it just works without a load conected (just with the voltmeter).

Explaining better:
When I receive a zero cross signal, I wait a time (via timer interrupt) in a range 0~100 (where 0 is 0ms and 100 is 8.3ms) and set the output to the MOC. If I have just the voltmeter connected to the AC output I can see all the range variation (between 220V and 0V), but if I connect some load it goes to 0V if I try to set the TRIAC after the zero cross signal (if I set the TRIAC while I'm receiving the zero cross signal, I have 220V in the output lol).

Important information:
1. AC Voltage: 220V/60Hz
2. I'm using a transistor to control de MOC because ESP8266 have 12mA of pin current limit.

Here I have a spreadsheet with the timer delay value VS output Voltage with and without load:

Here my circuit (using MOC3041 and BTA41-600V instead):

And the firmware:
ESP FW:
#include <user_interface.h>;//Biblioteca necessaria para acessar os Timers
#include <time.h>
#include <Ticker.h>  //Ticker Library

volatile int i=0;               // counter
volatile boolean zero_cross=0;  // cruzamento por zero status
int sinalOpto = D2;// Output to Opto Triac
int sinalZero = D1;
int dim1 = 0;// dimer level (0 = 100%; 100=0%)

void ICACHE_RAM_ATTR zero_cross_detect();
void ICACHE_RAM_ATTR dim_check();

void setup() {
attachInterrupt(sinalZero, zero_cross_detect, RISING);    // define interrupção no pino
timer1_attachInterrupt(dim_check); // timer 12.000 Hz (100x meio ciclo)
timer1_enable(TIM_DIV1, TIM_EDGE, TIM_SINGLE);
timer1_write(6667);
pinMode(sinalOpto, OUTPUT);
Serial.begin(115200);
while (!Serial) {};
Serial.println("Starting...");
Serial.println();
}

void loop(){
yield(); //delay(1);
}

void ICACHE_RAM_ATTR zero_cross_detect() {    //detecção de zero
static unsigned long last_interrupt_time = 0;
unsigned long interrupt_time = millis();
if (interrupt_time - last_interrupt_time > 2){   //debounce
zero_cross = true;               // seta flag de cruzamento por zero
i=0;
digitalWrite(sinalOpto, LOW);       // desativa o triac
Serial.print("crossing ");
Serial.println(millis());
}
last_interrupt_time = interrupt_time;
}

void ICACHE_RAM_ATTR dim_check() { //timer
if(zero_cross == true) {
if(i>=dim1) {
Serial.print("Setting ");
Serial.println(millis());
digitalWrite(sinalOpto, HIGH); // ativa o triac
i=0;  // reseta contagem
zero_cross = false;
}
else {
i++; //
}
}
timer1_write(6667);
}

#### Ian0

Joined Aug 7, 2020
3,784
it just works without a load conected (just with the voltmeter).
At what point do you switch off the signal to the MOC3021?

#### lucasperesm

Joined Jun 23, 2021
2
At what point do you switch off the signal to the MOC3021?
Just when I read the next zero (line 36).

But I was reading here other posts and I think I know what is happening. I'm using a MOC3041 and it's a zero-crossing optocoupler. I'm going to change it for a MOC3021 and than I bring here the news.

Thank you!