Merge pull request #487 from Aircoookie/pr/481

Add Analog/Solid RGB(W) strip support
This commit is contained in:
Aircoookie 2019-12-20 00:07:12 +01:00 committed by GitHub
commit 512c4dd6f1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 183 additions and 63 deletions

View File

@ -4,14 +4,17 @@
[platformio]
src_dir = ./wled00
data_dir = ./wled00/data
lib_extra_dirs = ./wled00/src
;lib_extra_dirs = ./wled00/src
lib_dir = ./wled00/src
; Please uncomment one of the 5 lines below to select your board
; env_default = nodemcuv2
; env_default = esp01
; env_default = esp01_1m
; env_default = d1_mini
; env_default = esp32dev
; env_default = esp8285_4CH_MagicHome
; env_default = esp8285_4CH_H801
; env_default = esp8285_5CH_H801
[common]
framework = arduino
@ -77,7 +80,7 @@ build_flags =
-D WLED_DISABLE_BLYNK
-D WLED_DISABLE_CRONIXIE
; -D WLED_DISABLE_HUESYNC
-D WLED_DISABLE_INFRARED
; -D WLED_DISABLE_INFRARED
[common:esp8266_512k]
platform = espressif8266@1.8.0
@ -89,15 +92,15 @@ build_flags =
; -D WLED_DISABLE_ALEXA
-D WLED_DISABLE_BLYNK
-D WLED_DISABLE_CRONIXIE
; -D WLED_DISABLE_HUESYNC
-D WLED_DISABLE_INFRARED
-D WLED_DISABLE_HUESYNC
; -D WLED_DISABLE_INFRARED
[common:esp32]
platform = espressif32@1.11.1
build_flags =
-D PIO_FRAMEWORK_ARDUINO_LWIP2_HIGHER_BANDWIDTH
-D ARDUINO_ARCH_ESP32
-D WLED_DISABLE_INFRARED
-D WLED_DISABLE_INFRARED
# see: http://docs.platformio.org/en/latest/platforms/espressif8266.html
[env:nodemcuv2]
@ -147,6 +150,7 @@ framework = ${common.framework}
build_flags =
${common.build_flags}
${common:esp8266_512k.build_flags}
-D WLED_DISABLE_INFRARED
lib_deps =
${common.lib_deps_external}
@ -165,3 +169,49 @@ lib_deps =
lib_ignore =
IRremoteESP8266
ESPAsyncUDP
[env:esp8285_4CH_MagicHome]
board = esp8285
platform = ${common:esp8266_1M.platform}
monitor_speed = ${common.monitor_speed}
upload_speed = ${common.upload_speed}
framework = ${common.framework}
build_flags =
${common.build_flags}
${common:esp8266_1M.build_flags}
-D WLED_DISABLE_HUESYNC
-D WLED_ENABLE_ANALOG_LEDS
lib_deps =
${common.lib_deps_external}
[env:esp8285_4CH_H801]
board = esp8285
platform = ${common:esp8266_1M.platform}
monitor_speed = ${common.monitor_speed}
upload_speed = ${common.upload_speed}
framework = ${common.framework}
build_flags =
${common.build_flags}
${common:esp8266_1M.build_flags}
-D WLED_DISABLE_HUESYNC
-D WLED_ENABLE_ANALOG_LEDS
-D WLED_USE_H801
lib_deps =
${common.lib_deps_external}
[env:esp8285_5CH_H801]
board = esp8285
platform = ${common:esp8266_1M.platform}
monitor_speed = ${common.monitor_speed}
upload_speed = ${common.upload_speed}
framework = ${common.framework}
build_flags =
${common.build_flags}
${common:esp8266_1M.build_flags}
-D WLED_DISABLE_HUESYNC
-D WLED_ENABLE_ANALOG_LEDS
-D WLED_USE_H801
-D WLED_ENABLE_5CH_LEDS
lib_deps =
${common.lib_deps_external}

View File

