Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- .______ .______ __ __ __ __ ___ __ __ .___________. ______ .___ ___. ___ .___________. __ ______ .__ __.
- | _ \ | _ \ | | | | | | | | / \ | | | | | | / __ \ | \/ | / \ | || | / __ \ | \ | |
- | |_) | | |_) | | | | | | |__| | / ^ \ | | | | `---| |----`| | | | | \ / | / ^ \ `---| |----`| | | | | | | \| |
- | _ < | / | | | | | __ | / /_\ \ | | | | | | | | | | | |\/| | / /_\ \ | | | | | | | | | . ` |
- | |_) | | |\ \-.| `--' | | | | | / _____ \ | `--' | | | | `--' | | | | | / _____ \ | | | | | `--' | | |\ |
- |______/ | _| `.__| \______/ |__| |__| /__/ \__\ \______/ |__| \______/ |__| |__| /__/ \__\ |__| |__| \______/ |__| \__|
- Thanks much to @corbanmailloux for providing a great framework for implementing flash/fade with HomeAssistant https://github.com/corbanmailloux/esp-mqtt-rgb-led
- To use this code you will need the following dependancies:
- - Support for the ESP8266 boards.
- - You can add it to the board manager by going to File -> Preference and pasting http://arduino.esp8266.com/stable/package_esp8266com_index.json into the Additional Board Managers URL field.
- - Next, download the ESP8266 dependancies by going to Tools -> Board -> Board Manager and searching for ESP8266 and installing it.
- - You will also need to download the follow libraries by going to Sketch -> Include Libraries -> Manage Libraries
- - DHT sensor library
- - Adfruit unified sensor
- - PubSubClient
- - ArduinoJSON
- */
- #include <ESP8266WiFi.h>
- #include <DHT.h>
- #include <PubSubClient.h>
- #include <ESP8266mDNS.h>
- #include <WiFiUdp.h>
- #include <ArduinoOTA.h>
- #include <ArduinoJson.h>
- /************ WIFI and MQTT INFORMATION (CHANGE THESE FOR YOUR SETUP) ******************/
- #define wifi_ssid "_wifi_" //type your WIFI information inside the quotes
- #define wifi_password "_password_"
- #define mqtt_server "_mqtt_server_"
- #define mqtt_user "_username_"
- #define mqtt_password "_password_"
- #define mqtt_port 1883
- /************* MQTT TOPICS (change these topics as you wish) **************************/
- #define light_state_topic "home/shed"
- #define light_set_topic "home/shed/set"
- const char* on_cmd = "ON";
- const char* off_cmd = "OFF";
- /**************************** FOR OTA **************************************************/
- #define SENSORNAME "sensor-shed"
- #define OTApassword "_ota_password_" // change this to whatever password you want to use when you upload OTA
- int OTAport = 8266;
- /**************************** PIN DEFINITIONS ********************************************/
- const int redPin = D1;
- const int greenPin = D2;
- const int bluePin = D3;
- /***Added for button***/
- const int buttonPin = D6;
- #define PIRPIN D5
- #define DHTPIN D7
- #define DHTTYPE DHT22
- #define LDRPIN A0
- /**************************** SENSOR DEFINITIONS *******************************************/
- float ldrValue;
- int LDR;
- float calcLDR;
- float diffLDR = 25;
- /***Added for button***/
- // the current state of the LED and button
- int buttonState = LOW;
- // the current and previous readings from the input pin
- int thisButtonState = LOW;
- int lastButtonState = LOW;
- // time is measured in milliseconds and will quickly exceed limitations of an integer, so we use a long for these two
- unsigned long lastDebounceTime = 0; // the time the button state last switched
- unsigned long debounceDelay = 50; // the state must remain the same for this many millis to register the button press
- String pressStatus;
- float diffTEMP = 0.2;
- float tempValue;
- float diffHUM = 1;
- float humValue;
- int pirValue;
- int pirStatus;
- String motionStatus;
- char message_buff[100];
- int calibrationTime = 0;
- const int BUFFER_SIZE = 300;
- #define MQTT_MAX_PACKET_SIZE 512
- /******************************** GLOBALS for fade/flash *******************************/
- byte red = 255;
- byte green = 255;
- byte blue = 255;
- byte brightness = 255;
- byte realRed = 0;
- byte realGreen = 0;
- byte realBlue = 0;
- bool stateOn = false;
- bool startFade = false;
- unsigned long lastLoop = 0;
- int transitionTime = 0;
- bool inFade = false;
- int loopCount = 0;
- int stepR, stepG, stepB;
- int redVal, grnVal, bluVal;
- bool flash = false;
- bool startFlash = false;
- int flashLength = 0;
- unsigned long flashStartTime = 0;
- byte flashRed = red;
- byte flashGreen = green;
- byte flashBlue = blue;
- byte flashBrightness = brightness;
- WiFiClient espClient;
- PubSubClient client(espClient);
- DHT dht(DHTPIN, DHTTYPE);
- /********************************** START SETUP*****************************************/
- void setup() {
- Serial.begin(115200);
- pinMode(PIRPIN, INPUT);
- pinMode(DHTPIN, INPUT);
- pinMode(LDRPIN, INPUT);
- /***Added for button***/
- pinMode(buttonPin, INPUT);
- Serial.begin(115200);
- delay(10);
- ArduinoOTA.setPort(OTAport);
- ArduinoOTA.setHostname(SENSORNAME);
- ArduinoOTA.setPassword((const char *)OTApassword);
- Serial.print("calibrating sensor ");
- for (int i = 0; i < calibrationTime; i++) {
- Serial.print(".");
- delay(1000);
- }
- Serial.println("Starting Node named " + String(SENSORNAME));
- setup_wifi();
- client.setServer(mqtt_server, mqtt_port);
- client.setCallback(callback);
- ArduinoOTA.onStart([]() {
- Serial.println("Starting");
- });
- 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("IPess: ");
- Serial.println(WiFi.localIP());
- reconnect();
- }
- /********************************** START SETUP WIFI*****************************************/
- void setup_wifi() {
- delay(10);
- Serial.println();
- Serial.print("Connecting to ");
- Serial.println(wifi_ssid);
- WiFi.mode(WIFI_STA);
- WiFi.begin(wifi_ssid, wifi_password);
- while (WiFi.status() != WL_CONNECTED) {
- delay(500);
- Serial.print(".");
- }
- Serial.println("");
- Serial.println("WiFi connected");
- Serial.println("IP address: ");
- Serial.println(WiFi.localIP());
- }
- /********************************** START CALLBACK*****************************************/
- void callback(char* topic, byte* payload, unsigned int length) {
- Serial.print("Message arrived [");
- Serial.print(topic);
- Serial.print("] ");
- char message[length + 1];
- for (int i = 0; i < length; i++) {
- message[i] = (char)payload[i];
- }
- message[length] = '\0';
- Serial.println(message);
- if (!processJson(message)) {
- return;
- }
- if (stateOn) {
- // Update lights
- realRed = map(red, 0, 255, 0, brightness);
- realGreen = map(green, 0, 255, 0, brightness);
- realBlue = map(blue, 0, 255, 0, brightness);
- }
- else {
- realRed = 0;
- realGreen = 0;
- realBlue = 0;
- }
- startFade = true;
- inFade = false; // Kill the current fade
- sendState();
- }
- /********************************** START PROCESS JSON*****************************************/
- bool processJson(char* message) {
- StaticJsonBuffer<BUFFER_SIZE> jsonBuffer;
- JsonObject& root = jsonBuffer.parseObject(message);
- if (!root.success()) {
- Serial.println("parseObject() failed");
- return false;
- }
- if (root.containsKey("state")) {
- if (strcmp(root["state"], on_cmd) == 0) {
- stateOn = true;
- }
- else if (strcmp(root["state"], off_cmd) == 0) {
- stateOn = false;
- }
- }
- // If "flash" is included, treat RGB and brightness differently
- if (root.containsKey("flash")) {
- flashLength = (int)root["flash"] * 1000;
- if (root.containsKey("brightness")) {
- flashBrightness = root["brightness"];
- }
- else {
- flashBrightness = brightness;
- }
- if (root.containsKey("color")) {
- flashRed = root["color"]["r"];
- flashGreen = root["color"]["g"];
- flashBlue = root["color"]["b"];
- }
- else {
- flashRed = red;
- flashGreen = green;
- flashBlue = blue;
- }
- flashRed = map(flashRed, 0, 255, 0, flashBrightness);
- flashGreen = map(flashGreen, 0, 255, 0, flashBrightness);
- flashBlue = map(flashBlue, 0, 255, 0, flashBrightness);
- flash = true;
- startFlash = true;
- }
- else { // Not flashing
- flash = false;
- if (root.containsKey("color")) {
- red = root["color"]["r"];
- green = root["color"]["g"];
- blue = root["color"]["b"];
- }
- if (root.containsKey("brightness")) {
- brightness = root["brightness"];
- }
- if (root.containsKey("transition")) {
- transitionTime = root["transition"];
- }
- else {
- transitionTime = 0;
- }
- }
- return true;
- }
- /********************************** START SEND STATE*****************************************/
- void sendState() {
- StaticJsonBuffer<BUFFER_SIZE> jsonBuffer;
- JsonObject& root = jsonBuffer.createObject();
- root["state"] = (stateOn) ? on_cmd : off_cmd;
- JsonObject& color = root.createNestedObject("color");
- color["r"] = red;
- color["g"] = green;
- color["b"] = blue;
- root["brightness"] = brightness;
- root["humidity"] = (String)humValue;
- root["motion"] = (String)motionStatus;
- root["ldr"] = (String)LDR;
- root["temperature"] = (String)tempValue;
- /***Added for button***/
- root["button"] = (String)pressStatus;
- char buffer[root.measureLength() + 1];
- root.printTo(buffer, sizeof(buffer));
- Serial.println(buffer);
- client.publish(light_state_topic, buffer, true);
- }
- /********************************** START SET COLOR *****************************************/
- void setColor(int inR, int inG, int inB) {
- analogWrite(redPin, inR);
- analogWrite(greenPin, inG);
- analogWrite(bluePin, inB);
- Serial.println("Setting LEDs:");
- Serial.print("r: ");
- Serial.print(inR);
- Serial.print(", g: ");
- Serial.print(inG);
- Serial.print(", b: ");
- Serial.println(inB);
- }
- /********************************** START RECONNECT*****************************************/
- void reconnect() {
- // Loop until we're reconnected
- while (!client.connected()) {
- Serial.print("Attempting MQTT connection...");
- // Attempt to connect
- if (client.connect(SENSORNAME, mqtt_user, mqtt_password)) {
- Serial.println("connected");
- client.subscribe(light_set_topic);
- setColor(0, 0, 0);
- sendState();
- } else {
- Serial.print("failed, rc=");
- Serial.print(client.state());
- Serial.println(" try again in 5 seconds");
- // Wait 5 seconds before retrying
- delay(5000);
- }
- }
- }
- /********************************** START CHECK SENSOR **********************************/
- bool checkBoundSensor(float newValue, float prevValue, float maxDiff) {
- return newValue < prevValue - maxDiff || newValue > prevValue + maxDiff;
- }
- /********************************** START MAIN LOOP***************************************/
- void loop() {
- ArduinoOTA.handle();
- if (!client.connected()) {
- // reconnect();
- software_Reset();
- }
- client.loop();
- if (!inFade) {
- float newTempValue = dht.readTemperature(true);
- float newHumValue = dht.readHumidity();
- //BUTTON CODE
- // the buttonPin is read multiple times and the value must remain the same for debounceDelay millis to toggle the LED
- // read button state, HIGH when pressed, LOW when not
- thisButtonState = digitalRead(buttonPin);
- // if the current state does not match the previous state
- // the button was just pressed/released, or is transition noise
- if (thisButtonState != lastButtonState) {
- // reset the timer
- lastDebounceTime = millis();
- }
- // once delay millis have elapsed, if the state remains the same, register the press
- if ((millis() - lastDebounceTime) > debounceDelay) {
- // if the button state has changed
- if (thisButtonState != buttonState) {
- buttonState = thisButtonState;
- // only toggle the LED if the buttonState has switched from LOW to HIGH
- if (buttonState == HIGH) {
- pressStatus = "off";
- sendState();
- }
- else {
- pressStatus = "on";
- sendState();
- }
- }
- }
- lastButtonState = thisButtonState;
- delay(100);
- //PIR CODE
- pirValue = digitalRead(PIRPIN); //read state of the
- if (pirValue == LOW && pirStatus != 1) {
- motionStatus = "standby";
- sendState();
- pirStatus = 1;
- }
- else if (pirValue == HIGH && pirStatus != 2) {
- motionStatus = "motion detected";
- sendState();
- pirStatus = 2;
- }
- delay(100);
- if (checkBoundSensor(newTempValue, tempValue, diffTEMP)) {
- tempValue = newTempValue;
- sendState();
- }
- if (checkBoundSensor(newHumValue, humValue, diffHUM)) {
- humValue = newHumValue;
- sendState();
- }
- int newLDR = analogRead(LDRPIN);
- if (checkBoundSensor(newLDR, LDR, diffLDR)) {
- LDR = newLDR;
- sendState();
- }
- }
- if (flash) {
- if (startFlash) {
- startFlash = false;
- flashStartTime = millis();
- }
- if ((millis() - flashStartTime) <= flashLength) {
- if ((millis() - flashStartTime) % 1000 <= 500) {
- setColor(flashRed, flashGreen, flashBlue);
- }
- else {
- setColor(0, 0, 0);
- // If you'd prefer the flashing to happen "on top of"
- // the current color, uncomment the next line.
- // setColor(realRed, realGreen, realBlue);
- }
- }
- else {
- flash = false;
- setColor(realRed, realGreen, realBlue);
- }
- }
- if (startFade) {
- // If we don't want to fade, skip it.
- if (transitionTime == 0) {
- setColor(realRed, realGreen, realBlue);
- redVal = realRed;
- grnVal = realGreen;
- bluVal = realBlue;
- startFade = false;
- }
- else {
- loopCount = 0;
- stepR = calculateStep(redVal, realRed);
- stepG = calculateStep(grnVal, realGreen);
- stepB = calculateStep(bluVal, realBlue);
- inFade = true;
- }
- }
- if (inFade) {
- startFade = false;
- unsigned long now = millis();
- if (now - lastLoop > transitionTime) {
- if (loopCount <= 1020) {
- lastLoop = now;
- redVal = calculateVal(stepR, redVal, loopCount);
- grnVal = calculateVal(stepG, grnVal, loopCount);
- bluVal = calculateVal(stepB, bluVal, loopCount);
- setColor(redVal, grnVal, bluVal); // Write current values to LED pins
- Serial.print("Loop count: ");
- Serial.println(loopCount);
- loopCount++;
- }
- else {
- inFade = false;
- }
- }
- }
- }
- /**************************** START TRANSITION FADER *****************************************/
- // From https://www.arduino.cc/en/Tutorial/ColorCrossfader
- /* BELOW THIS LINE IS THE MATH -- YOU SHOULDN'T NEED TO CHANGE THIS FOR THE BASICS
- The program works like this:
- Imagine a crossfade that moves the red LED from 0-10,
- the green from 0-5, and the blue from 10 to 7, in
- ten steps.
- We'd want to count the 10 steps and increase or
- decrease color values in evenly stepped increments.
- Imagine a + indicates raising a value by 1, and a -
- equals lowering it. Our 10 step fade would look like:
- 1 2 3 4 5 6 7 8 9 10
- R + + + + + + + + + +
- G + + + + +
- B - - -
- The red rises from 0 to 10 in ten steps, the green from
- 0-5 in 5 steps, and the blue falls from 10 to 7 in three steps.
- In the real program, the color percentages are converted to
- 0-255 values, and there are 1020 steps (255*4).
- To figure out how big a step there should be between one up- or
- down-tick of one of the LED values, we call calculateStep(),
- which calculates the absolute gap between the start and end values,
- and then divides that gap by 1020 to determine the size of the step
- between adjustments in the value.
- */
- int calculateStep(int prevValue, int endValue) {
- int step = endValue - prevValue; // What's the overall gap?
- if (step) { // If its non-zero,
- step = 1020 / step; // divide by 1020
- }
- return step;
- }
- /* The next function is calculateVal. When the loop value, i,
- reaches the step size appropriate for one of the
- colors, it increases or decreases the value of that color by 1.
- (R, G, and B are each calculated separately.)
- */
- int calculateVal(int step, int val, int i) {
- if ((step) && i % step == 0) { // If step is non-zero and its time to change a value,
- if (step > 0) { // increment the value if step is positive...
- val += 1;
- }
- else if (step < 0) { // ...or decrement it if step is negative
- val -= 1;
- }
- }
- // Defensive driving: make sure val stays in the range 0-255
- if (val > 255) {
- val = 255;
- }
- else if (val < 0) {
- val = 0;
- }
- return val;
- }
- /****reset***/
- void software_Reset() // Restarts program from beginning but does not reset the peripherals and registers
- {
- Serial.print("resetting");
- ESP.reset();
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement