Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /* Fill-in information from Blynk Device Info here */
- #define BLYNK_TEMPLATE_ID "TMPxxxxxx"
- #define BLYNK_TEMPLATE_NAME "Device"
- #define BLYNK_AUTH_TOKEN "YourAuthToken"
- /* Comment this out to disable prints and save space */
- #define BLYNK_PRINT Serial
- #include <WiFi.h>
- #include <WiFiClient.h>
- #include <BlynkSimpleEsp32_SSL.h>
- // Your WiFi credentials.
- // Set password to "" for open networks.
- char ssid[] = "YourNetworkName";
- char pass[] = "YourPassword";
- const bool GAMMA_CORRECT = true; // set to false to disable gamma correction
- // This table remaps linear input RGB values to
- // nonlinear gamma-corrected output values for human eyes.
- // To use/read it: result = pgm_read_byte(&gamma8[color]);
- // Source: https://learn.adafruit.com/led-tricks-gamma-correction/the-quick-fix
- const uint8_t PROGMEM gamma8[] = {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2,
- 2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5,
- 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10,
- 10, 10, 11, 11, 11, 12, 12, 13, 13, 13, 14, 14, 15, 15, 16, 16,
- 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, 23, 24, 24, 25,
- 25, 26, 27, 27, 28, 29, 29, 30, 31, 32, 32, 33, 34, 35, 35, 36,
- 37, 38, 39, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 50,
- 51, 52, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 66, 67, 68,
- 69, 70, 72, 73, 74, 75, 77, 78, 79, 81, 82, 83, 85, 86, 87, 89,
- 90, 92, 93, 95, 96, 98, 99,101,102,104,105,107,109,110,112,114,
- 115,117,119,120,122,124,126,127,129,131,133,135,137,138,140,142,
- 144,146,148,150,152,154,156,158,160,162,164,167,169,171,173,175,
- 177,180,182,184,186,189,191,193,196,198,200,203,205,208,210,213,
- 215,218,220,223,225,228,231,233,236,239,241,244,247,249,252,255
- };
- // Makes sure you assign PWM capable pins
- const byte PIN_RED = 14;
- const byte PIN_GREEN = 12;
- const byte PIN_BLUE = 13;
- int rgb_red = 0;
- int rgb_green = 0;
- int rgb_blue = 0;
- int rgb_brightness = 0;
- //uncomment next line if using a Common Anode LED
- //#define COMMON_ANODE
- const uint8_t MAX_COLOR_VALUE = 255;
- struct HSL_t {
- double h; // angle in degrees
- double s; // saturation % between 0 and 1
- double l; // luminance % between 0 and 1
- };
- struct RGB_t {
- int r; // red, 0 to 255
- int g; // green, 0 to 255
- int b; // blue, 0 to 255
- };
- HSL_t rgb2hsl(uint8_t red, uint8_t green, uint8_t blue) {
- // Returns HSL value calculated from red, green, blue values where:
- // h = hue in degrees, 0 to 360
- // s = saturation, 0.0 to 1.0
- // l = luminance, 0.0 to 1.0
- HSL_t result;
- // Scale red, blue, green from integer range 0-255 to float 0-1
- double r = static_cast<double>(red / 255.0);
- double g = static_cast<double>(green / 255.0);
- double b = static_cast<double>(blue / 255.0);
- float c_max = max(max(r,g),b);
- float c_min = min(min(r,g),b);
- // Luminance
- result.l = (c_max + c_min) / 2.0;
- // Saturation
- if (c_max == c_min) {
- // No saturation, achromatic
- result.h = 0.0;
- result.s = 0.0;
- return result;
- } else {
- if (result.l > 0.5) {
- // Saturation = ( max-min)/(2.0-max-min)
- result.s = (c_max - c_min) / (2.0 - c_max - c_min);
- } else {
- // Saturation = (max-min)/(max+min)
- result.s = (c_max - c_min) / (c_max + c_min);
- }
- }
- // Hue
- if (r == max(max(r,g),b)) {
- // red is the maximum value
- result.h = (g - b) / (c_max - c_min);
- } else if (g == max(max(r,g),b)) {
- // green is the maximum value
- result.h = 2.0 + (b - r) / (c_max - c_min);
- } else if (b == max(max(r,g),b)) {
- // blue is the maximum value
- result.h = 4.0 + (r - g) / (c_max - c_min);
- } else {
- // ERROR
- result.h = 0.0;
- }
- result.h *= 60.0;
- if (result.h < 0) {
- result.h += 360.0;
- }
- return result;
- } //rgb2hsl()
- RGB_t hsl2rgb(double h, double s, double l) {
- RGB_t result;
- float t_1 = 0.0;
- float t_2 = 0.0;
- float t_r = 0.0;
- float t_g = 0.0;
- float t_b = 0.0;
- if (h == 0.0 && s == 0.0) {
- // No saturation, so it is a shade of gray.
- // Covert the luminance and set r, g, b to that level.
- result.r = static_cast<int>(l * 255.0);
- result.g = static_cast<int>(l * 255.0);
- result.b = static_cast<int>(l * 255.0);
- } else {
- if (l < 0.5) {
- t_1 = l * (1.0 + s);
- } else {
- t_1 = l + s - l * s;
- }
- t_2 = 2.0 * l - t_1;
- // convert hue in degress to 1 by diving by 360 degrees
- h /= 360.0;
- t_r = h + (1.0/3.0);
- if (t_r < 0.0) {
- t_r += 1.0;
- }
- if (t_r > 1.0) {
- t_r -= 1.0;
- }
- t_g = h;
- if (t_g < 0.0) {
- t_g += 1.0;
- }
- if (t_g > 1.0) {
- t_g -= 1.0;
- }
- t_b = h - (1.0/3.0);
- if (t_b < 0.0) {
- t_b += 1.0;
- }
- if (t_b > 1.0) {
- t_b -= 1.0;
- }
- // red
- if (6.0*t_r < 1.0) {
- result.r = static_cast<int>(round((t_2 + (t_1 - t_2) * 6.0 * t_r) * 255.0));
- } else if (2.0*t_r < 1.0) {
- result.r = static_cast<int>(round(t_1 * 255.0));
- } else if (3.0*t_r < 2.0) {
- result.r = static_cast<int>(round((t_2 + (t_1 - t_2) * (2.0/3.0 - t_r) * 6.0) * 255.0));
- } else if (3.0*t_r > 2.0) {
- result.r = static_cast<int>(round(t_2 * 255.0));
- }
- // green
- if (6.0*t_g < 1.0) {
- result.g = static_cast<int>(round((t_2 + (t_1 - t_2) * 6.0 * t_g) * 255.0));
- } else if (2.0*t_g < 1.0) {
- result.g = static_cast<int>(round(t_1 * 255.0));
- } else if (3.0*t_g < 2.0) {
- result.g = static_cast<int>(round((t_2 + (t_1 - t_2) * (2.0/3.0 - t_g) * 6.0) * 255.0));
- } else if (3.0*t_g > 2.0) {
- result.g = static_cast<int>(round(t_2 * 255.0));
- }
- // blue
- if (6.0*t_b < 1.0) {
- result.b = static_cast<int>(round((t_2 + (t_1 - t_2) * 6.0 * t_b) * 255.0));
- } else if (2.0*t_b < 1.0) {
- result.b = static_cast<int>(round(t_1 * 255.0));
- } else if (3.0*t_b < 2.0) {
- result.b = static_cast<int>(round((t_2 + (t_1 - t_2) * (2.0/3.0 - t_b) * 6.0) * 255.0));
- } else if (3.0*t_b > 2.0) {
- result.b = static_cast<int>(round(t_2 * 255.0));
- }
- }
- return result;
- } // hsl2rgb()
- void setRGB(uint8_t red, uint8_t green, uint8_t blue, uint8_t luminance, bool gamma_correct) {
- // Note: the Blynk RGB Light Control widget color values
- // assume the use of a common cathode RGB.
- bool white_mode = false;
- if (red > 218 && green > 218 && blue > 168) {
- // Possibly in White Mode
- white_mode = true;
- }
- if (MAX_COLOR_VALUE == 255 && gamma_correct == true && white_mode == false) {
- // Gamma correction is applied to compensate for the non-linearity of
- // the human eye perception of color using pgm_read_byte(&gamma8[color]);
- red = pgm_read_byte(&gamma8[red]);
- green = pgm_read_byte(&gamma8[green]);
- blue = pgm_read_byte(&gamma8[blue]);
- }
- // Scale RGB color values based on the luminance setting.
- // Note that above 50% luminance, the color changes a lot.
- // Therefore, scale everything down by 1/2, so 100% = 50%.
- HSL_t hsl = rgb2hsl(red, green, blue);
- // hsl.l range is 0.0 to 1.0
- // luminance range is 0 to 100
- // Scale luminance from 0 to 100 to 0.0 to 1.0
- hsl.l = static_cast<double>(luminance)/100.0;
- // Scale luminance further by 1/2 to keep color true
- hsl.l /= 2.0;
- RGB_t rgb = hsl2rgb(hsl.h, hsl.s, hsl.l);
- red = rgb.r; green = rgb.g; blue=rgb.b;
- #ifdef COMMON_ANODE
- red = MAX_COLOR_VALUE - red;
- green = MAX_COLOR_VALUE - green;
- blue = MAX_COLOR_VALUE - blue;
- #else
- // common cathode RGB
- #endif
- // Write the RGB values to the RGB attached to the hardware
- analogWrite(PIN_RED, red);
- analogWrite(PIN_GREEN, green);
- analogWrite(PIN_BLUE, blue);
- } // setRGB()
- uint8_t rgb_light_control_mode = 0; // 0 = mode unknown, 1 = Color, 2 = White, 3 = Animation
- uint8_t animation_fade_strobe = 0; // 0 = mode unknown, 1 = strobe, 2 = fade
- RGB_t rgb_color_white_mode;
- uint8_t animation_pattern_count = 0; // either 3 or 2 when known
- RGB_t rgb_animation_left;
- RGB_t rgb_animation_right;
- RGB_t rgb_animation_top;
- /////////////////////////////////////////////////////////////////////////
- BLYNK_WRITE(V10) {
- // V10 integer, BUTTON, 0 or 1
- // Turn RGB on/off based on the BUTTON value
- int btn_state = param.asInt();
- if (btn_state == 1) {
- // do nothing with rgb_brightness
- } else {
- rgb_brightness = 0;
- }
- Serial.print("V10 = '");
- Serial.print(btn_state);
- Serial.println("' BUTTON..");
- setRGB(rgb_red, rgb_green, rgb_blue, rgb_brightness, GAMMA_CORRECT);
- } // BLYNK_WRITE(V10)
- BLYNK_WRITE(V2) {
- // Called when datastream for virtual pin V2 is updated
- // V2 string, COLOR
- Serial.println("");
- //Serial.println("All V2 array items:");
- byte param_items_count = 0;
- for (auto i = param.begin(); i < param.end(); ++i) {
- //Serial.print("\t");
- //Serial.print(param_items_count);
- //Serial.print(" = '");
- //Serial.print(i.asString());
- //Serial.println("'");
- if (param_items_count == 3) {
- String button_mode = i.asString();
- if (button_mode == "true") {
- rgb_light_control_mode = 1; // Color Mode
- } else if (button_mode == "false") {
- rgb_light_control_mode = 2; // White Mode
- }
- }
- if (param_items_count == 4) {
- //Serial.println("\tparam_items_count == 4");
- rgb_light_control_mode = 3; // Animation mode
- int fade_strobe = param[4].asInt();
- if (fade_strobe == 0) {
- animation_fade_strobe = 2; // fade
- } else if (fade_strobe == 1) {
- animation_fade_strobe = 1; // strobe
- } else {
- animation_fade_strobe = 0;
- }
- }
- param_items_count++;
- }
- //Serial.print("param_items_count = "); Serial.println(param_items_count);
- rgb_color_white_mode.r = param[0].asInt();
- rgb_color_white_mode.g = param[1].asInt();
- rgb_color_white_mode.b = param[2].asInt();
- if (param_items_count > 4) {
- rgb_animation_left.r = param[5].asInt();;
- rgb_animation_left.g = param[6].asInt();;
- rgb_animation_left.b = param[7].asInt();;
- }
- if (param_items_count == 11) {
- animation_pattern_count = 2;
- rgb_animation_top.r = 0;
- rgb_animation_top.g = 0;
- rgb_animation_top.b = 0;
- rgb_animation_right.r = param[8].asInt();;
- rgb_animation_right.g = param[9].asInt();;
- rgb_animation_right.b = param[10].asInt();;
- } else if (param_items_count == 14) {
- animation_pattern_count = 3;
- rgb_animation_top.r = param[8].asInt();;
- rgb_animation_top.g = param[9].asInt();;
- rgb_animation_top.b = param[10].asInt();;
- rgb_animation_right.r = param[11].asInt();;
- rgb_animation_right.g = param[12].asInt();;
- rgb_animation_right.b = param[13].asInt();;
- } else {
- animation_pattern_count = 0;
- }
- // Using the populated global values for:
- // rgb_light_control_mode, animation_fade_strobe, rgb_light_control_mode
- // animation_fade_strobe, rgb_color_white_mode, rgb_animation_left
- // rgb_animation_right, rgb_animation_top, animation_pattern_count
- switch (rgb_light_control_mode) {
- case 0:
- // button mode unknown
- Serial.println("RGB Light Control button mode UNKNOWN");
- break;
- case 1:
- // Color Mode
- Serial.println("Color Mode");
- Serial.print("R: "); Serial.print(rgb_color_white_mode.r); Serial.print("\tG:"); Serial.print(rgb_color_white_mode.g); Serial.print("\tB:"); Serial.println(rgb_color_white_mode.b);
- break;
- case 2:
- // White Mode
- Serial.println("White Mode");
- Serial.print("R: "); Serial.print(rgb_color_white_mode.r); Serial.print("\tG:"); Serial.print(rgb_color_white_mode.g); Serial.print("\tB:"); Serial.println(rgb_color_white_mode.b);
- break;
- case 3:
- // Animation Mode
- if (animation_fade_strobe == 1) {
- Serial.println("Animation Mode - strobe");
- } else if (animation_fade_strobe == 2) {
- Serial.println("Animation Mode - fade");
- }
- if (animation_fade_strobe > 0) {
- Serial.print("\t"); Serial.print(animation_pattern_count); Serial.println("x Pattern: ");
- Serial.print("\tLeft\tR: "); Serial.print(rgb_animation_left.r); Serial.print("\tG:"); Serial.print(rgb_animation_left.g); Serial.print("\tB:"); Serial.println(rgb_animation_left.b);
- if (animation_pattern_count > 2) {
- Serial.print("\tTop\tR: "); Serial.print(rgb_animation_top.r); Serial.print("\tG:"); Serial.print(rgb_animation_top.g); Serial.print("\tB:"); Serial.println(rgb_animation_top.b);
- }
- Serial.print("\tRight\tR: "); Serial.print(rgb_animation_right.r); Serial.print("\tG:"); Serial.print(rgb_animation_right.g); Serial.print("\tB:"); Serial.println(rgb_animation_right.b);
- }
- break;
- } // switch
- Serial.println("");
- setRGB(rgb_color_white_mode.r, rgb_color_white_mode.g, rgb_color_white_mode.b, rgb_brightness, GAMMA_CORRECT);
- } // BLYNK_WRITE(V2)
- BLYNK_WRITE(V6) {
- // V6 integer, BRIGHTNESS. 0 to 100
- rgb_brightness = param.asInt();
- Serial.print("V6 = '");
- Serial.print(rgb_brightness);
- Serial.println("' BRIGHTNESS..");
- setRGB(rgb_red, rgb_green, rgb_blue, rgb_brightness, GAMMA_CORRECT);
- } // BLYNK_WRITE(V6)
- BLYNK_WRITE(V5) {
- // V5 integer, ANIMATION SPEED, 0 to 10000
- int animation_speed = param.asInt();
- Serial.print("V5 = '");
- Serial.print(animation_speed);
- Serial.println("' ANIMATION SPEED");
- } // BLYNK_WRITE(V5)
- BLYNK_CONNECTED() {
- // Executes every time Blynk is connected to the cloud
- // (typically only if WiFi connection is lost, otherwise Blynk stays connected)
- Serial.println("BLYNK_CONNECTED() .. Blynk connected to the cloud.");
- // Request Blynk server to re-send latest values for all virtual pins
- Blynk.syncAll();
- } // BLYNK_CONNECTED
- /////////////////////////////////////////////////////////////////////////
- void setup() {
- Serial.begin(115200);
- while (!Serial) {
- delay(1);
- }
- Serial.println("\nSerial ready");
- // RGB
- pinMode(PIN_RED, OUTPUT);
- pinMode(PIN_GREEN, OUTPUT);
- pinMode(PIN_BLUE, OUTPUT);
- setRGB(0, 0, 0, 0, GAMMA_CORRECT);
- rgb_color_white_mode.r = 0;
- rgb_color_white_mode.g = 0;
- rgb_color_white_mode.b = 0;
- rgb_animation_left.r = 0;
- rgb_animation_left.g = 0;
- rgb_animation_left.b = 0;
- rgb_animation_right.r = 0;
- rgb_animation_right.g = 0;
- rgb_animation_right.b = 0;
- rgb_animation_top.r = 0;
- rgb_animation_top.g = 0;
- rgb_animation_top.b = 0;
- // Try to connect to Blynk Cloud.
- Serial.println("Connecting to Blynk..");
- Blynk.begin(BLYNK_AUTH_TOKEN, ssid, pass);
- Serial.println("\nSetup complete\n");
- } // setup()
- void loop() {
- Blynk.run();
- } // loop()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement