Variable PWM duty cycle resolution

This commit is contained in:
Blaz Kristan 2024-03-01 14:36:17 +01:00
parent 962e64106c
commit a2a632c415
2 changed files with 30 additions and 3 deletions

View File

@ -12,7 +12,6 @@
//colors.cpp //colors.cpp
uint32_t colorBalanceFromKelvin(uint16_t kelvin, uint32_t rgb); uint32_t colorBalanceFromKelvin(uint16_t kelvin, uint32_t rgb);
uint16_t approximateKelvinFromRGB(uint32_t rgb); uint16_t approximateKelvinFromRGB(uint32_t rgb);
void colorRGBtoRGBW(byte* rgb);
//udp.cpp //udp.cpp
uint8_t realtimeBroadcast(uint8_t type, IPAddress client, uint16_t length, byte *buffer, uint8_t bri=255, bool isRGBW=false); uint8_t realtimeBroadcast(uint8_t type, IPAddress client, uint16_t length, byte *buffer, uint8_t bri=255, bool isRGBW=false);
@ -384,6 +383,7 @@ BusPwm::BusPwm(BusConfig &bc)
if (_ledcStart == 255) { //no more free LEDC channels if (_ledcStart == 255) { //no more free LEDC channels
deallocatePins(); return; deallocatePins(); return;
} }
//_prevBri = _bri;
#endif #endif
for (unsigned i = 0; i < numPins; i++) { for (unsigned i = 0; i < numPins; i++) {
@ -395,7 +395,15 @@ BusPwm::BusPwm(BusConfig &bc)
#ifdef ESP8266 #ifdef ESP8266
pinMode(_pins[i], OUTPUT); pinMode(_pins[i], OUTPUT);
#else #else
ledcSetup(_ledcStart + i, _frequency, 8); switch (_frequency) {
case WLED_PWM_FREQ/3: _depth = 12; break; // 6510Hz
case WLED_PWM_FREQ/2: _depth = 11; break; // 9676Hz
default:
case WLED_PWM_FREQ: _depth = 10; break; // 19531Hz
case WLED_PWM_FREQ*4/3: _depth = 9; break; // 26041Hz
case WLED_PWM_FREQ*2: _depth = 8; break; // 39062Hz
}
ledcSetup(_ledcStart + i, _frequency, _depth);
ledcAttachPin(_pins[i], _ledcStart + i); ledcAttachPin(_pins[i], _ledcStart + i);
#endif #endif
} }
@ -403,6 +411,13 @@ BusPwm::BusPwm(BusConfig &bc)
_valid = true; _valid = true;
} }
void BusPwm::setBrightness(uint8_t bri) {
#ifdef ARDUINO_ARCH_ESP32
//_prevBri = _bri;
#endif
Bus::setBrightness(bri);
}
void BusPwm::setPixelColor(uint16_t pix, uint32_t c) { void BusPwm::setPixelColor(uint16_t pix, uint32_t c) {
if (pix != 0 || !_valid) return; //only react to first pixel if (pix != 0 || !_valid) return; //only react to first pixel
if (_type != TYPE_ANALOG_3CH) c = autoWhiteCalc(c); if (_type != TYPE_ANALOG_3CH) c = autoWhiteCalc(c);
@ -466,11 +481,20 @@ void BusPwm::show() {
if (!_valid) return; if (!_valid) return;
uint8_t numPins = NUM_PWM_PINS(_type); uint8_t numPins = NUM_PWM_PINS(_type);
for (unsigned i = 0; i < numPins; i++) { for (unsigned i = 0; i < numPins; i++) {
#ifdef ESP8266
uint8_t scaled = (_data[i] * _bri) / 255; uint8_t scaled = (_data[i] * _bri) / 255;
if (_reversed) scaled = 255 - scaled; if (_reversed) scaled = 255 - scaled;
#ifdef ESP8266
analogWrite(_pins[i], scaled); analogWrite(_pins[i], scaled);
#else #else
unsigned scaled = ((_data[i] * _bri) << (_depth-8)) / 255;
if (_reversed) scaled = (1<<_depth) - 1 - scaled;
// TODO: implement ledcFade() if the brightness changed between calls
// bool ledcFade(uint8_t pin, uint32_t start_duty, uint32_t target_duty, int max_fade_time_ms);
// if (_prevBri != _bri) {
// unsigned prevScaled = ((_data[i] * _prevBri) << (_depth-8)) / 255;
// ledcFade(_ledcStart + i, prevScaled, scaled, FRAMETIME-1); // frametime is a macro expanding to strip.getFrameTime() which is unwanted here
// _prevBri = _bri;
// } else
ledcWrite(_ledcStart + i, scaled); ledcWrite(_ledcStart + i, scaled);
#endif #endif
} }

View File

@ -255,6 +255,7 @@ class BusPwm : public Bus {
BusPwm(BusConfig &bc); BusPwm(BusConfig &bc);
~BusPwm() { cleanup(); } ~BusPwm() { cleanup(); }
void setBrightness(uint8_t bri) override;
void setPixelColor(uint16_t pix, uint32_t c) override; void setPixelColor(uint16_t pix, uint32_t c) override;
uint32_t getPixelColor(uint16_t pix) override; //does no index check uint32_t getPixelColor(uint16_t pix) override; //does no index check
uint8_t getPins(uint8_t* pinArray) override; uint8_t getPins(uint8_t* pinArray) override;
@ -267,6 +268,8 @@ class BusPwm : public Bus {
uint8_t _pwmdata[5]; uint8_t _pwmdata[5];
#ifdef ARDUINO_ARCH_ESP32 #ifdef ARDUINO_ARCH_ESP32
uint8_t _ledcStart; uint8_t _ledcStart;
uint8_t _depth;
//uint8_t _prevBri;
#endif #endif
uint16_t _frequency; uint16_t _frequency;