@ -5,12 +5,18 @@
//PIN CONFIGURATION
#define LEDPIN 2 //strip pin. Any for ESP32, gpio2 or 3 is recommended for ESP8266 (gpio2/3 are labeled D4/RX on NodeMCU and Wemos)
//#define USE_APA102 // Uncomment for using APA102 LEDs.
#define BTNPIN 0 //button pin. Needs to have pullup (gpio0 recommended)
#define IR_PIN 4 //infrared pin (-1 to disable)
#define RLYPIN 12 //pin for relay, will be set HIGH if LEDs are on (-1 to disable). Also usable for standby leds, triggers,...
#define AUXPIN -1 //debug auxiliary output pin (-1 to disable)
//#define WLED_USE_ANALOG_LEDS //Uncomment for using "dumb" PWM controlled LEDs (see pins below, default R: gpio5, G: 12, B: 15, W: 13)
//#define WLED_USE_H801 //H801 controller. Please uncomment #define WLED_USE_ANALOG_LEDS as well
//#define WLED_USE_5CH //5 Channel H801 for cold and warm white
#define RLYMDE 1 //mode for relay, 0: LOW if LEDs are on 1: HIGH if LEDs are on
#define BTNPIN 0 //button pin. Needs to have pullup (gpio0 recommended)
#define IR_PIN 4 //infrared pin (-1 to disable) MagicHome: 4, H801 Wifi: 0
#define RLYPIN 12 //pin for relay, will be set HIGH if LEDs are on (-1 to disable). Also usable for standby leds, triggers,...
#define AUXPIN -1 //debug auxiliary output pin (-1 to disable)
#define RLYMDE 1 //mode for relay, 0: LOW if LEDs are on 1: HIGH if LEDs are on
//END CONFIGURATION
#ifdef USE_APA102
#define CLKPIN 0
@ -20,6 +26,27 @@
#endif
#endif
#ifdef WLED_USE_ANALOG_LEDS
//PWM pins - PINs 15,13,12,14 (W2 = 04)are used with H801 Wifi LED Controller
#ifdef WLED_USE_H801
#define RPIN 15 //R pin for analog LED strip
#define GPIN 13 //G pin for analog LED strip
#define BPIN 12 //B pin for analog LED strip
#define WPIN 14 //W pin for analog LED strip (W1: 14, W2: 04)
#define W2PIN 04 //W2 pin for analog LED strip
#undef BTNPIN
#undef IR_PIN
#define IR_PIN 0 //infrared pin (-1 to disable) MagicHome: 4, H801 Wifi: 0
#else
//PWM pins - PINs 5,12,13,15 are used with Magic Home LED Controller
#define RPIN 5 //R pin for analog LED strip
#define GPIN 12 //G pin for analog LED strip
#define BPIN 15 //B pin for analog LED strip
#define WPIN 13 //W pin for analog LED strip (W1: 14, W2: 04)
#endif
#undef RLYPIN
#define RLYPIN -1 //disable as pin 12 is used by analog LEDs
#endif
//automatically uses the right driver method for each platform
#ifdef ARDUINO_ARCH_ESP32
@ -104,40 +131,94 @@ public:
#endif
_pGrbw->Begin();
break;
#ifdef WLED_USE_ANALOG_LEDS
//init PWM pins - PINs 5,12,13,15 are used with Magic Home LED Controller
pinMode(RPIN, OUTPUT);
pinMode(GPIN, OUTPUT);
pinMode(BPIN, OUTPUT);
switch (_type) {
case NeoPixelType_Grb: break;
#ifdef WLED_USE_5CH_LEDS
case NeoPixelType_Grbw: pinMode(WPIN, OUTPUT); pinMode(W2PIN, OUTPUT); break;
#else
case NeoPixelType_Grbw: pinMode(WPIN, OUTPUT); break;
#endif
}
analogWriteRange(255); //same range as one RGB channel
analogWriteFreq(880); //PWM frequency proven as good for LEDs
#endif
}
}
#ifdef WLED_USE_ANALOG_LEDS
void SetRgbwPwm(uint8_t r, uint8_t g, uint8_t b, uint8_t w, uint8_t w2=0)
{
analogWrite(RPIN, r);
analogWrite(GPIN, g);
analogWrite(BPIN, b);
switch (_type) {
case NeoPixelType_Grb: break;
#ifdef WLED_USE_5CH_LEDS
case NeoPixelType_Grbw: analogWrite(WPIN, w); analogWrite(W2PIN, w2); break;
#else
case NeoPixelType_Grbw: analogWrite(WPIN, w); break;
#endif
}
}
#endif
void Show()
{
byte b;
switch (_type)
{
case NeoPixelType_Grb: _pGrb->Show(); break;
case NeoPixelType_Grbw: _pGrbw->Show(); break;
}
}
bool CanShow() const
{
switch (_type) {
case NeoPixelType_Grb: _pGrb->CanShow(); break;
case NeoPixelType_Grbw: _pGrbw->CanShow(); break;
}
}
void SetPixelColor(uint16_t indexPixel, RgbColor color)
{
switch (_type) {
case NeoPixelType_Grb: _pGrb->SetPixelColor(indexPixel, color); break;
case NeoPixelType_Grbw:_pGrbw->SetPixelColor(indexPixel, color); break;
case NeoPixelType_Grb: _pGrb->Show(); break;
case NeoPixelType_Grbw: _pGrbw->Show(); break;
}
}
void SetPixelColor(uint16_t indexPixel, RgbwColor color)
{
switch (_type) {
case NeoPixelType_Grb: _pGrb->SetPixelColor(indexPixel, RgbColor(color.R,color.G,color.B)); break;
case NeoPixelType_Grbw: _pGrbw->SetPixelColor(indexPixel, color); break;
case NeoPixelType_Grb: {
_pGrb->SetPixelColor(indexPixel, RgbColor(color.R,color.G,color.B));
#ifdef WLED_USE_ANALOG_LEDS
if (indexPixel != 0) return; //set analog LEDs from first pixel
byte b = _pGrb->GetBrightness();
SetRgbwPwm(color.R * b / 255, color.G * b / 255, color.B * b / 255, 0);
#endif
}
break;
case NeoPixelType_Grbw: {
_pGrbw->SetPixelColor(indexPixel, color);
#ifdef WLED_USE_ANALOG_LEDS
if (indexPixel != 0) return; //set analog LEDs from first pixel
byte b = _pGrbw->GetBrightness();
// check color values for Warm / Cold white mix (for RGBW) // EsplanexaDevice.cpp
#ifdef WLED_USE_5CH_LEDS
if (color.R == 255 & color.G == 255 && color.B == 255 && color.W == 255) {
SetRgbwPwm(0, 0, 0, 0, color.W * b / 255);
} else if (color.R == 127 & color.G == 127 && color.B == 127 && color.W == 255) {
SetRgbwPwm(0, 0, 0, color.W * b / 512, colorW.W * b / 255);
} else if (color.R == 0 & color.G == 0 && color.B == 0 && color.W == 255) {
SetRgbwPwm(0, 0, 0, color.W * b / 255, 0);
} else if (color.R == 130 & color.G == 90 && color.B == 0 && color.W == 255) {
SetRgbwPwm(0, 0, 0, color.W * b / 255, color.W * b / 512);
} else if (color.R == 255 & color.G == 153 && color.B == 0 && color.W == 255) {
SetRgbwPwm(0, 0, 0, color.W * b / 255, 0);
} else { // not only white colors
SetRgbwPwm(color.R * b / 255, colorW.G * b / 255, colorW.B * b / 255, color.W * b / 255);
}
#else
SetRgbwPwm(color.R * b / 255, color.G * b / 255, color.B * b / 255, color.W * b / 255);
#endif
#endif
}
break;
}
}
void SetBrightness(byte b)
@ -148,15 +229,6 @@ public:
}
}
RgbColor GetPixelColor(uint16_t indexPixel) const
{
switch (_type) {
case NeoPixelType_Grb: return _pGrb->GetPixelColor(indexPixel); break;
case NeoPixelType_Grbw: /*doesn't support it so we don't return it*/ break;
}
return 0;
}
// NOTE: Due to feature differences, some support RGBW but the method name
// here needs to be unique, thus GetPixeColorRgbw
RgbwColor GetPixelColorRgbw(uint16_t indexPixel) const
@ -168,21 +240,6 @@ public:
return 0;
}
void ClearTo(RgbColor color)
{
switch (_type) {
case NeoPixelType_Grb: _pGrb->ClearTo(color); break;
case NeoPixelType_Grbw:_pGrbw->ClearTo(color); break;
}
}
void ClearTo(RgbwColor color)
{
switch (_type) {
case NeoPixelType_Grb: break;
case NeoPixelType_Grbw:_pGrbw->ClearTo(color); break;
}
}
private:
NeoPixelType _type;

