First of all, Thank You for the time You took to help me. I've made some progression on my code. Let's go
cattledog:
t-lastTime will always be equal to 8333 and I believe that value will always satisfy the second condition and the output will be LOW.
@cattledog You're right. So I changed the conditions to
if (t <= t1 + lastTime) {
state = LOW;
}
else if (t >= t1 + t_on + lastTime) {
state = LOW;
}
StefanL38:
Your ISR is called through the zero-crossing signal. It runs down once per zero-crossing-signal and that's it.
Until the next zero-crossing-signal occures. Again running down once and that's it.
The time when it is called is always when the zero-crossing signal occurs but not at a time that has some delay after the zero-crossing signal.
Timing with millis() or micros() needs a functionality that the if-condition that is used to check if a certain timeperiod is over will be checked repeatedly thousands of times per second. The code you have so far does not check repeatedly.
The basic principle for timing with micros() is:
the ISR just sets a boolean flag. And your main-loop checks if flag is set true. If flag has value true start timing
best regards Stefan
MarkT:
Your code needs to be in loop(), not the ISR. The ISR can record the latest zero-crossing, but its not
happening when the output needs to be toggled.
That can be tested for in loop, or perhaps scheduled using a timer interrupt if you want to do this
in the background with accurate timing.
Do you understand state-transition diagrams?
@Stefan and @MarkT, I thought the ISR would last untill all conditions are satisfied and all actions are made, but I was wrong and You're right on your statement. I've made some changes in the code with your suggestions:
void zeroCross() { // ISR
flag = HIGH; // Activates the flag everytime an interrupt occurs
}
With all changes the NEW code is down below. What happens now is that the pulse (dimmer signal) works for some time, falls down to zero (0 V) for some time, and then it works again and so on. t1 should be constant as the pot is constant too, but in first microseconds t1 varies until it reaches the constante value. (attached images)
image graphs:
Zero Cross signal -> blue
dimmer (pulse signal) -> red
Sine rms on lamp -> green
#define dimmer 4 // OUTPUT on Pin 4
// Initializing variables
long pot = 0.0; // potentiometer reading
unsigned long t = 0.0; // time
unsigned long lastTime = 0.0; // last time
unsigned long period = 8333; // Period (us)
unsigned long t_on = 100.0; // pulse duration
bool state = LOW; // pulse's state - HIGH/LOW
volatile bool flag = LOW; // flag that indicates ISR triggering
void zeroCross() { // ISR
flag = HIGH; // Activates the flag everytime an interrupt occurs
}
void setup() {
pinMode(dimmer, OUTPUT);
attachInterrupt(digitalPinToInterrupt(2), zeroCross, FALLING);
}
void loop() {
pot = 50.0; // potentiometer reading - it actually comes from an analogRead(A0)
// It is set to 50 just to simplify the test
// Calculates t1 that depends on potentiometer readings
unsigned long t1 = 8333L * (100L - pot) / 100L;
t = micros();
// If flag is HIGH, the dimmer signal routine starts
if (flag == HIGH) {
if (t <= t1 + lastTime) {
state = LOW;
}
else if (t >= t1 + t_on + lastTime) {
state = LOW;
}
else {
state = HIGH;
}
if (t - lastTime >= period) { // period end check
lastTime = t;
flag = LOW; // If period has passed away, it sets flag to LOW
}
}
digitalWrite(dimmer, state); // OUTPUT
}

