-
-
Notifications
You must be signed in to change notification settings - Fork 3.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
two wire cc cw with swapped polarity #4112
Comments
You can resolve this using additional circuitry and stock WLED. |
what kind of circuitry? |
Differential output comes to mind. |
Correction. Using H-bridge (a mandatory circuit in this case) will require phase shifted PWM. |
@jw2013 claimed he had a working solution for phase shifted PWM and exactly the same use case. |
That's correct, I also needed a solution to run 'polarity change LED strings' via WLED. unsigned char busPwmIntRoutine1Pin1 = 255;
unsigned char busPwmIntRoutine1Pin2 = 255;
unsigned char busPwmIntRoutine1Value1 = 255;
unsigned char busPwmIntRoutine1Value2 = 255;
void ICACHE_RAM_ATTR busPwmIntRoutine1() {
if ( digitalRead(busPwmIntRoutine1Pin1) ) {
GPOC = 1 << busPwmIntRoutine1Pin2;
}
else {
GPOS = 1 << busPwmIntRoutine1Pin2;
}
}
void analogWriteCombined(unsigned char gpio1, unsigned char gpio2, unsigned char value1, unsigned char value2) {
if ( (gpio1 == 0xFF) || (gpio2 == 0xFF) ) return;
if ( (busPwmIntRoutine1Pin1 == gpio1) && (busPwmIntRoutine1Pin2 == gpio2)
&& (busPwmIntRoutine1Value1 == value1) && (busPwmIntRoutine1Value1 == value2) ) return;
busPwmIntRoutine1Pin1 = gpio1;
busPwmIntRoutine1Pin2 = gpio2;
busPwmIntRoutine1Value1 = value1;
busPwmIntRoutine1Value2 = value2;
if ( (value1 == 0) || (value1 == 255) || (value2 == 0) || (value2 == 255) ) {
detachInterrupt(digitalPinToInterrupt(gpio1));
analogWrite( gpio2, value2 );
analogWrite( gpio1, value1 );
return;
}
unsigned int value = value1 + value2;
if ( value < 253 ) { // !!!D*RTY WORKAROUND: use overlap instead of gap
unsigned int overlap = 253 - value;
analogWrite( gpio1, value1+overlap );
analogWrite( gpio2, overlap );
attachInterrupt(digitalPinToInterrupt(gpio1), &busPwmIntRoutine1, FALLING);
}
else if ( value > 255 ) {
}
else {
analogWrite( gpio1, value1 );
digitalWrite( gpio2, LOW );
attachInterrupt(digitalPinToInterrupt(gpio1), &busPwmIntRoutine1, CHANGE);
}
} Later I found that there also exists a phase shift PWM API for ESP8266 only, but I never rewrote the WLED code (more below). As motor drivers, depending on the voltage, I used either DRV8833 (3V to 10V) or DRV8871 (6.5V to 45V). It would also be possible to use darlington drivers like L293D and L298D, but those are ancient and cause a big voltage drop. It's funny that the question came up today, as right now I'm working on a completely different approach, that will be portable, and supports more channels: https://www.wemos.cc/en/latest/d1_mini_shield/hr8833_motor.html (3V to 10V) OOTB, those motor shields are only usable via the LOLIN_I2C motor library, which does not expose the functionality required for phase shift PWM. So I started to develop my own firmware for the onboard microcontroller STC8H1K08, to make it behave similar to the PCA9685 :-) I already got some working code. If others are interested, I'll consider making this open source. |
The 'official' way to create a phase locked PWM can be found here, at least for ESP8266: IIRC, one needs to call enablePhaseLockedWaveform(), to make the linker use core_esp8266_waveform_phase instead of core_esp8266_waveform_pwm. |
@DedeHai & I have a POC ready (untested). If you want a binary, contact me on Discord. |
The video below shows an AT8870 motor shield (custom firmware), connected to a polarity change fairy light. VID_20240824_141347561_neu.mp4 |
Just tested the idea on a (analog) 12V RGBW strip, 5m with 108 LEDs/m. Works perfectly, too. |
working (but not final) implementation: |
@blazoncek, referring to https://github.com/Aircoookie/WLED/blob/bus-config/wled00/bus_manager.cpp#L687 The existing Bus classes are hardcoded in the BusManager::add() method.
Regarding the settings_leds.html and const.h, I'd like to use something like that:
|
@jw2013 that's something similar like @netmindz is doing with hub75 support. Other parts of WLED currently require at least one GPIO to be allocated to function properly. But this has nothing to do with this issue so please open a new one. Better yet, join discussion on Discord. |
@florenso please use |
Is your feature request related to a problem? Please describe.
i have a led strip that contains cold and warm leds, but it only has two wires.
Describe the solution you'd like
I want two pwm channels (cc, cw) that are never high at the same time. so that i have a option to configure this type of led strip.
Describe alternatives you've considered
Use the led strip with only warm or cold light.
Additional context
I know a lot of chips cant handle phase shifting, but if you support it only for the easy ones (esp32 for example) i would be verry happy! (because i already solderd one..., would be awsome to add this functionality)
The text was updated successfully, but these errors were encountered: