esphome / feature-requests

ESPHome Feature Request Tracker
https://esphome.io/
418 stars 26 forks source link

Software PWM/frequency generator for ESP32. #502

Closed yawor closed 4 years ago

yawor commented 4 years ago

Describe the problem you have/What new integration you would like A software PWM or a frequency generator for ESP32, which would allow to set the frequency independently between multiple outputs.

Please describe your use case for this integration and alternatives you've tried: I've tried using esp8266_pwm on ESP32 but I get an error which states that the component is not supported on ESP32.

Additional context I have two BLDC variable speed motors with integrated controllers. The speed input in these controllers needs a square wave 50% duty cycle signal, where the speeds depends on the signal's frequency (60-600 Hz). I'm trying to control individually both motors with a single ESPHome node running on ESP32. The problem is that the new output.ledc.set_frequency doesn't work as expected when multiple PWM channels are involved, as all channels use the same timer and share the same frequency. Setting different frequencies on individual ledc outputs makes the signals on the outputs to behave in an unpredictable way, as I've found out by testing this with an oscilloscope (the frequency is shared on all channels, but the duty cycle is not correct anymore on some channels, maybe it could be added as a note to the documentation). In addition to these 2 motors, I need few more PWM channels for controlling LEDs, so by changing the frequency of motor channels I would also affect the LEDs. By having a software PWM/frequency generator, I could generate independent frequency modulated signals to control both motors without affecting the ledc component itself. The frequency itself wouldn't need to be super stable, as the motors have some inertia and won't change the speed that fast.

OttoWinter commented 4 years ago

You can set the channel for LEDC outputs using the "channel" parameter. channels 0-1 share the same timer, 2-3, ... So you would set channel 0 and channel 2 for example.

If that works, I don't see a use case for software based PWM for ESP32s. In fact it would even make the documentation worse, as beginners would choose soft PWM instead of LEDC if the docs don't make clear which one to use in general.

yawor commented 4 years ago

You're right. I somehow have missed that info. I can confirm that by selecting, for example, channels 0 and 2, I'm able to set the frequency individually. But then I loose 4 channels to control individually control two frequency modulated outputs. So alternatively to my previous idea, would it be possible to expose timer selection in addition to channel selection? Unless I'm missing something, according to IDF documentation, it should be possible assign any of the four timers to any of the 8 channels. That way I could sacrifice two timers with one channel each and still be able to use the other 6 channels by assigning two other timers to them.

OttoWinter commented 4 years ago

No, that is not really possible.

ESPHome uses the arduino ledc* functions, not the ones from esp-idf. One reason for that is that esp-idf only allows integer frequencies, whereas the arduino APIs (and the hardware) support floating point frequency.

But then I loose 4 channels to control individually control two frequency modulated outputs.

Yes, true, but please tell me a real use-case for that. Only thing I can think of is combining frequency-based outputs (like motor) with fixed-frequency outputs (like lights). But why not use multiple esp32s then? They're certainly cheap enough.

yawor commented 4 years ago

I'm trying to replace a Marvell MCU in my Xiaomi Air Purifier Pro with ESP32 running ESPHome. Like I've mentioned, it has two frequency controlled motors. It also has an OLED screen, which (I don't know yet why) has two PWM channels to control OLED display brightness and three PWM channels for 3-color LED status indicator (a circle around the OLED display). Using two ESP32 could work to some extent, but then it would be harder to create in-device automation (not depending on network connection). Ultimately I can keep both motors in sync and control them with a single frequency, which would take only one timer and two channels. I think this is an acceptable solution. What's nice is that, other than the PWM, almost all hardware in the air purifier seems to be supported already (air quality sensor, temperature and humidity sensor, probably even the OLED display but I didn't test it yet). I think the only missing piece is a missing support for NFC reader used in the device (some I2C one) which reads a type of filter used and how long the filter has been in use - but I can live without that.

glmnet commented 4 years ago

The other devices (not the motors) doesn’t seem to be frequency dependent. You can add a https://esphome.io/components/output/pca9685.html This one has a fixed frequency for all the outputs

OttoWinter commented 4 years ago

Yeah so maintaining an accurate Soft PWM is not so easy. For example, the ESP8266 soft PWM is a couple hundred lines of code (in arduino core). For ESP32, we'd need to redevelop that, plus the time delay of interrupts etc needs to be found.

I understand there's a potential need for more PWM timers on ESP32, but the use case is not often and the cost of maintainig is too high.

There are other PWM chips like @glmnet mentioned, I would recommend those.