+/*\r
+ Filename: esp32_ws2812_effects.ino\r
+ Description: Demonstrates rainbow, color wipe, solid color, and breathing effects using WS2812 LED with ESP32.\r
+ Author: www.oceanlabz.in\r
+ Modification: 1/4/2025\r
+*/\r
+ \r
+ #include <ArduinoMqttClient.h>\r
+#include <Adafruit_NeoPixel.h>\r
+#include <WiFi.h>\r
+#include <stdlib.h>\r
+#include <string.h>\r
+ \r
+#define PIN 18 // Use a safe digital GPIO pin on ESP32\r
+#define NUM_LEDS 150 // Number of WS2812 LEDs\r
+#define DELAY_TIME 10 // Delay for Rainbow effect\r
+#define BREATH_SPEED 10 // Speed for breathing effect\r
+ \r
+Adafruit_NeoPixel strip(NUM_LEDS, PIN, NEO_GRB + NEO_KHZ800);\r
+\r
+const char ssid[] = "Pelle Sladdlös";\r
+const char pass[] = "";\r
+\r
+const char broker[] = "192.168.0.110";\r
+const char topic_enable[] = "/disco_box/enable";\r
+const char topic_animation[] = "/disco_box/animation";\r
+const char topic_max_brightness[] = "/disco_box/max_brightness";\r
+const char topic_anim_speed[] = "/disco_box/anim_speed";\r
+const char topic_color[] = "/disco_box/color"; \r
+\r
+const int port = 1883;\r
+\r
+const uint32_t WHITE = strip.Color(255, 255, 255);\r
+const uint32_t OFF_WHITE = strip.Color(242, 140, 40);\r
+const uint32_t BLUE = strip.Color(0, 0, 255);\r
+const uint32_t CYAN = strip.Color(0, 255, 255);\r
+const uint32_t YELLOW = strip.Color(255, 255, 0);\r
+const uint32_t VIOLET = strip.Color(127,0,255);\r
+\r
+const uint32_t MAGENTA = strip.Color(255, 0, 255);\r
+const uint32_t INIDIGO = strip.Color(86,5,145);\r
+\r
+\r
+const uint32_t GREEN = strip.Color(0, 255, 0);\r
+const uint32_t RED = strip.Color(255, 0, 0);\r
+const uint32_t ORANGE = strip.Color(255, 165, 0);\r
+\r
+const uint32_t OFF = strip.Color(0,0,0);\r
+\r
+WiFiClient wifiClient;\r
+MqttClient mqttClient(wifiClient);\r
+\r
+bool disabled = true;\r
+char current_anim[64] = {0};\r
+uint32_t current_color = OFF; \r
+float current_max_brightness = 0;\r
+float current_anim_speed = 0;\r
+ \r
+\r
+\r
+void setup() {\r
+ strip.begin();\r
+ strip.show(); // Initialize all pixels to 'off'\r
+\r
+ Serial.begin(115200);\r
+ delay(1000);\r
+\r
+ WiFi.mode(WIFI_STA); //Optional\r
+ WiFi.begin(ssid, pass);\r
+ Serial.println("\nConnecting");\r
+\r
+ while(WiFi.status() != WL_CONNECTED){\r
+ Serial.print(".");\r
+ delay(100);\r
+ }\r
+ Serial.println("\nConnected to the WiFi network");\r
+\r
+\r
+ Serial.print("Attempting to connect to the MQTT broker: ");\r
+ Serial.println(broker);\r
+\r
+ if (!mqttClient.connect(broker, port)) {\r
+ Serial.print("MQTT connection failed! Error code = ");\r
+ Serial.println(mqttClient.connectError());\r
+\r
+ while (1);\r
+ }\r
+\r
+ Serial.println("You're connected to the MQTT broker!");\r
+ Serial.println();\r
+\r
+ // set the message receive callback\r
+ mqttClient.onMessage(onMqttMessage);\r
+\r
+ Serial.println("Subscribing to topics!");\r
+\r
+ // subscribe to a topic\r
+ mqttClient.subscribe(topic_enable);\r
+ mqttClient.subscribe(topic_animation);\r
+ mqttClient.subscribe(topic_max_brightness);\r
+ mqttClient.subscribe(topic_anim_speed);\r
+ mqttClient.subscribe(topic_color);\r
+}\r
+\r
+void onMqttMessage(int messageSize) {\r
+\r
+ auto topic = mqttClient.messageTopic();\r
+\r
+ char message[64];\r
+ int index = 0;\r
+\r
+ while (mqttClient.available() && index < 64 - 1)\r
+ {\r
+ message[index++] = (char)mqttClient.read();\r
+ }\r
+\r
+ message[index] = '\0'; // Null-terminate the C-string\r
+\r
+ if (topic == topic_enable)\r
+ {\r
+ Serial.println("enabled case");\r
+ disabled = (strcmp(message, "0") == 0);\r
+ }\r
+ else if (topic == topic_animation)\r
+ {\r
+ Serial.println("animation case");\r
+ strcpy(current_anim, message);\r
+ }\r
+ else if (topic == topic_max_brightness)\r
+ {\r
+ Serial.println("max_brightness case");\r
+ current_max_brightness = atof(message); \r
+ }\r
+ else if (topic == topic_anim_speed)\r
+ {\r
+ Serial.println("anim_speed case");\r
+ current_anim_speed = atof(message);\r
+ }\r
+ else if (topic == topic_color)\r
+ {\r
+ if (strcmp(message, "White") == 0)\r
+ {\r
+ current_color = WHITE;\r
+ }\r
+ else if (strcmp(message, "Off_White") == 0)\r
+ {\r
+ current_color = OFF_WHITE;\r
+ }\r
+ else if (strcmp(message, "Blue") == 0)\r
+ {\r
+ current_color = BLUE;\r
+ }\r
+ else if (strcmp(message, "Cyan") == 0)\r
+ {\r
+ current_color = CYAN;\r
+ }\r
+ else if (strcmp(message, "Yellow") == 0)\r
+ {\r
+ current_color = YELLOW;\r
+ }\r
+ else if (strcmp(message, "Violet") == 0)\r
+ {\r
+ current_color = VIOLET;\r
+ }\r
+ else if (strcmp(message, "Indigo") == 0)\r
+ {\r
+ current_color = INIDIGO;\r
+ }\r
+ else if (strcmp(message, "Magenta") == 0)\r
+ {\r
+ current_color = MAGENTA;\r
+ }\r
+ else if (strcmp(message, "Green") == 0)\r
+ {\r
+ current_color = GREEN;\r
+ }\r
+ else if (strcmp(message, "Red") == 0)\r
+ {\r
+ current_color = RED;\r
+ }\r
+ else if (strcmp(message, "Orange") == 0)\r
+ {\r
+ current_color = ORANGE;\r
+ }\r
+ else\r
+ {\r
+ Serial.println("Bad color not defined!");\r
+ current_color = OFF;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ Serial.println("default case");\r
+ }\r
+}\r
+\r
+void loop() {\r
+ if (disabled)\r
+ {\r
+ Serial.println("DISABLED!");\r
+ staticEffect(OFF);\r
+ mqttClient.poll();\r
+ delay(100);\r
+ }\r
+ else if (strcmp(current_anim, "Wave") == 0)\r
+ {\r
+ colorWipe(300 / (current_anim_speed + 1));\r
+ }\r
+ else if (strcmp(current_anim, "Strobe") == 0)\r
+ {\r
+ strobeEffect(1000 / (current_anim_speed + 1));\r
+ }\r
+ else if (strcmp(current_anim, "Static") == 0)\r
+ {\r
+ staticEffect(current_color);\r
+ mqttClient.poll();\r
+ delay(100);\r
+\r
+ }\r
+ else if (strcmp(current_anim, "Breath") == 0)\r
+ {\r
+ breathingEffect(100 / (current_anim_speed + 1));\r
+ }\r
+ else\r
+ {\r
+ Serial.println("Unknown animation");\r
+ }\r
+}\r
+ \r
+\r
+ \r
+// Wipe a color across the LED\r
+void colorWipe(int wait) {\r
+ strip.setBrightness((int) current_max_brightness * 255 / 100);\r
+ for (int i = 0; i < NUM_LEDS; i++) {\r
+ strip.setPixelColor(i, current_color);\r
+ strip.show();\r
+ delay(wait);\r
+ mqttClient.poll();\r
+ if (disabled) break;\r
+ }\r
+ for (int i = 0; i < NUM_LEDS; i++) {\r
+ strip.setPixelColor(i, OFF);\r
+ strip.show();\r
+ delay(wait);\r
+ mqttClient.poll();\r
+ if (disabled) break;\r
+ }\r
+}\r
+\r
+void staticEffect(uint32_t color)\r
+{\r
+ // Set brightness (assuming current_max_brightness is 0.0 – 1.0)\r
+ strip.setBrightness((int)(current_max_brightness * 255 / 100));\r
+\r
+ // Set all LEDs to current_color\r
+ for (int i = 0; i < NUM_LEDS; i++)\r
+ {\r
+ strip.setPixelColor(i, color);\r
+ }\r
+\r
+ strip.show();\r
+}\r
+ \r
+// Smooth breathing effect\r
+void breathingEffect(int breathSpeed) {\r
+ for (int brightness = 0; brightness <= (int) current_max_brightness * 255 / 100; brightness++) {\r
+ for (int i = 0; i < NUM_LEDS; i++)\r
+ {\r
+ strip.setPixelColor(i, current_color);\r
+ }\r
+ strip.setBrightness(brightness);\r
+ strip.show();\r
+ delay(breathSpeed);\r
+ mqttClient.poll();\r
+ if (disabled) break;\r
+ }\r
+ for (int brightness = (int) current_max_brightness * 255 / 100; brightness >= 0; brightness--) {\r
+ for (int i = 0; i < NUM_LEDS; i++)\r
+ {\r
+ strip.setPixelColor(i, current_color);\r
+ }\r
+ strip.setBrightness(brightness);\r
+ strip.show();\r
+ delay(breathSpeed);\r
+ mqttClient.poll();\r
+ if (disabled) break;\r
+ }\r
+}\r
+\r
+void strobeEffect(int wait)\r
+{\r
+ int brightness = (int)(current_max_brightness * 255 / 100);\r
+\r
+ strip.setBrightness(brightness);\r
+ for (int i = 0; i < NUM_LEDS; i++)\r
+ {\r
+ strip.setPixelColor(i, current_color);\r
+ }\r
+ strip.show();\r
+\r
+ delay(wait);\r
+ mqttClient.poll();\r
+ if (disabled) return;\r
+\r
+ // OFF\r
+ for (int i = 0; i < NUM_LEDS; i++)\r
+ {\r
+ strip.setPixelColor(i, OFF);\r
+ }\r
+ strip.show();\r
+\r
+ delay(wait);\r
+ mqttClient.poll();\r
+ if (disabled) return;\r
+}
\ No newline at end of file