diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..89cc49c --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +.pio +.vscode/.browse.c_cpp.db* +.vscode/c_cpp_properties.json +.vscode/launch.json +.vscode/ipch diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..7c486f1 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,67 @@ +# Continuous Integration (CI) is the practice, in software +# engineering, of merging all developer working copies with a shared mainline +# several times a day < https://docs.platformio.org/page/ci/index.html > +# +# Documentation: +# +# * Travis CI Embedded Builds with PlatformIO +# < https://docs.travis-ci.com/user/integration/platformio/ > +# +# * PlatformIO integration with Travis CI +# < https://docs.platformio.org/page/ci/travis.html > +# +# * User Guide for `platformio ci` command +# < https://docs.platformio.org/page/userguide/cmd_ci.html > +# +# +# Please choose one of the following templates (proposed below) and uncomment +# it (remove "# " before each line) or use own configuration according to the +# Travis CI documentation (see above). +# + + +# +# Template #1: General project. Test it using existing `platformio.ini`. +# + +# language: python +# python: +# - "2.7" +# +# sudo: false +# cache: +# directories: +# - "~/.platformio" +# +# install: +# - pip install -U platformio +# - platformio update +# +# script: +# - platformio run + + +# +# Template #2: The project is intended to be used as a library with examples. +# + +# language: python +# python: +# - "2.7" +# +# sudo: false +# cache: +# directories: +# - "~/.platformio" +# +# env: +# - PLATFORMIO_CI_SRC=path/to/test/file.c +# - PLATFORMIO_CI_SRC=examples/file.ino +# - PLATFORMIO_CI_SRC=path/to/test/directory +# +# install: +# - pip install -U platformio +# - platformio update +# +# script: +# - platformio ci --lib="." --board=ID_1 --board=ID_2 --board=ID_N diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 0000000..272828b --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,7 @@ +{ + // See http://go.microsoft.com/fwlink/?LinkId=827846 + // for the documentation about the extensions.json format + "recommendations": [ + "platformio.platformio-ide" + ] +} \ No newline at end of file diff --git a/Readme.md b/Readme.md index 71f45f7..719e4d2 100644 --- a/Readme.md +++ b/Readme.md @@ -18,3 +18,8 @@ Simple MQTT-LED-Stripe Controller based on https://wiki.keks.cloud/doku.php?id=p * on = Just one color, color can changed via MQTT * fade = Fade * off = Off (color 000000000) + +# Error Codes +| Blink Code | Description | +| ---------- | ----------- | +| 4 short | MQTT Connection failed | \ No newline at end of file diff --git a/include/README b/include/README new file mode 100644 index 0000000..194dcd4 --- /dev/null +++ b/include/README @@ -0,0 +1,39 @@ + +This directory is intended for project header files. + +A header file is a file containing C declarations and macro definitions +to be shared between several project source files. You request the use of a +header file in your project source file (C, C++, etc) located in `src` folder +by including it, with the C preprocessing directive `#include'. + +```src/main.c + +#include "header.h" + +int main (void) +{ + ... +} +``` + +Including a header file produces the same results as copying the header file +into each source file that needs it. Such copying would be time-consuming +and error-prone. With a header file, the related declarations appear +in only one place. If they need to be changed, they can be changed in one +place, and programs that include the header file will automatically use the +new version when next recompiled. The header file eliminates the labor of +finding and changing all the copies as well as the risk that a failure to +find one copy will result in inconsistencies within a program. + +In C, the usual convention is to give header files names that end with `.h'. +It is most portable to use only letters, digits, dashes, and underscores in +header file names, and at most one dot. + +Read more about using header files in official GCC documentation: + +* Include Syntax +* Include Operation +* Once-Only Headers +* Computed Includes + +https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html diff --git a/led-controller.ino b/led-controller.ino deleted file mode 100644 index f918f80..0000000 --- a/led-controller.ino +++ /dev/null @@ -1,297 +0,0 @@ -#include -#include - -#define REDPIN1 5 -#define GREENPIN1 4 -#define BLUEPIN1 13 - -#define REDPIN2 12 -#define GREENPIN2 14 -#define BLUEPIN2 16 - -const char* SSID = "WIFISSID"; -const char* PSK = "WIDIPASS"; -const char* MQTT_BROKER = "mqtt.hostname.de"; -const char* MQTT_USER = ""; -const char* MQTT_PASS = ""; - -String LED1_MOD = "off"; -int LED1_SPEED = 10; -int LED1_RED = 0; -int LED1_GREEN = 0; -int LED1_BLUE = 0; -int LED1_LOOP = 0; -int LED1_LOOPCOUNT = 0; -int LED1_MODE_STEEP = 0; - -String LED2_MOD = "off"; -int LED2_SPEED = 10; -int LED2_RED = 0; -int LED2_GREEN = 0; -int LED2_BLUE = 0; -int LED2_LOOP = 0; -int LED2_LOOPCOUNT = 0; -int LED2_MODE_STEEP = 0; - -int LED_SYNC = 0; - -WiFiClient espClient; -PubSubClient client(espClient); - -void setup() { - //Turn LED ON - pinMode(LED_BUILTIN, OUTPUT); - digitalWrite(LED_BUILTIN, LOW); - - Serial.begin(115200); - Serial.println(); - - //LED Stripe Pins - analogWrite(REDPIN1, 0); - analogWrite(REDPIN2, 0); - analogWrite(GREENPIN1, 0); - analogWrite(GREENPIN2, 0); - analogWrite(BLUEPIN1, 0); - analogWrite(BLUEPIN2, 0); - - //Connecting to WiFi - Serial.print("Connecting to "); - Serial.println(SSID); - - WiFi.begin(SSID, PSK); - - while (WiFi.status() != WL_CONNECTED) { - delay(500); - Serial.print("."); - } - - Serial.println(""); - Serial.println("WiFi connected"); - Serial.println("IP address: "); - Serial.println(WiFi.localIP()); - - //Prepair MQTT Connection - client.setServer(MQTT_BROKER, 1883); - client.setCallback(callback); - - //Turn LED OFF - digitalWrite(LED_BUILTIN, HIGH); -} - -//Connect to MQTT -void reconnect() { - while (!client.connected()) { - digitalWrite(LED_BUILTIN, LOW); - Serial.print("Reconnecting..."); - if (!client.connect("ESP8266Client-LED-Controller-Schrank", "user", "password", "led1/status", 1, true, "0")) { - Serial.print("failed, rc="); - Serial.print(client.state()); - Serial.println(" retrying in 5 seconds"); - delay(5000); - } - client.subscribe("led1/#"); - } - client.publish("led1/status", "1", true); - digitalWrite(LED_BUILTIN, HIGH); -} -int loopDebugCount = 0; -void loop() { - if (!client.connected()) { - reconnect(); - } - client.loop(); - - if(LED1_MOD == "off") { - LED1_RED = 0; - LED1_GREEN = 0; - LED1_BLUE = 0; - } - if(LED2_MOD == "off") { - LED2_RED = 0; - LED2_GREEN = 0; - LED2_BLUE = 0; - } - - if(LED1_MOD == "fade") { - if(LED1_LOOP >= LED1_LOOPCOUNT) - { - fade_led_1(); - LED1_LOOP = 0; - } else { - LED1_LOOP ++; - } - } - if(LED2_MOD == "fade") { - if(LED2_LOOP >= LED2_LOOPCOUNT) - { - fade_led_2(); - LED2_LOOP = 0; - } else { - LED2_LOOP ++; - } - } - - if(LED_SYNC==1) { - LED2_RED = LED1_RED; - LED2_GREEN = LED1_GREEN; - LED2_BLUE = LED1_BLUE; - } - - analogWrite(REDPIN1, LED1_RED); - analogWrite(REDPIN2, LED2_RED); - analogWrite(GREENPIN1, LED1_GREEN); - analogWrite(GREENPIN2, LED2_GREEN); - analogWrite(BLUEPIN1, LED1_BLUE); - analogWrite(BLUEPIN2, LED2_BLUE); - /*if(loopDebugCount >= 200) { - char cc[20]; - String("LED1:"+String(LED1_RED)+":"+String(LED1_GREEN)+":"+String(LED1_BLUE)).toCharArray(cc, 20); - client.publish("led1/debug", cc); - String("LED2:"+String(LED2_RED)+":"+String(LED2_GREEN)+":"+String(LED2_BLUE)).toCharArray(cc, 20); - client.publish("led1/debug", cc); - loopDebugCount = 0; - } else { - loopDebugCount = loopDebugCount + 1; - }*/ - - - //delay(10); -} -void callback(char* topic, byte* payload, unsigned int length) { - String message = ""; - for (int i=0;i= 255) { - LED1_MODE_STEEP ++; - } - } - if(LED1_MODE_STEEP == 1) { - LED1_RED = 255; - LED1_GREEN = 0; - LED1_BLUE --; - if(LED1_BLUE <= 0) { - LED1_MODE_STEEP ++; - } - } - if(LED1_MODE_STEEP == 2) { - LED1_RED = 255; - LED1_GREEN ++; - LED1_BLUE = 0; - if(LED1_GREEN >= 255) { - LED1_MODE_STEEP ++; - } - } - if(LED1_MODE_STEEP == 3) { - LED1_RED --; - LED1_GREEN = 255; - LED1_BLUE = 0; - if(LED1_RED <= 0) { - LED1_MODE_STEEP ++; - } - } - if(LED1_MODE_STEEP == 4) { - LED1_RED = 0; - LED1_GREEN = 255; - LED1_BLUE ++; - if(LED1_BLUE >= 255) { - LED1_MODE_STEEP ++; - } - } - if(LED1_MODE_STEEP == 5) { - LED1_RED = 0; - LED1_GREEN --; - LED1_BLUE = 255; - if(LED1_GREEN <= 0) { - LED1_MODE_STEEP = 0; - } - } -} -void fade_led_2() { - if(LED2_MODE_STEEP == 0) { - LED2_RED = LED2_RED + 1; - LED2_GREEN = 0; - LED2_BLUE = 255; - if(LED2_RED >= 255) { - LED2_MODE_STEEP = LED2_MODE_STEEP + 1; - } - } - if(LED2_MODE_STEEP == 1) { - LED2_RED = 255; - LED2_GREEN = 0; - LED2_BLUE = LED2_BLUE - 1; - if(LED2_BLUE <= 0) { - LED2_MODE_STEEP = LED2_MODE_STEEP + 1; - } - } - if(LED2_MODE_STEEP == 2) { - LED2_RED = 255; - LED2_GREEN = LED2_GREEN + 1; - LED2_BLUE = 0; - if(LED2_GREEN >= 255) { - LED2_MODE_STEEP = LED2_MODE_STEEP + 1; - } - } - if(LED2_MODE_STEEP == 3) { - LED2_RED = LED2_RED - 1; - LED2_GREEN = 255; - LED2_BLUE = 0; - if(LED2_RED <= 0) { - LED2_MODE_STEEP = LED2_MODE_STEEP + 1; - } - } - if(LED2_MODE_STEEP == 4) { - LED2_RED = 0; - LED2_GREEN = 255; - LED2_BLUE = LED2_BLUE + 1; - if(LED2_BLUE >= 255) { - LED2_MODE_STEEP = LED2_MODE_STEEP + 1; - } - } - if(LED2_MODE_STEEP == 5) { - LED2_RED = 0; - LED2_GREEN = LED2_GREEN - 1; - LED2_BLUE = 255; - if(LED2_GREEN <= 0) { - LED2_MODE_STEEP = 0; - } - } -} diff --git a/lib/README b/lib/README new file mode 100644 index 0000000..6debab1 --- /dev/null +++ b/lib/README @@ -0,0 +1,46 @@ + +This directory is intended for project specific (private) libraries. +PlatformIO will compile them to static libraries and link into executable file. + +The source code of each library should be placed in a an own separate directory +("lib/your_library_name/[here are source files]"). + +For example, see a structure of the following two libraries `Foo` and `Bar`: + +|--lib +| | +| |--Bar +| | |--docs +| | |--examples +| | |--src +| | |- Bar.c +| | |- Bar.h +| | |- library.json (optional, custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html +| | +| |--Foo +| | |- Foo.c +| | |- Foo.h +| | +| |- README --> THIS FILE +| +|- platformio.ini +|--src + |- main.c + +and a contents of `src/main.c`: +``` +#include +#include + +int main (void) +{ + ... +} + +``` + +PlatformIO Library Dependency Finder will find automatically dependent +libraries scanning project source files. + +More information about PlatformIO Library Dependency Finder +- https://docs.platformio.org/page/librarymanager/ldf.html diff --git a/platformio.ini b/platformio.ini new file mode 100644 index 0000000..4ff2143 --- /dev/null +++ b/platformio.ini @@ -0,0 +1,15 @@ +;PlatformIO Project Configuration File +; +; Build options: build flags, source filter +; Upload options: custom upload port, speed and extra flags +; Library options: dependencies, extra library storages +; Advanced options: extra scripting +; +; Please visit documentation for the other options and examples +; https://docs.platformio.org/page/projectconf.html + +[env:d1] +platform = espressif8266 +board = d1 +framework = arduino + diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..6c229fa --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,275 @@ +#include +#include +#include + +#define REDPIN1 5 +#define GREENPIN1 4 +#define BLUEPIN1 13 + +#define REDPIN2 12 +#define GREENPIN2 14 +#define BLUEPIN2 16 + +#define MQTT_TOPIC_START "led1" +#define MQTT_USER "" +#define MQTT_PASS "" +#define MQTT_BROKER "mqtt.example.com" +#define MQTT_CLIENT_ID "LED-Schrank-1" + +const char* SSID = "WIFISSID"; +const char* PSK = "WIDIPASS"; + +WiFiClient espClient; +PubSubClient client(espClient); + + + +struct LEDStripe { + String MOD = "off"; //Which mode is used "off", "fade", "on" + String OLD_MOD = "off"; + int SPEED = 3000; + int RED = 0; + int GREEN = 0; + int BLUE = 0; + int LOOP = 0; + int LOOPCOUNT = 0; + int MOD_STEP = 0; +}; + +int Sync = 0; //Sync LED2 on the value of LED1 + +LEDStripe led1; +LEDStripe led2; + +void connectWiFi() { + digitalWrite(LED_BUILTIN, LOW); + Serial.println("Start WiFi Connection"); + WiFi.begin(SSID, PSK); + while (WiFi.status() != WL_CONNECTED) { + delay(500); + Serial.print("."); + } + digitalWrite(LED_BUILTIN, HIGH); + Serial.println(""); + Serial.println("WiFi connected"); + Serial.print("IP address: "); + Serial.println(WiFi.localIP()); +} + +//BLink +void blink_short() { + digitalWrite(LED_BUILTIN, LOW); + delay(500); + digitalWrite(LED_BUILTIN, HIGH); + delay(500); +} +void blink_long() { + digitalWrite(LED_BUILTIN, LOW); + delay(1500); + digitalWrite(LED_BUILTIN, HIGH); + delay(500); +} +void blink(int status) { + if(status == 1) { + blink_short(); + blink_short(); + blink_short(); + blink_short(); + } +} + + + +char* getTopicName(String topic) { + String topicName = String(MQTT_TOPIC_START)+String(topic); + int str_len = topicName.length() + 1; + char cc[str_len]; + topicName.toCharArray(cc, str_len); + return cc; +} + +void connectMQTT() { + digitalWrite(LED_BUILTIN, LOW); + Serial.print("Reconnecting..."); + if (!client.connect(MQTT_CLIENT_ID, MQTT_USER, MQTT_PASS, getTopicName("/status"), 1, true, "0")) { + Serial.print("failed, rc="); + Serial.print(client.state()); + Serial.println(" retrying in 5 seconds"); + digitalWrite(LED_BUILTIN, HIGH); + delay(2000); + blink(1); + delay(3000); + } + digitalWrite(LED_BUILTIN, HIGH); + client.subscribe(getTopicName("/#")); +} + + + +//Actions +void pulse_white_three_times() { + LEDStripe tmpLed(); +} + +//Modes +//LED Fade +void fade(LEDStripe led) { + if(led.MOD_STEP == 0) { + led.RED ++; + led.GREEN = 0; + led.BLUE = 255; + if(led.RED >= 255) { + led.MOD_STEP++; + } + } + if(led.MOD_STEP == 1) { + led.RED = 255; + led.GREEN = 0; + led.BLUE --; + if(led.BLUE <= 0) { + led.MOD_STEP++; + } + } + if(led.MOD_STEP == 2) { + led.RED = 255; + led.GREEN ++; + led.BLUE = 0; + if(led.GREEN >= 255) { + led.MOD_STEP++; + } + } + if(led.MOD_STEP == 3) { + led.RED --; + led.GREEN = 255; + led.BLUE = 0; + if(led.RED <= 0) { + led.MOD_STEP++; + } + } + if(led.MOD_STEP == 4) { + led.RED = 0; + led.GREEN = 255; + led.BLUE ++; + if(led.BLUE >= 255) { + led.MOD_STEP++; + } + } + if(led.MOD_STEP == 5) { + led.RED = 0; + led.GREEN --; + led.BLUE = 255; + if(led.GREEN <= 0) { + led.MOD_STEP = 0; + } + } +} + +void writeToLedStrips(LEDStripe l1, LEDStripe l2) { + analogWrite(REDPIN1, l1.RED); + analogWrite(REDPIN2, l2.RED); + analogWrite(GREENPIN1, l1.GREEN); + analogWrite(GREENPIN2, l2.GREEN); + analogWrite(BLUEPIN1, l1.BLUE); + analogWrite(BLUEPIN2, l2.BLUE); + Serial.println("LED1: "+String(l1.RED)+"|"+String(l1.GREEN)+"|"+String(l1.BLUE)); + Serial.println("LED2: "+String(l2.RED)+"|"+String(l2.GREEN)+"|"+String(l2.BLUE)); +} + +void callback(char* topic, byte* payload, unsigned int length) { + String message = ""; + for (int i=0;i