Your new topic does not fit any of the above??? Check first. Then post here. Thanks.

Moderator: igrr

User avatar
By kislein
#87861 Hey there...
I've been struggling with a timing problem and was hoping to maybe find some help here.
Essentially I've built an AC phase angle dimmer using an ESP8266. I've done this before using an ATmega328P and it works fine.
Essentially a pin change interrupt is triggered at the zero cross of the sine wave and I need the the ESP to pulse a pin high for half a millisecond or so a specific time after that. For example if the phase angle is set to 50 % the ESP would have to pulse a pin high 5000 microseconds later. On the ATmega I did this using one of the hardware timer without any issues. And I tried doing this using an ESP also with the hardware timer. Which does work, but the timing isn't stable. There is too much jitter. I've tried many different things. But so far the ONLY thing that has worked reliably (without jitter) is to delay the whole 5000 microseconds. The problem with that is that, if the phase angle is set to 10 % the ESP will jitter 9000 microseconds every 10000 microseconds so 90 % of the time. And will occasionally even crash due to watchdog resets.
Obviously delaying is a terrible solution. And I've been looking for a solution for a long time but I just can't find any way to do this. I even tried setting the hardware timer to earlier than necessary and then going into a while loop and waiting the last 1000 microseconds to ensure accurate timing. I tried doing it in the main loop and delaying the last X microseconds in a while loop to ensure accurate timing. But for some reason the jitters always persists. It seems as if micros() itself loses accuracy as soon as the processor does anything else in the meantime.
User avatar
By pangolin
#87868 "I've done this before using an ATmega328P and it works fine."...because that MCU doesn't hve WiFi running "in the background". Anything that prevents WiFi coded executing for more than about 20mS will fire the watchdog and cause a reset

Have you looked at the Ticker library? Set a volatile global var in the ISR at the zero cross point, then in main loop, check the var, If set, reset it then ticker.attach_ms(5000,[]{ do your thing });

As long as you don't block or take a week inside "do your thing" the above pseudo-code should work fine.
User avatar
By pangolin
#87872 PS - also be carefull not to do TOO much inside the ticker callback, especially timing and/or WiFi functions etc think of it like another ISR, do as little as possible and get out and use the main loop for "real" code