fabianoriccardi/dimmable-light

problem with running on esp32

radzikr opened this issue · 51 comments

Hi.
the library works fine on esp8266, I haven't noticed any problems.

I wanted to use esp32 now, but it doesn't run on esp32. ESP keeps resetting when I connect ZC to any defined gpio.

Which core version are you using? Are you experiencing the issue with the library's example?

ESP32 DevKit ESP-WROOM-32 V1

arduino esp32 board manager 2.0.14

yes, the problem is using the example from the library

set value light.setBrightness(0);
and light.setBrightness(255); works

the problem is between light.setBrightness(1); do light.setBrightness(254); setting any value from 1 to 254 resets esp

abort() was called at PC 0x40084df3 on core 1

Backtrace: 0x400838d9:0x3ffbec7c |<-CORRUPTED

ELF file SHA256: 2a4370c72ca79f07

Rebooting...
ets Jun 8 2016 00:22:57

rst:0xc (SW_CPU_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0030,len:1344
load:0x40078000,len:13964
load:0x40080400,len:3600
entry 0x400805f0

Can you provide the exact and complete code you are running? So I can make few tests

example 1_dimmable_light.ino

#include <dimmable_light.h>

const int syncPin = 25; //13;
const int thyristorPin = 26; //14;

DimmableLight light(thyristorPin);

// Delay between brightness increments, in milliseconds
const int period = 50;

void setup() {
Serial.begin(115200);
// while (!Serial) ;
Serial.println();
Serial.println("Dimmable Light for Arduino: first example");

Serial.print("Initializing DimmableLight library... ");
DimmableLight::setSyncPin(syncPin);
// VERY IMPORTANT: Call this method to activate the library
DimmableLight::begin();
Serial.println("Done!");
}

void loop() {
for (int i = 0; i < 256; i++) {
Serial.println(i); //test
light.setBrightness(i);
delay(period);
}
}

the problem is probably board manager 2.0.14

on board manager 2.0.0 it works fine

I managed to run on esp32 board 2.0.0 and 2.0.1. higher boards cause esp reset.

second topic, I am comparing operation on esp8266 and esp32. esp8266 does better, tests example

for (int i = 50; i < 99; i++) {
Serial.println(i);
light.setBrightness(i);
delay(1000);
}

the problem is probably board manager 2.0.14

on board manager 2.0.0 it works fine

I can confirm the issue, it should be something about the misusage of DRAM_ATTR / IRAM_ATTR, I'm investigating it.

I had found out that in version 2.0.2 the developers deeply refactored the timer APIs, so something had broken this library. You can try a quick fix on "dev" branch, the first example should work. I will continue to investigate in the next days.

ok, thank you for your interest in the topic, I hope the problem will be solved. I would like to use ESP + LAN, so I would like to run the dimmer on ESP32.

I tested versions with dev from 2.0.14 - esp32 resets as before

dev from 2.0.1 - works but unstable, the bulb blinks, the same software in esp8266 works smoothly without any problems

New trial on dev branch, I have tested it on core v2.0.11 (the latest available on platformIO). Let me know if it works for you (note it may not compile/work for other platform, I'm trying only esp32).

I have pushed a minor update, but I can confirm the more complex examples flickers. I will continue to investigate on timers...

#28 #30 probably the root cause is the same

Today I checked the latest version, it is a little better, but the work is still unstable, you can see the blinking. Thanks for your involvement and for not abandoning the topic.

✔ I successfully tested the 6th example (8 lamps with all effects). Commited on dev branch.

I take a bit more time to check and test the other platforms before releasing.

Thanks for your involvement and for not abandoning the topic.

I still feel a bit guilty for letting so much time passing, but now here I am!

I'm glad you're fighting.

I'm learning.
I don't know much yet.
A thought occurred to me.
The triac is controlled using GPIO digital.write(HIGH/LOW) the timers set the HIGH time and LOW time of the gpio accordingly. Yes?

I did an experiment. I have a PCA9685 pwm expander,
For the GPIO pin, I substituted the values ​​from the PCA pins into the library. HIGH=PCA4096 and LOW=0.
I didn't expect it to work at all. but to my surprise the Arduino IDE compiled the program correctly. So I posted it on esp. I don't remember if esp32 or 8266.
but the light bulb started flashing. So it was a sign that the triac was controlled, but randomly, chaotically.

Do you think it would be possible to use the PCA9685 expander instead of the ESP GPIO?
PCA9685 is also used as a servo driver, I think it can set the length of the up/down rectangular signal.

I wonder if it could be used to control a triac.
What do you think?

Somehow it will work, work I2C apis of Arduino are blocking, so they shouldn't be used in ISR. I expect that the timer may fail to trigger at the correct time point.

I have found and fixed the sporadic activation when dimmer was dimmly activated. Now it should properly work on v2.0.11 (and on v2.0.14). Unfortunately, I have to fix the compatibility with v2.0.1 (don't sure if I should spend time on that version) and check the other platforms.

If you try the latest commit, let me know if it works.

Today I tested on 2.0.14, it worked. Good job.
However, the bulb is unstable. blink.

I recorded a short video showing the setting to light.setBrightness(100);

https://youtube.com/shorts/rTYe9jJpMUg?feature=share

Today I tested on 2.0.14, it worked. Good job.

Finally!

Clearly that flashes hurt 😅 Have you tried with v2.0.11? I don't think it will change something, but I would give a chance.

Then, which dimmer breakout are you using? The zero cross detector circuit may lead to sporadic failures if not well designed. Have you an oscilloscope to check it?

images
AC-Light-lamp-dimming-and-motor-Dimmer-Module-1-Channel-3-3V-5V-logic-AC-50

for testing I use the robotdyn module 4 channels and 1 channel. I haven't tried it on 2.0.11 yet, I will try it it works perfectly on esp8266, so the zero detector circuit is definitely good.

In the meanwhile, I have tested for v2.0.14 and it works, so core version is not the problem.
Which frequency is your mains electricity?

50 Hz

Poland

I'm out of ideas... Is it flashing at every brightness level?

I have digged the issue a little bit, and your issue may be related to this espressif/arduino-esp32#1111. From that discussion, it seems that ESP32 doesn't handle the curved interrupt very well...

If you read the wiki of this repo, there is a screen of zero cross signals for 2 boards. The one with the "curved" signal (the bad one) is generated by a RobotDyn dimmer.

If this is the root cause, you can solve it by adding a "squarer" circuitry or a software filter in the library.

Nie mam już pomysłów... Czy miga na każdym poziomie jasności?

I'm out of ideas... Is it flashing at every brightness level?

hi, the flashing is practically at every level, but most noticeable at lower levels below 50%. above 50% is also visible, but less.
I can record a longer video to show you.

Write if you want a longer video with each value.

I have digged the issue a little bit, and your issue may be related to this espressif/arduino-esp32#1111. From that discussion, it seems that ESP32 doesn't handle the curved interrupt very well...

If you read the wiki of this repo, there is a screen of zero cross signals for 2 boards. The one with the "curved" signal (the bad one) is generated by a RobotDyn dimmer.

If this is the root cause, you can solve it by adding a "squarer" circuitry or a software filter in the library.

I didn't read WIKI, I didn't know it existed. I'll read. I use the robotdyn module for testing.
Ultimately, I would like to design my own circuit, but I see that it will not be that simple. I will have to look for good projects/boards with triacs and see their construction.

I have got some idea.
How does the library on AVR work? I mean an AVR that will be able to support 8 or 16 channels.
I don't have an AVR for testing to see.

But I have an idea that AVR could be responsible for dimming and ESP32 for network connectivity and then I could communicate them with each other. I just don't have the opportunity to test the AVR. I guess I'll have to buy a CD and check it out.

I read the WIKI, looked in the library, commented
#define FILTER_INT_PERIOD
, it shines nicely.
It seems that a very well-designed zero crossing system is needed.

I'll test it

Write if you want a longer video with each value.

No need, I can replicate the same behavior you describe with Robotdyn dimmer. The issue is always presents at every level, but for physical reasons, it is less visible at higher brightness levels. You can clearly see it if you analyze it with an oscilloscope.

#define FILTER_INT_PERIOD

It should work! Don't enable the prints otherwise the ESP32 will crash

#zdefiniuj FILTER_INT_PERIOD

Powinno działać! Nie włączaj wydruków, w przeciwnym razie ESP32 ulegnie awarii

I already know, I tested

#define CHECK_MANAGED_THYR
#define PREDEFINED_PULSE_LENGTH
also resets esp

CHECK_MANAGED_THYR contains Serial.print, so you replace them with ets_printf.

Does PREDEFINED_PULSE_LENGTH only make it crash?

CHECK_MANAGED_THYR contains Serial.print, so you replace them with ets_printf.

Does PREDEFINED_PULSE_LENGTH only make it crash?

sorry, my mistake, I got the function wrong.
#define PREDEFINED_PULSE_LENGTH
it doesn't cause a crash, but if I uncomment it, the compilation doesn't go through

C:\Users\radzi\Documents\Arduino\libraries\dimmable-light-dev\src\thyristor.cpp: In function 'void activate_thyristors()': C:\Users\radzi\Documents\Arduino\libraries\dimmable-light-dev\src\thyristor.cpp:205:14: error: 'delayAbsolute' was not declared in this scope setAlarm(delayAbsolute); ^~~~~~~~~~~~~

it doesn't cause a crash, but if I uncomment it, the compilation doesn't go through

Correct, I have to fix it. However, I don't think it will solve your problem...

Has FILTER_INT_PERIOD any effect? Given that hardware, you should configure that shrink threshold at least to 300us (500us to be sure)

Yesterday I turned on the definition regarding the filtration of the ZC circuit. after that the bulb glows beautifully in all values even the minimal ones. very good job. in your ZC project you will probably have to build it based on a Smith flip-flop. very good job, thank you

Glad to hear that! Which values do you use? 500us?

I think 400us is the lowest secure value. Here the screenshot of the oscilloscope that justify this number.

I only activated #define PRINT INT PERIOD
I didn't change anything else, so it probably works with the default semiPeriodShrinkMargin=50.

I will test 400

The Krida dimmer probably has a Schmitt flip-flop to detect zero?

Is there a diagram of the Krida dimmer available somewhere?

Do you mean #define FILTER_INT_PERIOD ?

However, I confirm that I see it working well with semiPeriodShrinkMargin=50, but I think in few cases you can enter in a bad event flow that leads to flickering.

The Krida dimmer probably has a Schmitt flip-flop to detect zero?

It is more than that.

Is there a diagram of the Krida dimmer available somewhere?

To my knowledge, Krida's boards are closed source, so no schematic.

Do you mean #define FILTER_INT_PERIOD ?

Yes

I also had these issues on an ESP32.
This is mainly due to the mediocre design of the Robotdyn module.
There's no input filter for the zero-crossing and the signal is not perfectly square which makes the ESP32 trigger multiple times and sometimes too late. I added a 100nF capacitor on the input of the bridge rectifier (4 legs square IC) and a transistor on the output to clean the signal. With a reliable zero crossing, I can now directly drive Triacs with the MCPWM peripheral. It takes cares of the PWM and synchronisation in hardware without any interruption.

Simulation with falstad:
https://tinyurl.com/yuod5nyy

Hey guys, what would you suggest to get stable work for a new project for lots of independent lights, using RobotDyn dimmers?

  • Use ESP32 and board manager v2.0.1?
  • Or use ESP8266?
  • Switch to KRIDA board instead of RobotDyn?
  • Or current dev version is stable enough?

I added a 100nF capacitor on the input of the bridge rectifier (4 legs square IC) and a transistor on the output to clean the signal.

Can you provide a screenshot of the measurement with an oscilloscope? The simulation seems perfect, but I would see the measurement on the real circuitry.

Hey guys, what would you suggest to get stable work for a new project for lots of independent lights, using RobotDyn dimmers?

I think the dev version is stable enough (@radzikr can confirm it too). I'm going to release it very soon.

yes, I confirm, the development version works beautifully with esp32 and stably on 2.0.14

I added a 100nF capacitor on the input of the bridge rectifier (4 legs square IC) and a transistor on the output to clean the signal.

Can you provide a screenshot of the measurement with an oscilloscope? The simulation seems perfect, but I would see the measurement on the real circuitry.

My system is up an running and I don't have a spare board to make a capture.
The result on the scope by forwarding the ZC interrupt to a GPIO were more or less consistent with the simulation.

The added capacitor act as a low pass filter to suppress the noise and it reduces the zero crossing delay. In persistence mode, I could see less deviation on the delay. Though it depends on the power resistor on the input. Not all the boards have the same value. The lower the resistance, the more precise but at the expense of the power consumption (1 Watt with a 50k resistor). So adding capacitance will reduce the noise and ZC delay but too much and the ZC will be too late and give 100% power when requested close to 1%.

For the transistor, without it I could clearly see a significant rise/fall time and potato shape on the edges. With it, I didn't measure the rise/fall time but it was what I would expect of a clean square signal and more important, I no longer had unexpected interrupts. The ESP32 doesn't have a Schmitt trigger on it's GPIO compared to an atmega328p. This is why we get multiple input interrupt for a single distorted impulse. It can be de-bounced by software, but at the expense of CPU time. An alternative would be to replace the optocoupler with one having a CTR over 1000% or one with logic output. The 4n25 is specified at 50% which is way too low, thus the need to condition the signal with a transistor or Schmitt trigger.

@florentbr Thanks for the clear explanation of your circuit. I will try to make a few experiments on my board in next days.

I never use the MCPWM peripheral on ESP32... Can it be integrated in this library? Can it handle multiple independent dimmers?

@florentbr Thanks for the clear explanation of your circuit. I will try to make a few experiments on my board in next days.

I never use the MCPWM peripheral on ESP32... Can it be integrated in this library? Can it handle multiple independent dimmers?

The ESP32 can drive directly up to 6 triacs per MCPWM periferial, so 12 triacs in total since it has 2 MCPWM.

I don't know if it can be integrated since this library is heavily dependent on timers.

Note that it's also possible to drive triacs with the LEDC (PWM) periferial.
Once the setup is done, all it takes is resetting the LEDC timer with the zero-crossing interrupt.

Great, maybe in the next release I will consider it.

Theoretically you can use more that 8 channels, but I never tested it and, unfortunately, it seems there are few problems, look at #24 for more info.

I close this issue since the main topic is solved.