fabianoriccardi / dimmable-light

Arduino library to manage dimmers compatible with AVR, ESP8266, ESP32, SAMD, and RP2040 platforms.
GNU Lesser General Public License v2.1
97 stars 29 forks source link

problem with running on esp32 #41

Closed radzikr closed 11 months ago

radzikr commented 1 year ago

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.

fabianoriccardi commented 1 year ago

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

radzikr commented 1 year ago

ESP32 DevKit ESP-WROOM-32 V1

arduino esp32 board manager 2.0.14

yes, the problem is using the example from the library

radzikr commented 1 year ago

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

fabianoriccardi commented 1 year ago

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

radzikr commented 1 year ago

example 1_dimmable_light.ino

include

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); } }

radzikr commented 1 year ago

the problem is probably board manager 2.0.14

on board manager 2.0.0 it works fine

radzikr commented 1 year ago

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); }

fabianoriccardi commented 1 year ago

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.

fabianoriccardi commented 1 year ago

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.

radzikr commented 1 year ago

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.

radzikr commented 1 year ago

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

fabianoriccardi commented 1 year ago

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).

fabianoriccardi commented 1 year ago

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

fabianoriccardi commented 1 year ago

28 #30 probably the root cause is the same

radzikr commented 1 year ago

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.

fabianoriccardi commented 1 year ago

✔ 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!

radzikr commented 1 year ago

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?

fabianoriccardi commented 1 year ago

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.

fabianoriccardi commented 1 year ago

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.

radzikr commented 1 year ago

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

fabianoriccardi commented 1 year ago

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?

radzikr commented 1 year ago

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.

fabianoriccardi commented 1 year ago

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?

radzikr commented 1 year ago

50 Hz

Poland

fabianoriccardi commented 1 year ago

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

fabianoriccardi commented 1 year ago

I have digged the issue a little bit, and your issue may be related to this https://github.com/espressif/arduino-esp32/issues/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.

radzikr commented 1 year ago

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.

radzikr commented 1 year ago

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.

radzikr commented 1 year ago

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

fabianoriccardi commented 1 year ago

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.

fabianoriccardi commented 1 year ago

define FILTER_INT_PERIOD

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

radzikr commented 1 year ago

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

fabianoriccardi commented 1 year ago

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

Does PREDEFINED_PULSE_LENGTH only make it crash?

radzikr commented 1 year ago

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); ^~~~~~~~~~~~~

fabianoriccardi commented 1 year ago

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)

radzikr commented 1 year ago

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

fabianoriccardi commented 12 months ago

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

fabianoriccardi commented 12 months ago

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

radzikr commented 12 months ago

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?

fabianoriccardi commented 12 months ago

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.

radzikr commented 12 months ago

Do you mean #define FILTER_INT_PERIOD ?

Yes

florentbr commented 12 months ago

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

ivanzoid commented 12 months ago

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

fabianoriccardi commented 12 months ago

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.

fabianoriccardi commented 12 months ago

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.

radzikr commented 12 months ago

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

florentbr commented 12 months ago

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.

fabianoriccardi commented 12 months ago

@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 commented 11 months ago

@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.

fabianoriccardi commented 11 months ago

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