View File

@ -110,8 +110,8 @@ uint32_t EspalexaDevice::getKelvin()
uint32_t EspalexaDevice::getRGB()
{
if (_rgb != 0) return _rgb; //color has not changed
uint8_t rgb[3];
float r, g, b;
byte rgb[4]{0, 0, 0, 0};
float r, g, b, w;
if (_mode == EspalexaColorMode::none) return 0;
@ -122,6 +122,15 @@ uint32_t EspalexaDevice::getRGB()
float temp = 10000/ _ct; //kelvins = 1,000,000/mired (and that /100)
float r, g, b;
// Cold white to warm white receiving from Alexa: _ct = 199, 234, 284, 350, 383 (from cold white to warm white)
switch (_ct) {
case 199: rgb[0]=255,rgb[1]=255,rgb[2]=255;rgb[3]=255;break;
case 234: rgb[0]=127,rgb[1]=127,rgb[2]=127;rgb[3]=255;break;
case 284: rgb[0]=0,rgb[1]=0,rgb[2]=0;rgb[3]=255;break;
case 350: rgb[0]=130,rgb[1]=90,rgb[2]=0;rgb[3]=255;break;
case 383: rgb[0]=255,rgb[1]=153,rgb[2]=0;rgb[3]=255;break;
default: {
if( temp <= 66 ){
r = 255;
g = temp;
@ -143,6 +152,9 @@ uint32_t EspalexaDevice::getRGB()
rgb[0] = (byte)constrain(r,0.1,255.1);
rgb[1] = (byte)constrain(g,0.1,255.1);
rgb[2] = (byte)constrain(b,0.1,255.1);
}
}
} else if (_mode == EspalexaColorMode::hs)
{
float h = ((float)_hue)/65535.0;
@ -216,7 +228,7 @@ uint32_t EspalexaDevice::getRGB()
rgb[1] = 255.0*g;
rgb[2] = 255.0*b;
}
_rgb = ((rgb[0] << 16) | (rgb[1] << 8) | (rgb[2]));
_rgb = ((rgb[3] << 24) | (rgb[0] << 16) | (rgb[1] << 8) | (rgb[2])); //white value is only >0 if Alexa did provide a CT value, RGB colors will not be touched.
return _rgb;
}

