/* ESP8266 MQTT Version 2017-08-15 * using decimal values (0..255) for mode,speed, brightness !! * less use of ws2812fx.stop(); * ws2812fx.start() only when a mode is recieved. this sketch subscibes 2 MQTT topics: topic: "huette/clubraum/000/ws2812tonne/actuators/frame" - receive a binary MQTT message with seperate RGB values for all pixels (1 frame / ein Bild ) and control Neopixel LEDs 3 bytes per pixel (r,g,b) topic: "huette/clubraum/000/ws2812tonne/actuators/set_pixel" - receive a command (ascii) possible commands: 0-n #RRGGBB (set one pixel, disable effects) 255 #RRGGBB (set all pixels, disable effects) mode 0-46 (WS2812FX mode, enable effects) speed 0-255 brightness 0-255 color #RRGGBB */ #include <ESP8266WiFi.h> #include <WiFiUdp.h> #include <ArduinoOTA.h> #include <PubSubClient.h> #include <Adafruit_NeoPixel.h> #include <WS2812FX.h> #include "conf.h" // I moved this to conf.h //const char* ssid = "XXXXXXX"; //const char* password = "XXXXXXX"; //const char* mqtt_server = "XXXX"; WiFiClient espClient; PubSubClient client(espClient); WS2812FX ws2812fx = WS2812FX(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800); Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800); int r,g,b; byte framebuffer[NUMPIXELS*3]; String stringPixel, stringFrame, stringIntopic ; bool fx_is_active; void printModes() { Serial.println(F("Supporting the following modes: ")); Serial.println(); for(int i=0; i < ws2812fx.getModeCount(); i++) { Serial.print(i); Serial.print(F("\t")); Serial.println(ws2812fx.getModeName(i)); } Serial.println(); } void setup() { //pinMode(BUILTIN_LED, OUTPUT); // Initialize the BUILTIN_LED pin as an output Serial.begin(115200); pixels.begin(); setup_wifi(); client.setServer(mqtt_server, 1883); client.subscribe("inTopic"); client.subscribe("inTopic2"); client.setCallback(callback); stringPixel = String(inTopic2); stringFrame = String(inTopic); ArduinoOTA.setHostname("saturnring"); // give an name to our module ArduinoOTA.begin(); // OTA initialization ws2812fx.init(); ws2812fx.setBrightness(30); ws2812fx.setSpeed(200); ws2812fx.setColor(0x220022); ws2812fx.setMode(9); ws2812fx.start(); fx_is_active = true; printModes(); } //setup void setup_wifi() { delay(10); // We start by connecting to a WiFi network // Serial.print("BUILTIN_LED Value: "); // Serial.println(BUILTIN_LED); Serial.print("Connecting to "); Serial.println(ssid); WiFi.softAPdisconnect(true); WiFi.mode(WIFI_STA); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); pixels.setPixelColor(0, pixels.Color(50,0,0)); pixels.show(); //Serial.println("trying SSID2.."); //pixels.setPixelColor(0, pixels.Color(50,50,0)); //WiFi.begin(ssid2, password2); } Serial.println(""); Serial.println("WiFi connected"); pixels.setPixelColor(0, pixels.Color(0,50,0)); pixels.show(); delay(500); Serial.println("IP address: "); Serial.println(WiFi.localIP()); client.subscribe(inTopic); client.setCallback(callback); } //setup_wifi void parse_mqtt_message( byte* payload, unsigned int length){ int splitat; // Einmal die ganze Payload durcharbeiten... String s = ""; for(int i = 0; i < length; i++) { // und Seriell ausgeben s += (char)payload[i]; // Serial.println((char)payload[i]); if (isWhitespace((char)payload[i])) { splitat = i; i = length; } } String Numberstring = ""; String Colorstring = ""; for(int i = 0; i < splitat; i++) { Numberstring += (char) payload[i]; } for (int i = (splitat + 1); i < length; i++) { Colorstring += (char) payload[i]; } //Colorstring contains something like = "#00ff00" or "00ff00" // you need to convert it to 0,255,0 and insert it to the two calls below // Am ende Newline. int intcolors=(int) strtol(&Colorstring[1],NULL,16); int r = intcolors >> 16; int g = intcolors >> 8 & 0xFF; int b = intcolors & 0xFF; Serial.print("Numberstring:" + Numberstring + " Colorstring:" + Colorstring + " intcolors:"); Serial.print(intcolors); Serial.print(" " ); Serial.print( Numberstring.toInt() ); Serial.print(" " ); Serial.println( Colorstring.toInt() ); if(Numberstring == "mode") { ws2812fx.setMode(Colorstring.toInt()); if(! fx_is_active){ ws2812fx.start(); fx_is_active = true; } } else if(Numberstring == "speed") { ws2812fx.setSpeed(Colorstring.toInt()); } else if(Numberstring == "brightness") { ws2812fx.setBrightness(Colorstring.toInt()); } else if(Numberstring == "color") { ws2812fx.setColor(intcolors); } else if(Numberstring.toInt() == 255) { //set all pixels to the same color if(fx_is_active){ ws2812fx.stop(); fx_is_active = false; } for(int i = 0; i < NUMPIXELS; i++) { pixels.setPixelColor(i, pixels.Color(r,g,b)); } pixels.show(); } // needs testing: // toInt returns 0 if it is not a number ! else if(Numberstring.toInt() >= 0 && Numberstring.toInt() < NUMPIXELS) { if( fx_is_active){ ws2812fx.stop(); fx_is_active = false; } pixels.setPixelColor(Numberstring.toInt(), pixels.Color(r,g,b)); pixels.show(); // This sends the updated pixel color to the hardware. } } //parse_mqtt_message void writeframe(byte* payload, unsigned int length){ //Serial.print("TOPIC=frame"); if(fx_is_active){ ws2812fx.stop(); fx_is_active = false; } //write bytes to framebuffer for (int i = 0; i < (length) ; i++) { // Serial.print((char)payload[i]); // Serial.print(" "); if (i < NUMPIXELS*3) { framebuffer[i] = payload[i]; } } //write frame to LEDs int j=0; for(int i = 0; i < NUMPIXELS*3 ; i=i+3) { //Serial.print(" "); //Serial.print(j); //Serial.print(":"); r = framebuffer[i]; g = framebuffer[i+1]; b = framebuffer[i+2]; //Serial.print(r); //Serial.print(g); //Serial.print(b); pixels.setPixelColor(j, pixels.Color(r,g,b)); j++; } //Serial.println(); pixels.show(); } //writeframe void callback(char* topic, byte* payload, unsigned int length) { //Serial.print("Message arrived ["); //Serial.print(topic); //Serial.print("] "); //Serial.print("length:"); //Serial.print( length ); stringIntopic = String(topic); if (stringIntopic == stringPixel ){ //Serial.print("TOPIC=setpixel"); parse_mqtt_message(payload,length); } if (stringIntopic == stringFrame ){ writeframe(payload,length); } } //callback void reconnect() { // Loop until we're reconnected while (!client.connected()) { Serial.print("Attempting MQTT connection..."); // Attempt to connect if (client.connect("")) { Serial.println("connected"); // Once connected, publish an announcement... client.publish(outTopic, "hello world"); // ... and resubscribe client.subscribe(inTopic); client.subscribe(inTopic2); } else { Serial.print("failed, rc="); Serial.print(client.state()); Serial.println(" try again in 5 seconds"); // Wait 5 seconds before retrying delay(5000); } } } //reconnect void loop() { if (!client.connected()) { reconnect(); } client.loop(); ArduinoOTA.handle(); delay(20); ws2812fx.service(); } //loop