From f0ecb4d38fff522c72905a8551355ca925381fa3 Mon Sep 17 00:00:00 2001 From: manuel Date: Tue, 17 Mar 2020 12:00:59 +0100 Subject: platform io cleanup --- oliver/dr_desk/lib/readme.txt | 36 ---- oliver/dr_desk/src/dr_desk.cpp | 316 ---------------------------- oliver/dr_desk/src/main.cpp | 315 ++++++++++++++++++++++++++++ oliver/lr_stripes/lib/readme.txt | 36 ---- oliver/lr_stripes/src/lr_stripes.cpp | 394 ----------------------------------- oliver/lr_stripes/src/main.cpp | 393 ++++++++++++++++++++++++++++++++++ 6 files changed, 708 insertions(+), 782 deletions(-) delete mode 100644 oliver/dr_desk/lib/readme.txt delete mode 100644 oliver/dr_desk/src/dr_desk.cpp create mode 100644 oliver/dr_desk/src/main.cpp delete mode 100644 oliver/lr_stripes/lib/readme.txt delete mode 100644 oliver/lr_stripes/src/lr_stripes.cpp create mode 100644 oliver/lr_stripes/src/main.cpp (limited to 'oliver') diff --git a/oliver/dr_desk/lib/readme.txt b/oliver/dr_desk/lib/readme.txt deleted file mode 100644 index dbadc3d..0000000 --- a/oliver/dr_desk/lib/readme.txt +++ /dev/null @@ -1,36 +0,0 @@ - -This directory is intended for the project specific (private) libraries. -PlatformIO will compile them to static libraries and link to executable file. - -The source code of each library should be placed in separate directory, like -"lib/private_lib/[here are source files]". - -For example, see how can be organized `Foo` and `Bar` libraries: - -|--lib -| |--Bar -| | |--docs -| | |--examples -| | |--src -| | |- Bar.c -| | |- Bar.h -| |--Foo -| | |- Foo.c -| | |- Foo.h -| |- readme.txt --> THIS FILE -|- platformio.ini -|--src - |- main.c - -Then in `src/main.c` you should use: - -#include -#include - -// rest H/C/CPP code - -PlatformIO will find your libraries automatically, configure preprocessor's -include paths and build them. - -More information about PlatformIO Library Dependency Finder -- http://docs.platformio.org/page/librarymanager/ldf.html diff --git a/oliver/dr_desk/src/dr_desk.cpp b/oliver/dr_desk/src/dr_desk.cpp deleted file mode 100644 index 6f31b76..0000000 --- a/oliver/dr_desk/src/dr_desk.cpp +++ /dev/null @@ -1,316 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include "secrets.h" - -#define _STR(s) #s -#define STR(s) _STR(s) - -const char* mqtt_server = "192.168.1.2"; //MQTT Server IP, your home MQTT server eg Mosquitto on RPi, or some public MQTT -const int mqtt_port = 1883; //MQTT Server PORT, default is 1883 but can be anything. - -const char* mqtt_pingall_sub = "home/pingall"; -const char* mqtt_pingall_pub = "home/pingall/response"; - -#define MQTT_BASE "home/diningroom/desk" -const char* mqtt_device_boot = MQTT_BASE "/device"; - -const char* mqtt_mode_sub = MQTT_BASE; -const char* mqtt_mode_pub = MQTT_BASE "/status"; - -const char* mqtt_color_sub = MQTT_BASE "/color"; -const char* mqtt_color_pub = MQTT_BASE "/color/status"; - -const char* mqtt_brightness_sub = MQTT_BASE "/brightness"; -const char* mqtt_brightness_pub = MQTT_BASE "/brightness/status"; - -#define RGB_PIN 2 -#define RGB_NUM_LEDS 12 -#define RGB_CHIPSET WS2812B -#define RGB_COLOR_ORDER GRB -#define NUM(a) (sizeof(a) / sizeof(*a)) - -#define FIRMWARE_VERSION 1 -//#define FIRMWARE_URL "" - -WiFiClient espClient; -PubSubClient client(espClient); -char convBuffer[10]; -CRGB leds[RGB_NUM_LEDS]; - -void callback(char *topic, uint8_t *payload, unsigned int length); -void blink(); -void checkFirmwareUpdate(); - -void switchMode(struct mode *mode); -void modeOff(); -void modeSolid(); -void modeRainbow(); -void modeRainbowFast(); -void modeStrobo(); - -struct mode { - const char *name; - void (*func)(); -}; - -struct mode modes[] = { - { "off", modeOff }, - { "solid", modeSolid }, - { "rainbow", modeRainbow }, - { "rainbowfast", modeRainbowFast }, - { "strobo", modeStrobo }, -}; - -struct -{ - struct mode *mode = &modes[0]; - uint32_t color = CRGB::Red; - uint8_t brightness = 204; // 80% -} set; - -struct -{ - uint8_t brightness; - bool idle = false; -} current; - -void setup() -{ - Serial.begin(115200); - pinMode(LED_BUILTIN, OUTPUT); - - FastLED.addLeds(leds, RGB_NUM_LEDS); - current.brightness = set.brightness; - // update leds - set.mode->func(); - FastLED.show(); - - WiFiManager wifiManager; - wifiManager.setConfigPortalTimeout(600); - Serial.printf_P(PSTR("Setting up WiFi\n")); - if (!wifiManager.autoConnect("ESP8266_DR_DESK")) { - Serial.printf_P(PSTR("Failed to connect and hit timeout\n")); - delay(5000); - ESP.restart(); - } - - yield(); - checkFirmwareUpdate(); - yield(); - - client.setServer(mqtt_server, mqtt_port); - client.setCallback(callback); - - digitalWrite(LED_BUILTIN, HIGH); //Turn off led as default -} - -void reconnect() -{ - // Loop until we're reconnected - while (!client.connected()) - { - // Create a random client ID - String clientId = "ESP8266Client-"; - clientId += String(random(0xffff), HEX); - - // Attempt to connect - if (client.connect(clientId.c_str())) - { - // Once connected, publish an announcement... - client.publish(mqtt_device_boot, "connected"); - // ... and resubscribe - client.subscribe(mqtt_pingall_sub); - - // publish states - Serial.println(mqtt_mode_sub); - client.subscribe(mqtt_mode_sub); - client.publish(mqtt_mode_pub, set.mode->name, true); - - Serial.println(mqtt_color_sub); - client.subscribe(mqtt_color_sub); - itoa(set.color, convBuffer, 10); - client.publish(mqtt_color_pub, convBuffer, true); - - Serial.println(mqtt_brightness_sub); - client.subscribe(mqtt_brightness_sub); - itoa(map(set.brightness, 0, 255, 0, 100), convBuffer, 10); - client.publish(mqtt_brightness_pub, convBuffer, true); - } - else - { - // Wait 5 seconds before retrying - delay(5000); - } - } -} - -void callback(char *topic, uint8_t *payload, unsigned int length) -{ - uint8_t c_payload[length]; - memcpy(c_payload, payload, length); - c_payload[length] = '\0'; - - if (strcmp(topic, mqtt_pingall_sub) == 0) - { - blink(); - client.publish(mqtt_pingall_pub, - "{\"diningroom_desk\":\"connected\"}"); - } - else if (strcmp(topic, mqtt_mode_sub) == 0) - { - for (uint8_t i = 0; i < NUM(modes); ++i) - { - if (strcmp(modes[i].name, (char *)c_payload) != 0) - continue; - switchMode(&modes[i]); - break; - } - } - else if (strcmp(topic, mqtt_color_sub) == 0) - { - // switch from OFF to SOLID - if (set.mode == &modes[0]) - switchMode(&modes[1]); - - set.color = atoi((char *)c_payload); - current.idle = false; - itoa(set.color, convBuffer, 10); - client.publish(mqtt_color_pub, convBuffer, true); - } - else if (strcmp(topic, mqtt_brightness_sub) == 0) - { - set.brightness = map(atoi((char *)c_payload), 0, 100, 0, 255); - current.idle = false; - itoa(map(set.brightness, 0, 255, 0, 100), convBuffer, 10); - client.publish(mqtt_brightness_pub, convBuffer, true); - } -} - -void blink() -{ - //Blink on received MQTT message - digitalWrite(LED_BUILTIN, LOW); - delay(25); - digitalWrite(LED_BUILTIN, HIGH); -} - -void calcBrightness() -{ - #define FADE_STEP 10 - if (current.brightness == set.brightness) - return; - int fadeAmount = set.brightness - current.brightness; - if (abs(fadeAmount) > FADE_STEP) - fadeAmount = (fadeAmount > 0) ? FADE_STEP : -FADE_STEP; - current.brightness += fadeAmount; -} - -void switchMode(struct mode *mode) -{ - if (set.mode == mode) - return; - Serial.print("Switching mode to "); - Serial.println(mode->name); - set.mode = mode; - current.idle = false; - client.publish(mqtt_mode_pub, set.mode->name, true); -} - -void modeOff() -{ - fill_solid(leds, RGB_NUM_LEDS, CRGB::Black); - current.idle = true; -} - -void modeSolid() -{ - fill_solid(leds, RGB_NUM_LEDS, set.color); - calcBrightness(); - nscale8_video(leds, RGB_NUM_LEDS, current.brightness); - current.idle = (current.brightness == set.brightness); -} - -void modeRainbow() -{ - static CRGBPalette16 palette = RainbowColors_p; - static uint8_t hue = 0; - calcBrightness(); - for (int i = 0; i < RGB_NUM_LEDS; ++i) - leds[i] = ColorFromPalette(palette, hue, current.brightness); - hue++; -} - -void modeRainbowFast() -{ - static CRGBPalette16 palette = RainbowColors_p; - static uint8_t hue = 0; - calcBrightness(); - for (int i = 0; i < RGB_NUM_LEDS; ++i) - leds[i] = ColorFromPalette(palette, hue, current.brightness); - hue+=5; -} - -void modeStrobo() -{ - static bool state = 0; - if (set.color == CRGB::Black) - return; - fill_solid(leds, RGB_NUM_LEDS, (state) ? set.color : CRGB::Black); - calcBrightness(); - nscale8_video(leds, RGB_NUM_LEDS, current.brightness); - state = !state; -} - -void checkFirmwareUpdate() -{ - BearSSL::WiFiClientSecure update_client; - update_client.setInsecure(); - - client.publish(mqtt_device_boot, "fwupdate running"); - ESPhttpUpdate.setLedPin(LED_BUILTIN, HIGH); - ESPhttpUpdate.rebootOnUpdate(true); - t_httpUpdate_return ret = ESPhttpUpdate.update(update_client, FIRMWARE_URL, STR(FIRMWARE_VERSION)); - switch(ret) - { - case HTTP_UPDATE_FAILED: - { - Serial.printf_P(PSTR("HTTP_UPDATE_FAILED Error (%d): %s\n"), - ESPhttpUpdate.getLastError(), ESPhttpUpdate.getLastErrorString().c_str()); - String tmp = String("fwupdate error: ") + ESPhttpUpdate.getLastErrorString(); - client.publish(mqtt_device_boot, tmp.c_str()); - } - break; - - case HTTP_UPDATE_NO_UPDATES: - Serial.printf_P(PSTR("HTTP_UPDATE_NO_UPDATES\n")); - client.publish(mqtt_device_boot, "fwupdate noupdates"); - break; - - case HTTP_UPDATE_OK: - Serial.printf_P(PSTR("HTTP_UPDATE_OK\n")); - client.publish(mqtt_device_boot, "fwupdate ok"); - break; - } -} - -void loop() -{ - if (!client.connected()) - reconnect(); - client.loop(); - - EVERY_N_MILLISECONDS(100) - { - if (!current.idle) - { - set.mode->func(); - FastLED.show(); - } - if (!current.idle && current.brightness == 0) - current.idle = true; - } -} diff --git a/oliver/dr_desk/src/main.cpp b/oliver/dr_desk/src/main.cpp new file mode 100644 index 0000000..706996b --- /dev/null +++ b/oliver/dr_desk/src/main.cpp @@ -0,0 +1,315 @@ +#include +#include +#include +#include +#include +#include + +#define _STR(s) #s +#define STR(s) _STR(s) + +const char* mqtt_server = "192.168.1.2"; //MQTT Server IP, your home MQTT server eg Mosquitto on RPi, or some public MQTT +const int mqtt_port = 1883; //MQTT Server PORT, default is 1883 but can be anything. + +const char* mqtt_pingall_sub = "home/pingall"; +const char* mqtt_pingall_pub = "home/pingall/response"; + +#define MQTT_BASE "home/diningroom/desk" +const char* mqtt_device_boot = MQTT_BASE "/device"; + +const char* mqtt_mode_sub = MQTT_BASE; +const char* mqtt_mode_pub = MQTT_BASE "/status"; + +const char* mqtt_color_sub = MQTT_BASE "/color"; +const char* mqtt_color_pub = MQTT_BASE "/color/status"; + +const char* mqtt_brightness_sub = MQTT_BASE "/brightness"; +const char* mqtt_brightness_pub = MQTT_BASE "/brightness/status"; + +#define RGB_PIN 2 +#define RGB_NUM_LEDS 12 +#define RGB_CHIPSET WS2812B +#define RGB_COLOR_ORDER GRB +#define NUM(a) (sizeof(a) / sizeof(*a)) + +#define FIRMWARE_VERSION 1 +//#define FIRMWARE_URL "" + +WiFiClient espClient; +PubSubClient client(espClient); +char convBuffer[10]; +CRGB leds[RGB_NUM_LEDS]; + +void callback(char *topic, uint8_t *payload, unsigned int length); +void blink(); +void checkFirmwareUpdate(); + +void switchMode(struct mode *mode); +void modeOff(); +void modeSolid(); +void modeRainbow(); +void modeRainbowFast(); +void modeStrobo(); + +struct mode { + const char *name; + void (*func)(); +}; + +struct mode modes[] = { + { "off", modeOff }, + { "solid", modeSolid }, + { "rainbow", modeRainbow }, + { "rainbowfast", modeRainbowFast }, + { "strobo", modeStrobo }, +}; + +struct +{ + struct mode *mode = &modes[0]; + uint32_t color = CRGB::Red; + uint8_t brightness = 204; // 80% +} set; + +struct +{ + uint8_t brightness; + bool idle = false; +} current; + +void setup() +{ + Serial.begin(115200); + pinMode(LED_BUILTIN, OUTPUT); + + FastLED.addLeds(leds, RGB_NUM_LEDS); + current.brightness = set.brightness; + // update leds + set.mode->func(); + FastLED.show(); + + WiFiManager wifiManager; + wifiManager.setConfigPortalTimeout(600); + Serial.printf_P(PSTR("Setting up WiFi\n")); + if (!wifiManager.autoConnect("ESP8266_DR_DESK")) { + Serial.printf_P(PSTR("Failed to connect and hit timeout\n")); + delay(5000); + ESP.restart(); + } + + yield(); + checkFirmwareUpdate(); + yield(); + + client.setServer(mqtt_server, mqtt_port); + client.setCallback(callback); + + digitalWrite(LED_BUILTIN, HIGH); //Turn off led as default +} + +void reconnect() +{ + // Loop until we're reconnected + while (!client.connected()) + { + // Create a random client ID + String clientId = "ESP8266Client-"; + clientId += String(random(0xffff), HEX); + + // Attempt to connect + if (client.connect(clientId.c_str())) + { + // Once connected, publish an announcement... + client.publish(mqtt_device_boot, "connected"); + // ... and resubscribe + client.subscribe(mqtt_pingall_sub); + + // publish states + Serial.println(mqtt_mode_sub); + client.subscribe(mqtt_mode_sub); + client.publish(mqtt_mode_pub, set.mode->name, true); + + Serial.println(mqtt_color_sub); + client.subscribe(mqtt_color_sub); + itoa(set.color, convBuffer, 10); + client.publish(mqtt_color_pub, convBuffer, true); + + Serial.println(mqtt_brightness_sub); + client.subscribe(mqtt_brightness_sub); + itoa(map(set.brightness, 0, 255, 0, 100), convBuffer, 10); + client.publish(mqtt_brightness_pub, convBuffer, true); + } + else + { + // Wait 5 seconds before retrying + delay(5000); + } + } +} + +void callback(char *topic, uint8_t *payload, unsigned int length) +{ + uint8_t c_payload[length]; + memcpy(c_payload, payload, length); + c_payload[length] = '\0'; + + if (strcmp(topic, mqtt_pingall_sub) == 0) + { + blink(); + client.publish(mqtt_pingall_pub, + "{\"diningroom_desk\":\"connected\"}"); + } + else if (strcmp(topic, mqtt_mode_sub) == 0) + { + for (uint8_t i = 0; i < NUM(modes); ++i) + { + if (strcmp(modes[i].name, (char *)c_payload) != 0) + continue; + switchMode(&modes[i]); + break; + } + } + else if (strcmp(topic, mqtt_color_sub) == 0) + { + // switch from OFF to SOLID + if (set.mode == &modes[0]) + switchMode(&modes[1]); + + set.color = atoi((char *)c_payload); + current.idle = false; + itoa(set.color, convBuffer, 10); + client.publish(mqtt_color_pub, convBuffer, true); + } + else if (strcmp(topic, mqtt_brightness_sub) == 0) + { + set.brightness = map(atoi((char *)c_payload), 0, 100, 0, 255); + current.idle = false; + itoa(map(set.brightness, 0, 255, 0, 100), convBuffer, 10); + client.publish(mqtt_brightness_pub, convBuffer, true); + } +} + +void blink() +{ + //Blink on received MQTT message + digitalWrite(LED_BUILTIN, LOW); + delay(25); + digitalWrite(LED_BUILTIN, HIGH); +} + +void calcBrightness() +{ + #define FADE_STEP 10 + if (current.brightness == set.brightness) + return; + int fadeAmount = set.brightness - current.brightness; + if (abs(fadeAmount) > FADE_STEP) + fadeAmount = (fadeAmount > 0) ? FADE_STEP : -FADE_STEP; + current.brightness += fadeAmount; +} + +void switchMode(struct mode *mode) +{ + if (set.mode == mode) + return; + Serial.print("Switching mode to "); + Serial.println(mode->name); + set.mode = mode; + current.idle = false; + client.publish(mqtt_mode_pub, set.mode->name, true); +} + +void modeOff() +{ + fill_solid(leds, RGB_NUM_LEDS, CRGB::Black); + current.idle = true; +} + +void modeSolid() +{ + fill_solid(leds, RGB_NUM_LEDS, set.color); + calcBrightness(); + nscale8_video(leds, RGB_NUM_LEDS, current.brightness); + current.idle = (current.brightness == set.brightness); +} + +void modeRainbow() +{ + static CRGBPalette16 palette = RainbowColors_p; + static uint8_t hue = 0; + calcBrightness(); + for (int i = 0; i < RGB_NUM_LEDS; ++i) + leds[i] = ColorFromPalette(palette, hue, current.brightness); + hue++; +} + +void modeRainbowFast() +{ + static CRGBPalette16 palette = RainbowColors_p; + static uint8_t hue = 0; + calcBrightness(); + for (int i = 0; i < RGB_NUM_LEDS; ++i) + leds[i] = ColorFromPalette(palette, hue, current.brightness); + hue+=5; +} + +void modeStrobo() +{ + static bool state = 0; + if (set.color == CRGB::Black) + return; + fill_solid(leds, RGB_NUM_LEDS, (state) ? set.color : CRGB::Black); + calcBrightness(); + nscale8_video(leds, RGB_NUM_LEDS, current.brightness); + state = !state; +} + +void checkFirmwareUpdate() +{ + BearSSL::WiFiClientSecure update_client; + update_client.setInsecure(); + + client.publish(mqtt_device_boot, "fwupdate running"); + ESPhttpUpdate.setLedPin(LED_BUILTIN, HIGH); + ESPhttpUpdate.rebootOnUpdate(true); + t_httpUpdate_return ret = ESPhttpUpdate.update(update_client, FIRMWARE_URL, STR(FIRMWARE_VERSION)); + switch(ret) + { + case HTTP_UPDATE_FAILED: + { + Serial.printf_P(PSTR("HTTP_UPDATE_FAILED Error (%d): %s\n"), + ESPhttpUpdate.getLastError(), ESPhttpUpdate.getLastErrorString().c_str()); + String tmp = String("fwupdate error: ") + ESPhttpUpdate.getLastErrorString(); + client.publish(mqtt_device_boot, tmp.c_str()); + } + break; + + case HTTP_UPDATE_NO_UPDATES: + Serial.printf_P(PSTR("HTTP_UPDATE_NO_UPDATES\n")); + client.publish(mqtt_device_boot, "fwupdate noupdates"); + break; + + case HTTP_UPDATE_OK: + Serial.printf_P(PSTR("HTTP_UPDATE_OK\n")); + client.publish(mqtt_device_boot, "fwupdate ok"); + break; + } +} + +void loop() +{ + if (!client.connected()) + reconnect(); + client.loop(); + + EVERY_N_MILLISECONDS(100) + { + if (!current.idle) + { + set.mode->func(); + FastLED.show(); + } + if (!current.idle && current.brightness == 0) + current.idle = true; + } +} diff --git a/oliver/lr_stripes/lib/readme.txt b/oliver/lr_stripes/lib/readme.txt deleted file mode 100644 index dbadc3d..0000000 --- a/oliver/lr_stripes/lib/readme.txt +++ /dev/null @@ -1,36 +0,0 @@ - -This directory is intended for the project specific (private) libraries. -PlatformIO will compile them to static libraries and link to executable file. - -The source code of each library should be placed in separate directory, like -"lib/private_lib/[here are source files]". - -For example, see how can be organized `Foo` and `Bar` libraries: - -|--lib -| |--Bar -| | |--docs -| | |--examples -| | |--src -| | |- Bar.c -| | |- Bar.h -| |--Foo -| | |- Foo.c -| | |- Foo.h -| |- readme.txt --> THIS FILE -|- platformio.ini -|--src - |- main.c - -Then in `src/main.c` you should use: - -#include -#include - -// rest H/C/CPP code - -PlatformIO will find your libraries automatically, configure preprocessor's -include paths and build them. - -More information about PlatformIO Library Dependency Finder -- http://docs.platformio.org/page/librarymanager/ldf.html diff --git a/oliver/lr_stripes/src/lr_stripes.cpp b/oliver/lr_stripes/src/lr_stripes.cpp deleted file mode 100644 index 6ad4282..0000000 --- a/oliver/lr_stripes/src/lr_stripes.cpp +++ /dev/null @@ -1,394 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include "secrets.h" - -#define _STR(s) #s -#define STR(s) _STR(s) - -const char* mqtt_server = "192.168.1.2"; //MQTT Server IP, your home MQTT server eg Mosquitto on RPi, or some public MQTT -const int mqtt_port = 1883; //MQTT Server PORT, default is 1883 but can be anything. - -const char* mqtt_pingall_sub = "home/pingall"; -const char* mqtt_pingall_pub = "home/pingall/response"; - -#define MQTT_BASE "home/livingroom/ledstripe" -const char* mqtt_device_boot = MQTT_BASE "/device"; - -enum sensor_type : uint8_t -{ - SENSOR_RELAY = (1u << 0), - SENSOR_DIMMER = (1u << 1), - SENSOR_BUTTON = (1u << 2), -}; - -struct sensor_t -{ - uint8_t type; - struct - { - uint8_t pin; // relay pin - const char *mqtt_sub; - const char *mqtt_pub; - } relay; - struct - { - uint8_t pin; // push button pin - Bounce bounce; - } button; - struct - { - uint8_t pin; // dimmer pin - uint8_t level; // current dim level (0 to 100) - const char *mqtt_sub; - const char *mqtt_pub; - } dimmer; -}; - -struct sensor_t sensors[] = { - { - .type = SENSOR_RELAY | SENSOR_BUTTON | SENSOR_DIMMER, - .relay = { - .pin = D5, - .mqtt_sub = MQTT_BASE, - .mqtt_pub = MQTT_BASE "/status" - }, - .button = { - .pin = D0, - .bounce = Bounce(), - }, - .dimmer = { - .pin = D8, - .level = 100, - .mqtt_sub = MQTT_BASE "/brightness", - .mqtt_pub = MQTT_BASE "/brightness/status" - }, - } -}; - -//#define SAVE_RESTORE - -#define NUM(a) (sizeof(a) / sizeof(*a)) - -#define RELAY_ON 1 // GPIO value to write to turn on attached relay -#define RELAY_OFF 0 // GPIO value to write to turn off attached relay - -#define DIMMER_FADE_DELAY 40 // Delay in ms for each percentage fade up/down (10ms = 1s full-range dim) - -WiFiClient espClient; -PubSubClient client(espClient); -char convBuffer[10]; - -void callback(char* topic, byte* payload, unsigned int length); -void blink(); -bool relayRead(struct sensor_t *sensor); -void relayWrite(struct sensor_t *sensor, bool state, bool send_update=false); -void flipRelay(struct sensor_t *sensor, bool send_update=false); -void checkButtons(void); -inline uint8_t pwmValue(uint8_t level); -void fadeDimmer(struct sensor_t *sensor, uint8_t level, bool send_update=false); -void checkFirmwareUpdate(); - -void setup() -{ - Serial.begin(115200); - pinMode(LED_BUILTIN, OUTPUT); - analogWriteRange(100); - - // set relay pins to output mode + restore to last known state - for (uint8_t i = 0; i < NUM(sensors); i++) - { - struct sensor_t *sensor = &sensors[i]; - if (sensor->type & SENSOR_RELAY) - { - pinMode(sensor->relay.pin, OUTPUT); -#ifdef SAVE_RESTORE -#error "not implemented" -#else - digitalWrite(sensor->relay.pin, RELAY_OFF); -#endif - } - - if (sensor->type & SENSOR_DIMMER) - { - pinMode(sensor->dimmer.pin, OUTPUT); -#ifdef SAVE_RESTORE -#error "not implemented" -#else - uint8_t level = sensor->dimmer.level; -#endif - if ((sensor->type & SENSOR_RELAY) && !relayRead(sensor)) - level = 0; - analogWrite(sensor->dimmer.pin, pwmValue(level)); - } - - if (sensor->type & SENSOR_BUTTON) - { - pinMode(sensor->button.pin, INPUT); - sensor->button.bounce.attach(sensor->button.pin); - } - } - - WiFiManager wifiManager; - wifiManager.setConfigPortalTimeout(600); - Serial.printf_P(PSTR("Setting up WiFi\n")); - if (!wifiManager.autoConnect("ESP8266_LR_STRIPES")) { - Serial.printf_P(PSTR("Failed to connect and hit timeout\n")); - delay(5000); - ESP.restart(); - } - - yield(); - checkFirmwareUpdate(); - yield(); - - client.setServer(mqtt_server, mqtt_port); - client.setCallback(callback); - - digitalWrite(LED_BUILTIN, HIGH); //Turn off led as default -} - -void reconnect() -{ - // Loop until we're reconnected - while (!client.connected()) - { - // Create a random client ID - String clientId = "ESP8266Client-"; - clientId += String(random(0xffff), HEX); - - // Attempt to connect - if (client.connect(clientId.c_str())) - { - // Once connected, publish an announcement... - client.publish(mqtt_device_boot, "connected"); - // ... and resubscribe - client.subscribe(mqtt_pingall_sub); - - // publish states - for (uint8_t i = 0; i < NUM(sensors); i++) - { - struct sensor_t *sensor = &sensors[i]; - if (sensor->type & SENSOR_RELAY) - { - Serial.println(sensor->relay.mqtt_sub); - client.subscribe(sensor->relay.mqtt_sub); - client.publish(sensor->relay.mqtt_pub, relayRead(sensor) ? "1" : "0", - true); - } - - if (sensor->type & SENSOR_DIMMER) - { - Serial.println(sensor->dimmer.mqtt_sub); - client.subscribe(sensor->dimmer.mqtt_sub); - itoa(sensor->dimmer.level, convBuffer, 10); - client.publish(sensor->dimmer.mqtt_pub, convBuffer, true); - } - } - } - else - { - // Wait 5 seconds before retrying - delay(5000); - } - } -} - -void callback(char* topic, byte* payload, unsigned int length) -{ - char c_payload[length]; - memcpy(c_payload, payload, length); - c_payload[length] = '\0'; - - if (strcmp(topic, mqtt_pingall_sub) == 0) - { - blink(); - client.publish(mqtt_pingall_pub, - "{\"livingroom_ledstrip\":\"connected\"}"); - return; - } - - for (uint8_t i = 0; i < NUM(sensors); i++) - { - struct sensor_t *sensor = &sensors[i]; - if (sensor->type & SENSOR_RELAY - && length > 0 - && strcmp(topic, sensor->relay.mqtt_sub) == 0) - { - blink(); - relayWrite(sensor, payload[0] == '1', true); - return; - } - - if (sensor->type & SENSOR_DIMMER - && length > 0 - && strcmp(topic, sensor->dimmer.mqtt_sub) == 0) - { - blink(); - uint8_t level = atoi((char *)payload); - fadeDimmer(sensor, (level > 100) ? 100 : level, true); - return; - } - } -} - -void blink() -{ - //Blink on received MQTT message - digitalWrite(LED_BUILTIN, LOW); - delay(25); - digitalWrite(LED_BUILTIN, HIGH); -} - -void loop() -{ - if (!client.connected()) - reconnect(); - client.loop(); - checkButtons(); -} - -bool relayRead(struct sensor_t *sensor) -{ - if (sensor->type & SENSOR_RELAY) - return digitalRead(sensor->relay.pin) == RELAY_ON; - return false; -} - -void relayWrite(struct sensor_t *sensor, bool state, bool send_update) -{ - if (!(sensor->type & SENSOR_RELAY)) - return; - - Serial.print(F("Incoming change for relay: ")); - Serial.print(sensor->relay.pin); - Serial.print(F(", New state: ")); - Serial.println(state); - - digitalWrite(sensor->relay.pin, state ? RELAY_ON : RELAY_OFF); - - if (sensor->type & SENSOR_DIMMER) - analogWrite(sensor->dimmer.pin, state ? pwmValue(sensor->dimmer.level) : 0); - -#ifdef SAVE_RESTORE -#error "not implemented" -#endif - - if (send_update) - client.publish(sensor->relay.mqtt_pub, state ? "1" : "0", true); -} - -void flipRelay(struct sensor_t *sensor, bool send_update) -{ - relayWrite(sensor, relayRead(sensor) ? RELAY_OFF : RELAY_ON, send_update); -} - -inline void checkButtons(void) -{ - for (uint8_t i = 0; i < NUM(sensors); i++) - { - struct sensor_t *sensor = &sensors[i]; - if (sensor->type & SENSOR_BUTTON) - { - sensor->button.bounce.update(); - if (sensor->button.bounce.fell()) - flipRelay(sensor, true); - } - } -} - -const uint8_t pwmtable[101] PROGMEM = { - // value below 0 turns of the power supply - 0, 10, 10, 11, 11, 11, 11, 12, 12, 12, - 13, 13, 13, 13, 14, 14, 14, 15, 15, 15, - 16, 16, 17, 17, 17, 18, 18, 19, 19, 19, - 20, 20, 21, 21, 22, 22, 23, 23, 24, 25, - 25, 26, 26, 27, 28, 28, 29, 30, 30, 31, - 32, 32, 33, 34, 35, 35, 36, 37, 38, 39, - 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, - 50, 51, 52, 54, 55, 56, 58, 59, 60, 62, - 63, 65, 66, 68, 69, 71, 72, 74, 76, 78, - 79, 81, 83, 85, 87, 89, 91, 93, 95, 98, - 100 -}; - -inline uint8_t pwmValue(uint8_t level) -{ - //uint8_t lvl = 100 - (uint8_t)pgm_read_byte(&pwmtable[level]); - //return (lvl < 10) 10 : lvl; - //level = (level > 0 && level < 10) ? 10 : level; - //return 100 - level; - return 100 - (uint8_t)pgm_read_byte(&pwmtable[level]); -} - -void fadeDimmer(struct sensor_t *sensor, uint8_t level, bool send_update) -{ - if (!(sensor->type & SENSOR_DIMMER)) - return; - if (level > 100) - level = 100; - - Serial.print(F("Incoming change for dimmer: ")); - Serial.print(sensor->dimmer.pin); - Serial.print(F(", New level: ")); - Serial.println(level); - - if (level > 0 && sensor->type & SENSOR_RELAY && !relayRead(sensor)) - relayWrite(sensor, RELAY_ON, send_update); - - int delta = ((int8_t)(level - sensor->dimmer.level) < 0) ? -1 : 1; - while (sensor->dimmer.level != level) - { - sensor->dimmer.level += delta; - analogWrite(sensor->dimmer.pin, pwmValue(sensor->dimmer.level)); - delay(DIMMER_FADE_DELAY); - } - - if (level == 0 && sensor->type & SENSOR_RELAY && relayRead(sensor)) - relayWrite(sensor, RELAY_OFF, send_update); - -#ifdef SAVE_RESTORE -#error "not implemented" -#endif - - if (send_update) - { - itoa(level, convBuffer, 10); - client.publish(sensor->dimmer.mqtt_pub, convBuffer, true); - } -} - -void checkFirmwareUpdate() -{ - BearSSL::WiFiClientSecure update_client; - update_client.setInsecure(); - - client.publish(mqtt_device_boot, "fwupdate running"); - ESPhttpUpdate.setLedPin(LED_BUILTIN, HIGH); - ESPhttpUpdate.rebootOnUpdate(true); - t_httpUpdate_return ret = ESPhttpUpdate.update(update_client, FIRMWARE_URL, STR(FIRMWARE_VERSION)); - switch(ret) - { - case HTTP_UPDATE_FAILED: - { - Serial.printf_P(PSTR("HTTP_UPDATE_FAILED Error (%d): %s\n"), - ESPhttpUpdate.getLastError(), ESPhttpUpdate.getLastErrorString().c_str()); - String tmp = String("fwupdate error: ") + ESPhttpUpdate.getLastErrorString(); - client.publish(mqtt_device_boot, tmp.c_str()); - } - break; - - case HTTP_UPDATE_NO_UPDATES: - Serial.printf_P(PSTR("HTTP_UPDATE_NO_UPDATES\n")); - client.publish(mqtt_device_boot, "fwupdate noupdates"); - break; - - case HTTP_UPDATE_OK: - Serial.printf_P(PSTR("HTTP_UPDATE_OK\n")); - client.publish(mqtt_device_boot, "fwupdate ok"); - break; - } -} diff --git a/oliver/lr_stripes/src/main.cpp b/oliver/lr_stripes/src/main.cpp new file mode 100644 index 0000000..b55a198 --- /dev/null +++ b/oliver/lr_stripes/src/main.cpp @@ -0,0 +1,393 @@ +#include +#include +#include +#include +#include +#include + +#define _STR(s) #s +#define STR(s) _STR(s) + +const char* mqtt_server = "192.168.1.2"; //MQTT Server IP, your home MQTT server eg Mosquitto on RPi, or some public MQTT +const int mqtt_port = 1883; //MQTT Server PORT, default is 1883 but can be anything. + +const char* mqtt_pingall_sub = "home/pingall"; +const char* mqtt_pingall_pub = "home/pingall/response"; + +#define MQTT_BASE "home/livingroom/ledstripe" +const char* mqtt_device_boot = MQTT_BASE "/device"; + +enum sensor_type : uint8_t +{ + SENSOR_RELAY = (1u << 0), + SENSOR_DIMMER = (1u << 1), + SENSOR_BUTTON = (1u << 2), +}; + +struct sensor_t +{ + uint8_t type; + struct + { + uint8_t pin; // relay pin + const char *mqtt_sub; + const char *mqtt_pub; + } relay; + struct + { + uint8_t pin; // push button pin + Bounce bounce; + } button; + struct + { + uint8_t pin; // dimmer pin + uint8_t level; // current dim level (0 to 100) + const char *mqtt_sub; + const char *mqtt_pub; + } dimmer; +}; + +struct sensor_t sensors[] = { + { + .type = SENSOR_RELAY | SENSOR_BUTTON | SENSOR_DIMMER, + .relay = { + .pin = D5, + .mqtt_sub = MQTT_BASE, + .mqtt_pub = MQTT_BASE "/status" + }, + .button = { + .pin = D0, + .bounce = Bounce(), + }, + .dimmer = { + .pin = D8, + .level = 100, + .mqtt_sub = MQTT_BASE "/brightness", + .mqtt_pub = MQTT_BASE "/brightness/status" + }, + } +}; + +//#define SAVE_RESTORE + +#define NUM(a) (sizeof(a) / sizeof(*a)) + +#define RELAY_ON 1 // GPIO value to write to turn on attached relay +#define RELAY_OFF 0 // GPIO value to write to turn off attached relay + +#define DIMMER_FADE_DELAY 40 // Delay in ms for each percentage fade up/down (10ms = 1s full-range dim) + +WiFiClient espClient; +PubSubClient client(espClient); +char convBuffer[10]; + +void callback(char* topic, byte* payload, unsigned int length); +void blink(); +bool relayRead(struct sensor_t *sensor); +void relayWrite(struct sensor_t *sensor, bool state, bool send_update=false); +void flipRelay(struct sensor_t *sensor, bool send_update=false); +void checkButtons(void); +inline uint8_t pwmValue(uint8_t level); +void fadeDimmer(struct sensor_t *sensor, uint8_t level, bool send_update=false); +void checkFirmwareUpdate(); + +void setup() +{ + Serial.begin(115200); + pinMode(LED_BUILTIN, OUTPUT); + analogWriteRange(100); + + // set relay pins to output mode + restore to last known state + for (uint8_t i = 0; i < NUM(sensors); i++) + { + struct sensor_t *sensor = &sensors[i]; + if (sensor->type & SENSOR_RELAY) + { + pinMode(sensor->relay.pin, OUTPUT); +#ifdef SAVE_RESTORE +#error "not implemented" +#else + digitalWrite(sensor->relay.pin, RELAY_OFF); +#endif + } + + if (sensor->type & SENSOR_DIMMER) + { + pinMode(sensor->dimmer.pin, OUTPUT); +#ifdef SAVE_RESTORE +#error "not implemented" +#else + uint8_t level = sensor->dimmer.level; +#endif + if ((sensor->type & SENSOR_RELAY) && !relayRead(sensor)) + level = 0; + analogWrite(sensor->dimmer.pin, pwmValue(level)); + } + + if (sensor->type & SENSOR_BUTTON) + { + pinMode(sensor->button.pin, INPUT); + sensor->button.bounce.attach(sensor->button.pin); + } + } + + WiFiManager wifiManager; + wifiManager.setConfigPortalTimeout(600); + Serial.printf_P(PSTR("Setting up WiFi\n")); + if (!wifiManager.autoConnect("ESP8266_LR_STRIPES")) { + Serial.printf_P(PSTR("Failed to connect and hit timeout\n")); + delay(5000); + ESP.restart(); + } + + yield(); + checkFirmwareUpdate(); + yield(); + + client.setServer(mqtt_server, mqtt_port); + client.setCallback(callback); + + digitalWrite(LED_BUILTIN, HIGH); //Turn off led as default +} + +void reconnect() +{ + // Loop until we're reconnected + while (!client.connected()) + { + // Create a random client ID + String clientId = "ESP8266Client-"; + clientId += String(random(0xffff), HEX); + + // Attempt to connect + if (client.connect(clientId.c_str())) + { + // Once connected, publish an announcement... + client.publish(mqtt_device_boot, "connected"); + // ... and resubscribe + client.subscribe(mqtt_pingall_sub); + + // publish states + for (uint8_t i = 0; i < NUM(sensors); i++) + { + struct sensor_t *sensor = &sensors[i]; + if (sensor->type & SENSOR_RELAY) + { + Serial.println(sensor->relay.mqtt_sub); + client.subscribe(sensor->relay.mqtt_sub); + client.publish(sensor->relay.mqtt_pub, relayRead(sensor) ? "1" : "0", + true); + } + + if (sensor->type & SENSOR_DIMMER) + { + Serial.println(sensor->dimmer.mqtt_sub); + client.subscribe(sensor->dimmer.mqtt_sub); + itoa(sensor->dimmer.level, convBuffer, 10); + client.publish(sensor->dimmer.mqtt_pub, convBuffer, true); + } + } + } + else + { + // Wait 5 seconds before retrying + delay(5000); + } + } +} + +void callback(char* topic, byte* payload, unsigned int length) +{ + char c_payload[length]; + memcpy(c_payload, payload, length); + c_payload[length] = '\0'; + + if (strcmp(topic, mqtt_pingall_sub) == 0) + { + blink(); + client.publish(mqtt_pingall_pub, + "{\"livingroom_ledstrip\":\"connected\"}"); + return; + } + + for (uint8_t i = 0; i < NUM(sensors); i++) + { + struct sensor_t *sensor = &sensors[i]; + if (sensor->type & SENSOR_RELAY + && length > 0 + && strcmp(topic, sensor->relay.mqtt_sub) == 0) + { + blink(); + relayWrite(sensor, payload[0] == '1', true); + return; + } + + if (sensor->type & SENSOR_DIMMER + && length > 0 + && strcmp(topic, sensor->dimmer.mqtt_sub) == 0) + { + blink(); + uint8_t level = atoi((char *)payload); + fadeDimmer(sensor, (level > 100) ? 100 : level, true); + return; + } + } +} + +void blink() +{ + //Blink on received MQTT message + digitalWrite(LED_BUILTIN, LOW); + delay(25); + digitalWrite(LED_BUILTIN, HIGH); +} + +void loop() +{ + if (!client.connected()) + reconnect(); + client.loop(); + checkButtons(); +} + +bool relayRead(struct sensor_t *sensor) +{ + if (sensor->type & SENSOR_RELAY) + return digitalRead(sensor->relay.pin) == RELAY_ON; + return false; +} + +void relayWrite(struct sensor_t *sensor, bool state, bool send_update) +{ + if (!(sensor->type & SENSOR_RELAY)) + return; + + Serial.print(F("Incoming change for relay: ")); + Serial.print(sensor->relay.pin); + Serial.print(F(", New state: ")); + Serial.println(state); + + digitalWrite(sensor->relay.pin, state ? RELAY_ON : RELAY_OFF); + + if (sensor->type & SENSOR_DIMMER) + analogWrite(sensor->dimmer.pin, state ? pwmValue(sensor->dimmer.level) : 0); + +#ifdef SAVE_RESTORE +#error "not implemented" +#endif + + if (send_update) + client.publish(sensor->relay.mqtt_pub, state ? "1" : "0", true); +} + +void flipRelay(struct sensor_t *sensor, bool send_update) +{ + relayWrite(sensor, relayRead(sensor) ? RELAY_OFF : RELAY_ON, send_update); +} + +inline void checkButtons(void) +{ + for (uint8_t i = 0; i < NUM(sensors); i++) + { + struct sensor_t *sensor = &sensors[i]; + if (sensor->type & SENSOR_BUTTON) + { + sensor->button.bounce.update(); + if (sensor->button.bounce.fell()) + flipRelay(sensor, true); + } + } +} + +const uint8_t pwmtable[101] PROGMEM = { + // value below 0 turns of the power supply + 0, 10, 10, 11, 11, 11, 11, 12, 12, 12, + 13, 13, 13, 13, 14, 14, 14, 15, 15, 15, + 16, 16, 17, 17, 17, 18, 18, 19, 19, 19, + 20, 20, 21, 21, 22, 22, 23, 23, 24, 25, + 25, 26, 26, 27, 28, 28, 29, 30, 30, 31, + 32, 32, 33, 34, 35, 35, 36, 37, 38, 39, + 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, + 50, 51, 52, 54, 55, 56, 58, 59, 60, 62, + 63, 65, 66, 68, 69, 71, 72, 74, 76, 78, + 79, 81, 83, 85, 87, 89, 91, 93, 95, 98, + 100 +}; + +inline uint8_t pwmValue(uint8_t level) +{ + //uint8_t lvl = 100 - (uint8_t)pgm_read_byte(&pwmtable[level]); + //return (lvl < 10) 10 : lvl; + //level = (level > 0 && level < 10) ? 10 : level; + //return 100 - level; + return 100 - (uint8_t)pgm_read_byte(&pwmtable[level]); +} + +void fadeDimmer(struct sensor_t *sensor, uint8_t level, bool send_update) +{ + if (!(sensor->type & SENSOR_DIMMER)) + return; + if (level > 100) + level = 100; + + Serial.print(F("Incoming change for dimmer: ")); + Serial.print(sensor->dimmer.pin); + Serial.print(F(", New level: ")); + Serial.println(level); + + if (level > 0 && sensor->type & SENSOR_RELAY && !relayRead(sensor)) + relayWrite(sensor, RELAY_ON, send_update); + + int delta = ((int8_t)(level - sensor->dimmer.level) < 0) ? -1 : 1; + while (sensor->dimmer.level != level) + { + sensor->dimmer.level += delta; + analogWrite(sensor->dimmer.pin, pwmValue(sensor->dimmer.level)); + delay(DIMMER_FADE_DELAY); + } + + if (level == 0 && sensor->type & SENSOR_RELAY && relayRead(sensor)) + relayWrite(sensor, RELAY_OFF, send_update); + +#ifdef SAVE_RESTORE +#error "not implemented" +#endif + + if (send_update) + { + itoa(level, convBuffer, 10); + client.publish(sensor->dimmer.mqtt_pub, convBuffer, true); + } +} + +void checkFirmwareUpdate() +{ + BearSSL::WiFiClientSecure update_client; + update_client.setInsecure(); + + client.publish(mqtt_device_boot, "fwupdate running"); + ESPhttpUpdate.setLedPin(LED_BUILTIN, HIGH); + ESPhttpUpdate.rebootOnUpdate(true); + t_httpUpdate_return ret = ESPhttpUpdate.update(update_client, FIRMWARE_URL, STR(FIRMWARE_VERSION)); + switch(ret) + { + case HTTP_UPDATE_FAILED: + { + Serial.printf_P(PSTR("HTTP_UPDATE_FAILED Error (%d): %s\n"), + ESPhttpUpdate.getLastError(), ESPhttpUpdate.getLastErrorString().c_str()); + String tmp = String("fwupdate error: ") + ESPhttpUpdate.getLastErrorString(); + client.publish(mqtt_device_boot, tmp.c_str()); + } + break; + + case HTTP_UPDATE_NO_UPDATES: + Serial.printf_P(PSTR("HTTP_UPDATE_NO_UPDATES\n")); + client.publish(mqtt_device_boot, "fwupdate noupdates"); + break; + + case HTTP_UPDATE_OK: + Serial.printf_P(PSTR("HTTP_UPDATE_OK\n")); + client.publish(mqtt_device_boot, "fwupdate ok"); + break; + } +} -- cgit v1.2.3