View File

@ -32,7 +32,6 @@
//to toggle usb serial debug (un)comment the following line
//#define WLED_DEBUG
//library inclusions
#include <Arduino.h>
#ifdef ESP8266
@ -85,6 +84,7 @@
#endif
#ifdef ARDUINO_ARCH_ESP32
#undef WLED_USE_ANALOG_LEDS // Solid RGBW not implemented for ESP32 yet
/*#ifndef WLED_DISABLE_INFRARED
#include <IRremote.h>
#endif*/ //there are issues with ESP32 infrared, so it is disabled for now
@ -98,8 +98,8 @@
//version code in format yymmddb (b = daily build)
#define VERSION 1912182
char versionString[] = "0.9.0-b1";
#define VERSION 1912191
char versionString[] = "0.9.0-b2";
//AP and OTA default passwords (for maximum change them!)

View File

@ -62,10 +62,11 @@ void onAlexaChange(EspalexaDevice* dev)
} else //color
{
uint32_t color = espalexaDevice->getRGB();
col[3] = ((color >> 24) & 0xFF); // white color from Alexa is "pure white only"
col[0] = ((color >> 16) & 0xFF);
col[1] = ((color >> 8) & 0xFF);
col[2] = (color & 0xFF);
if (useRGBW) colorRGBtoRGBW(col);
if (useRGBW && col[3] == 0) colorRGBtoRGBW(col); // do not touch white value if EspalexaDevice.cpp did set the white channel
colorUpdated(10);
}
}

View File

@ -165,6 +165,6 @@ void colorRGBtoRGBW(byte* rgb) //rgb to rgbw (http://codewelt.com/rgbw)
float low = minf(rgb[0],minf(rgb[1],rgb[2]));
float high = maxf(rgb[0],maxf(rgb[1],rgb[2]));
if (high < 0.1f) return;
float sat = 255.0f * ((high - low) / high);
float sat = 100.0f * ((high - low) / high);; // maximum saturation is 100 (corrected from 255)
rgb[3] = (byte)((255.0f - sat) / 255.0f * (rgb[0] + rgb[1] + rgb[2]) / 3);
}