Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #define FASTLED_ALLOW_INTERRUPTS 0
- #define FASTLED_INTERRUPT_RETRY_COUNT 0
- #define FASTLED_ESP8266_RAW_PIN_ORDER
- #include <ESP8266WiFi.h>
- #include <ESP8266mDNS.h>
- #include <ESP8266HTTPUpdateServer.h>
- #include <WiFiUdp.h>
- #include <ArduinoOTA.h>
- #include <PubSubClient.h>
- #include <ArduinoJson.h>
- #include <FastLED.h>
- // In theory you can define a max packet size for MQTT here, but it doesn't work
- // You have to find the MQTT source (/home/dan/Arduino) and change it
- // there in the .h file. Then it seems to work
- //// Actually you can set it as client.setBufferSize(8192); // see below in setup
- //#undef MQTT_MAX_PACKET_SIZE
- //#define MQTT_MAX_PACKET_SIZE 16384
- #ifndef STASSID
- #define STASSID "wifi"
- #define STAPSK "pass"
- #endif
- const char* host = "browner";
- const char* ssid = STASSID;
- const char* password = STAPSK;
- ESP8266WebServer httpServer(80);
- ESP8266HTTPUpdateServer httpUpdater;
- //
- // LED PIN Setup
- //
- #define LED_PIN 13
- #define NUM_LEDS 292
- #define LED_TYPE WS2812B
- #define COLOR_ORDER GRB
- #define BRIGHTNESS 255
- #define SATURATION 255
- CRGB leds[NUM_LEDS];
- //
- // MQTT Setup
- //
- const char* mqttServer = "10.11.151.10";
- WiFiClient espClient; // defines the wifi clieent
- PubSubClient client(espClient); // constructor with partially initializsed client instance (see docs for pubsubclient)
- long lastReconnectAttempt = 0;
- #define MQTT_CONNECTED_LED 2
- //
- // Individual Selected LEDs Array
- //
- #define LED_SELECT_ELEMENTS 5
- #define OFF_LEAD 0
- int selectedLeds[NUM_LEDS][LED_SELECT_ELEMENTS]; // led_select_elements is 5 now, for/// LED# / Brightness / R / G / B
- int staticSchema = 0; // 0 = static, lights on/off, 1 = dynamic, flowing/moving/rainbow lights
- int dynamicScene = 0; // integers running through all the dynamic scenes you set. Will be updated by MQTT and then assign an effect
- //
- // JSON memory allocation
- //
- StaticJsonDocument<16384> ledArrayDoc; // For receiving light data;
- /*
- * Start writing functions below
- *
- */
- //
- // LED Settings (and GRADIENT PALETTES)
- //
- // Gradient palettes are setup using palette knife from the FastLED pages.
- // http://fastled.io/tools/paletteknife/
- CRGBPalette16 currentPalette;
- TBlendType currentBlending;
- // http://soliton.vm.bytemark.co.uk/pub/cpt-city/rc/tn/purplefly.png.index.html
- DEFINE_GRADIENT_PALETTE( purplefly_gp ) {
- 0, 0, 0, 0,
- 63, 239, 0,122,
- 191, 252,255, 78,
- 255, 0, 0, 0};
- // http://soliton.vm.bytemark.co.uk/pub/cpt-city/rc/tn/autumnrose.png.index.html
- DEFINE_GRADIENT_PALETTE( autumnrose_gp ) {
- 0, 71, 3, 1,
- 45, 128, 5, 2,
- 84, 186, 11, 3,
- 127, 215, 27, 8,
- 153, 224, 69, 13,
- 188, 229, 84, 6,
- 226, 242,135, 17,
- 255, 247,161, 79};
- // http://soliton.vm.bytemark.co.uk/pub/cpt-city/nd/atmospheric/tn/Sunset_Real.png.index.html
- DEFINE_GRADIENT_PALETTE( Sunset_Real_gp ) {
- 0, 120, 0, 0,
- 22, 179, 22, 0,
- 51, 255,104, 0,
- 85, 167, 22, 18,
- 135, 100, 0,103,
- 198, 16, 0,130,
- 255, 0, 0,160};
- // http://soliton.vm.bytemark.co.uk/pub/cpt-city/bhw/bhw1/tn/bhw1_19.png.index.html
- DEFINE_GRADIENT_PALETTE( bhw1_19_gp ) {
- 0, 82, 1, 3,
- 79, 20, 1, 1,
- 181, 139, 1, 0,
- 252, 20, 1, 1,
- 255, 20, 1, 1};
- // http://soliton.vm.bytemark.co.uk/pub/cpt-city/ibcso/tn/ibcso-bath.png.index.html
- DEFINE_GRADIENT_PALETTE( ibcso_bath_gp ) {
- 0, 1, 4, 13,
- 106, 1, 4, 13,
- 106, 1, 10, 28,
- 127, 1, 10, 28,
- 127, 2, 19, 50,
- 148, 2, 19, 50,
- 148, 4, 31, 79,
- 170, 4, 31, 79,
- 170, 5, 47,119,
- 191, 5, 47,119,
- 191, 9, 80,158,
- 212, 9, 80,158,
- 212, 17,125,203,
- 233, 17,125,203,
- 233, 19,146,223,
- 244, 19,146,223,
- 244, 31,152,214,
- 249, 31,152,214,
- 249, 54,166,216,
- 255, 54,166,216};
- // http://soliton.vm.bytemark.co.uk/pub/cpt-city/saga/tn/saga-21.png.index.html
- DEFINE_GRADIENT_PALETTE( saga_21_gp ) {
- 0, 22, 81, 0,
- 13, 10,115, 0,
- 26, 3,154, 0,
- 40, 1,201, 0,
- 53, 0,255, 0,
- 67, 0,156, 4,
- 80, 0, 82, 25,
- 93, 0, 33, 71,
- 107, 0, 7,145,
- 120, 0, 0,255,
- 134, 3, 0,145,
- 147, 23, 0, 71,
- 161, 67, 0, 25,
- 174, 142, 0, 4,
- 187, 255, 0, 0,
- 201, 192, 1, 0,
- 214, 140, 7, 0,
- 228, 100, 17, 0,
- 241, 66, 33, 0,
- 255, 41, 55, 0};
- //
- // Clear SelectedLedsArray()
- //
- void clearSelectedLedsArray() {
- for (int i=0; i<NUM_LEDS; i++) {
- // First you must put in the number of the led into the array
- selectedLeds[i][0] = i;
- // Now for all three colors make them zero
- for (int j=1; j<LED_SELECT_ELEMENTS; j++) {
- selectedLeds[i][j] = 0;
- }
- }
- }
- //
- // printSelectedLedArray
- //
- void printSelectedLedArray() {
- for(int i = 0; i<NUM_LEDS; i++) {
- Serial.print("Printing Selected Led Array: {{");
- for(int j = 0; j<LED_SELECT_ELEMENTS; j++) {
- Serial.print(selectedLeds[i][j]);
- Serial.print(",");
- }
- Serial.println("}}");
- }
- } // end print selected led array
- //
- // reconnectMQTT_NonBlock()
- //
- boolean reconnectMQTT_NonBlock() {
- if (client.connect("BookshelfLights")) {
- client.publish("connected", "Hello World, We have connected from the bookshelf lights successfully");
- client.subscribe("bookshelflights/#");
- }
- return client.connected();
- }
- //
- // mqttCallback()
- // callback function to handle incoming mqtt messages
- //
- // This is also where you assign topics on mqtt to be processed to respective functions
- //
- void mqttCallback(char* topic, byte* payload, unsigned int length) {
- //Serial.print("Payload arrived on topic: ");
- //Serial.println(topic);
- //Serial.print("Payload size is: ");
- //Serial.println(sizeof(payload));
- //Serial.print(". Payload msg is: ");
- /*
- for (int i=0; i<length; i++) {
- Serial.print((char)payload[i]);
- }
- Serial.println();
- */
- // Parse topics from the MQTT to be parsed accordingly
- //
- // turn LEDs ON individually based on received json data
- //
- if (strcmp(topic, "bookshelflights/selectedLedsOn") == 0) {
- //Serial.println("Here New");
- staticSchema = 1; // set scheme to be static instead of dynamic moving lights
- processMqttIndividualLedsOnRequest(payload);
- }
- //
- // turn LEDs OFF
- //
- if (strcmp(topic, "bookshelflights/ledsOff") == 0) {
- //processMqttLedsOff();
- staticSchema = 1; // set scheme to be static instead of dynamic moving lights
- clearSelectedLedsArray();
- }
- //
- // set a dynamic/moving scene
- //
- if (strcmp(topic, "bookshelflights/dynamicScene") == 0) {
- staticSchema = 0;
- clearSelectedLedsArray();
- // Convert payload to int
- payload[length] = '\0';
- int sceneVal = atoi((char *)payload);
- dynamicScene = sceneVal;
- //Serial.print("Here is the dynamicScene, set to ");
- //Serial.println(dynamicScene);
- }
- } // end mqttCallback
- //
- // updateIndividualLed
- //
- void updateIndividualLed(int ledNumber, int ledBrightness, int red, int green, int blue) {
- Serial.println(ledNumber);
- for (int i = 0; i<NUM_LEDS; i++) {
- if (selectedLeds[i][0] == ledNumber) {
- selectedLeds[i][1] = ledBrightness;
- selectedLeds[i][2] = red;
- selectedLeds[i][3] = green;
- selectedLeds[i][4] = blue;
- }
- }
- }
- //
- // processMqttIndividualLedsOnRequest(byte* payload)
- //
- void processMqttIndividualLedsOnRequest(byte* payload) {
- // Using ArduinoJson we put it into the memory
- DeserializationError error = deserializeJson(ledArrayDoc, payload);
- if (error) {
- Serial.print(F("deserializeJson() failed: "));
- Serial.println(error.c_str());
- return;
- }
- // Clear old ones
- //clearSelectedLedsArray();
- // Now make json array into loacl array
- JsonArray arr = ledArrayDoc.as<JsonArray>();
- // Loop through the d ata and update master led array
- for (JsonObject repo : arr) {
- int ledNumber = repo["ledNumber"];
- int ledBright = repo["data"]["bright"];
- int ledR = repo["data"]["R"];
- int ledG = repo["data"]["G"];
- int ledB = repo["data"]["B"];
- // Now update the array
- updateIndividualLed(ledNumber, ledBright, ledR, ledG, ledB);
- }
- }
- //
- // processMqttLedsOff()
- //
- void processMqttLedsOff() {
- clearSelectedLedsArray();
- }
- /*
- * fillLEDsFromPalete()
- * Fill the array of leds -- using an increasing colorIndex -- based on the current color paelette
- */
- void fillLEDsFromPalette( int ledStartIndex, int ledStopIndex, uint8_t colorIndex = 1, uint8_t brightness = 255 ) {
- for (int i = ledStartIndex; i < ledStopIndex; i++) {
- leds[i] = ColorFromPalette( currentPalette, colorIndex, brightness, currentBlending );
- // Advance index by 3, for R G B
- colorIndex += 3;
- }
- }
- /*
- * setup() loop
- *
- */
- void setup() {
- WiFi.setSleepMode(WIFI_NONE_SLEEP);
- Serial.begin(115200);
- Serial.println("Booting");
- WiFi.mode(WIFI_STA);
- WiFi.begin(ssid, password);
- while (WiFi.waitForConnectResult() != WL_CONNECTED) {
- Serial.println("Connection Failed! Rebooting...");
- delay(5000);
- ESP.restart();
- }
- // Port defaults to 8266
- // ArduinoOTA.setPort(8266);
- // Hostname defaults to esp8266-[ChipID]
- // ArduinoOTA.setHostname("myesp8266");
- // No authentication by default
- // ArduinoOTA.setPassword("admin");
- // Password can be set with it's md5 value as well
- // MD5(admin) = 21232f297a57a5a743894a0e4a801fc3
- // ArduinoOTA.setPasswordHash("21232f297a57a5a743894a0e4a801fc3");
- ArduinoOTA.onStart([]() {
- String type;
- if (ArduinoOTA.getCommand() == U_FLASH) {
- type = "sketch";
- } else { // U_FS
- type = "filesystem";
- }
- // NOTE: if updating FS this would be the place to unmount FS using FS.end()
- Serial.println("Start updating " + type);
- });
- ArduinoOTA.onEnd([]() {
- Serial.println("\nEnd");
- });
- ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
- Serial.printf("Progress: %u%%\r", (progress / (total / 100)));
- });
- ArduinoOTA.onError([](ota_error_t error) {
- Serial.printf("Error[%u]: ", error);
- if (error == OTA_AUTH_ERROR) {
- Serial.println("Auth Failed");
- } else if (error == OTA_BEGIN_ERROR) {
- Serial.println("Begin Failed");
- } else if (error == OTA_CONNECT_ERROR) {
- Serial.println("Connect Failed");
- } else if (error == OTA_RECEIVE_ERROR) {
- Serial.println("Receive Failed");
- } else if (error == OTA_END_ERROR) {
- Serial.println("End Failed");
- }
- });
- ArduinoOTA.begin();
- Serial.println("Ready");
- Serial.print("IP address: ");
- Serial.println(WiFi.localIP());
- //************** HTTP UPDATE ******************
- Serial.println();
- Serial.println("Booting Sketch...");
- WiFi.mode(WIFI_STA);
- WiFi.softAPdisconnect(true);
- //WiFi.begin(ssid, password); // If you uncomment this it will also be in AP mode, from security perspective, you don't want that!
- while(WiFi.waitForConnectResult() != WL_CONNECTED){
- WiFi.begin(ssid, password);
- Serial.println("WiFi failed, retrying.");
- }
- MDNS.begin(host);
- httpUpdater.setup(&httpServer);
- httpServer.begin();
- MDNS.addService("http", "tcp", 80);
- Serial.printf("HTTPUpdateServer ready! Open http://%s.local/update in your browser\n", host);
- Serial.println("");
- Serial.print ( "IP address: " );
- Serial.println ( WiFi.localIP() );
- //************** END HTTP UPDATE **************
- client.setServer(mqttServer, 1883);
- client.setCallback(mqttCallback);
- client.setBufferSize(9192); // It seems I just can't get more than 8192 at a time on the wemos d1 mini
- pinMode(MQTT_CONNECTED_LED, OUTPUT);
- // Must setup the initial array
- clearSelectedLedsArray();
- currentBlending = LINEARBLEND;
- FastLED.addLeds<LED_TYPE, LED_PIN, COLOR_ORDER>(leds, NUM_LEDS);
- FastLED.setBrightness( BRIGHTNESS );
- } // end setup loop
- void loop() {
- //
- // Begin by setting up wifi and http server for over the air updates
- // go to 10.11.151.81/update
- //
- httpServer.handleClient();
- ArduinoOTA.handle();
- //
- // Now process MQTT being connected
- //
- if (!client.connected()) {
- digitalWrite(MQTT_CONNECTED_LED,HIGH);
- long now = millis();
- if (now - lastReconnectAttempt > 3000) {
- lastReconnectAttempt = now;
- if (reconnectMQTT_NonBlock()) {
- lastReconnectAttempt = 0;
- }
- }
- } else {
- client.loop();
- digitalWrite(MQTT_CONNECTED_LED, LOW);
- }
- static uint8_t colorIndex = 0;
- colorIndex = colorIndex + 1;
- int speed = 10;
- //
- // Move on to processing lights
- //
- // Process if it's static or still lights
- if (staticSchema == 1) {
- for(int i = 0; i <NUM_LEDS; i++) {
- leds[selectedLeds[i][0]].r = selectedLeds[i][2];
- leds[selectedLeds[i][0]].g = selectedLeds[i][3];
- leds[selectedLeds[i][0]].b = selectedLeds[i][4];
- //leds[selectedLeds[i][0]].fadeLightBy(255 - selectedLeds[i][1]);
- }
- speed = 100;
- }
- // Process if it's for 'moving' lights
- if (staticSchema == 0) {
- if (dynamicScene == 0) {
- currentPalette = bhw1_19_gp;
- fillLEDsFromPalette( 0, NUM_LEDS, colorIndex );
- speed = 5;
- }
- if (dynamicScene == 1) {
- currentPalette = autumnrose_gp;
- fillLEDsFromPalette( 0, NUM_LEDS, colorIndex );
- speed = 100;
- }
- if (dynamicScene == 2) {
- currentPalette = Sunset_Real_gp;
- fillLEDsFromPalette( 0, NUM_LEDS, colorIndex );
- speed = 100;
- }
- if (dynamicScene == 3) {
- currentPalette = ibcso_bath_gp;
- fillLEDsFromPalette( 0, NUM_LEDS, colorIndex );
- speed = 10;
- }
- if (dynamicScene == 4) {
- currentPalette = saga_21_gp;
- fillLEDsFromPalette( 0, NUM_LEDS, colorIndex );
- speed = 10;
- }
- }
- //char str[8];
- //itoa( dynamicScene, str, 10 );
- //client.publish("temp/hi", str);
- FastLED.show();
- FastLED.delay(speed);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement