• V2 Updated Logs

    thjubeck04/14/2018 at 06:26 0 comments

    I will try to keep the logs from version 2 posted here just for information but all further code development will be uploaded at  version 2

    • State Machine Debouncing

      thjubeck • 04/14/2018 at 02:00

      The state machine article posted a few days ago was really interesting so the debouncing technique has been added to the project as opposed to the timer debouncing that was there before. This also allows for more functionality in the future so reply with comments if you would like to see anything specific added and maybe it will be available in the future. 

      See the links below for the Hack a Day article as well as the creators GitHub page. Be sure to check out his video as it is very interesting and has a lot to learn from it. 

      https://hackaday.com/2018/04/06/state-your-intentions-more-clearly-with-state-machines/#more-302326

      https://gist.github.com/NormalUniverse/5b3a8a8d909b56b58b67bd3ec2808f4b#file-simple-button-debounce-state-machine

    • Initial Log

      thjubeck • 03/19/2018 at 06:18

      This project is a continuation of the first home automation project https://hackaday.io/project/11922-home-automation-on-the-cheap  with  a few updates. 

      First is a web-page built into the esp8266 for displaying the temperature and controlling the light. You can access this page by entering the ip adress of the esp8266 in the browser and it should show the sensor and light control. Also the update page is located at http://youresp8266ip/update. It is also possible to update the esp8266 directly from the arduino IDE by selecting the ip/hostname as the port. 

      IMPORTANT!!!!!!!

      FAILURE TO DO THIS WILL RESULT IN THE OTA UPDATE NOT WORKING!!!

      AFTER UPDATING THE ESP8266 OVER SERIAL ALWAYS MANUALLY CLICK THE RESET BUTTON ON THE ESP8266  THIS IS BECAUSE OF A KNOWN BUG IN THE WATCHDOG FIND OUT MORE HERE https://github.com/esp8266/Arduino/tree/master/doc/faq IMPORTANT!!!!!!!

      Second is the structure of the program. It is now broken up into tabs and individual programs / configuration files to make it a little easier to understand what is happening

      Lastly, the web-page is now completely controlled through php without the need for scripts running on the web-server constantly. The handling of the updates is now  much more streamline as the esp8266 triggers the php script directly on the update cycle set in the program. 

      All the files needed are included in the files list and there is a README file to get started. There is an update planned where the temp sensor is optional so watch for that in future updates. Also the webcam stream will be added in future updates as well. 

  • Major Update

    thjubeck03/19/2018 at 03:49 0 comments

    Well after a long thought process, I decided to do a major revamp of this project so webcam will have to wait for a future post.

    I will be starting a new project as this one is a little cluttered.

    You can find more information here:  https://hackaday.io/project/94867-home-automation-on-the-cheap-v2

  • Webpage Update

    thjubeck03/15/2018 at 04:59 0 comments

    So after a long break from writing, this series of logs will once again get an update. After reviewing the webpage code which was hard to follow, I decided to clean it up a bit and leave only what is necessary to run. As seen below the code is much more manageable and should run much smoother if you only have one light. There is still some code that can be cleaned up or removed but some will be used in my next update on the topic of adding the streaming webcam to the page. Stay tuned as more updates will follow. 

    <?php
    
    if (isset($_POST["ON1"])) {
      $fp = fsockopen("10.125.2.1", 23, $errno, $errstr);  // Replace the  IP address with your own
    if (!$fp) {
        echo "$errstr ($errno)<br />\n";
    } else {
        fwrite($fp, "2");
        fclose($fp);
        }
    } 
    
    $f_pointer2 =fsockopen("10.125.2.1", 23, $errno, $errstr); // Replace the  IP address with your own
    fwrite($f_pointer2,'4'); 
    $lampstat=fread($f_pointer2, 1); //1 is the character length to be read. arduino sends a char length data
    fclose($f_pointer2);
    
    if ($lampstat=='0') {
       $Source3="/images/offbulb.png";
        $stat2 = "Off";
    } else {
        $Source3="/images/onbulb.png";
         $stat2 = "On";
    }
    
    
    $verz="2.0";
    
    ?>
    
    <html>
    <body>
    
    <center><h1>MY LIGHTS</h1><b>Version <?php echo $verz; ?></b></center><br/>
    
    <center><b>Lamp <?php echo $stat2?>  <img src="<?php echo $Source3; ?>"  alt="Light On" height="42" width="42" </a> </b></center>
    
    <form method="post" action="temp.php" >
    <center><h3>Bedroom</h3>
    
    <input type="submit" value="Lamp" name="ON1"  action="temp.php" width=20% height=10%  ><br/><br/>
    
    
    <!--
    
    <br/></center>
    
    <!--<b><img src=temp_graphShort.png></a></b><br/>
    
    <b><img src=temp_graphtoday.png></a></b><br/>
    
    <b><img src=temp_graph.png></a></b><br/>
    
    <b><img src=temp_graphmonth.png></a></b><br/>
    
    <b><img src=temp_graphyear.png></a></b><br/>
    
    
    <center><b><img src="stream.php"></b><br/></center> -->
    
    
    
    </form>
    
    </body>
    </html>

  • Mini Update Configuration Portal and Optimized Code

    thjubeck01/11/2017 at 08:46 0 comments

    UPDATE: tested webpage update. It works really well.

    For this update I tried to clean up the code a little and added a Configuration Portal for Wifi so no longer have to change the code to get this to work as long as you use the outputs and inputs the same as in the code. I may try to add the ability to enable setting the hostname from the Configuration portal as well but for now, still have to use the hardcode for that.

    GPIO 12 is the light relay

    GPIO 0 is the indicator light

    GPIO 2 is the push button

    New Creds:

    Configuration Portal

    To install new libraries see here

    //Define all Libraries to be used
    
    #include <ESP8266WiFi.h>
    #include <ESP8266mDNS.h>
    #include <WiFiUdp.h>
    #include <ArduinoOTA.h>
    #include <EEPROM.h>
    #include <ESP8266WebServer.h>
    #include <ESP8266HTTPUpdateServer.h>
    #include <DNSServer.h>
    #include <ESP8266WebServer.h>
    #include <WiFiManager.h> 
    
    //Define Outputs, inputs, and if started bit. Remember on the WEMOS board these are the GPIO numbers not what is on the board
    boolean LightStart = false;
    int LightRelay = 14;
    int Light = 0;
    int LightSwitch =2;
    
    static int relayValLight = 0;  //Define relayValLight as 0
    
    char ser;   //Define the character ser that will be used later
    uint8_t i=0; // Define i. Used in a counter 
    
    int reading;           // the current reading from the input pin
    int previous = HIGH;    // the previous reading from the input pin
    
    void toggleLight(); //Define the toggle light function
    
    //Set Debounce Time
    
    long lastDebounceTime = 0;  // the last time the output pin was toggled
    long debounceDelay = 50;  // the debounce time; increase if the output flickers
    
    //how many clients should be able to telnet to this ESP8266
    #define MAX_SRV_CLIENTS 3
    
    //Define hostname
    const char* host = "myesp8266"; // This value can be changed and should be if you use multiple devices
    
    //Define Port to start server on
    WiFiServer server(23);
    //Define Max Clients that can connect
    WiFiClient serverClients[MAX_SRV_CLIENTS];
    
    //Needed for httpUpgrade webpage. Define server at port 80
    ESP8266WebServer httpServer(80);
    ESP8266HTTPUpdateServer httpUpdater;
    
    
    void setup() {
     //EEPROM start. This is a function of the ESP8266 that is needed for EEPROM to work
      EEPROM.begin(512);
     //Begin Serial
      Serial.begin(115200);
     //Begin WiFi Manager
      WiFiManager wifiManager;
     /*include only one of the below functions. The first auto connects the second always
       creates a Configuration Portal*/
      wifiManager.autoConnect("AutoConnectAP");
      //wifiManager.startConfigPortal("OnDemandAP");
     
      server.begin();
      server.setNoDelay(true);
      
      //Setup Outputs and Inputs
      pinMode(LightSwitch, INPUT_PULLUP);
      pinMode(LightRelay, OUTPUT);
      pinMode(Light, OUTPUT);
      
    
    // WIFI OTA SECTION
    
      // Port defaults to 8266
      // ArduinoOTA.setPort(8266);
    
      // Hostname defaults to esp8266-[ChipID]
      ArduinoOTA.setHostname(host);
    
      // No authentication by default
      //ArduinoOTA.setPassword((const char *)"123");
    
      ArduinoOTA.onStart([]() {
        Serial.println("Start");
      });
      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();
     
    //Create UPDATE WEB PAGE this webpage will be at http://(host).local/update
      MDNS.begin(host);
      httpUpdater.setup(&httpServer);
      httpServer.begin();
      MDNS.addService("http", "tcp", 80);
    
    // My switch has an indicator light so I blink it here to indicate setup done
      digitalWrite(Light,HIGH);
      delay(500);
      digitalWrite(Light,LOW);
    
    //Call toggle light function to set old value
       toggleLight();
      
    /*
     //Uncomment...
    Read more »

  • Direct Program

    thjubeck01/09/2017 at 05:42 0 comments

    UPDATE: ADDED comments and updated EEPROM to work correctly after power off. Will be doing a mini update with an optimized version of the code that includes a auto-start hot spot for setting up connections on the fly

    NOTE: I recommend using the EEPROM clear function in examples before uploading this code as I have had issues with this and other micro-controllers where I did not clear the EEPROM before using.

    So I finally broke down and figured out how to program this without the additional micro-controller. I used a Wemos D1 mini (the esp8266 on a breakout) which allowed me to power directly from the 5v and program easier. Connect the inputs and outputs to the Wemos directly and power directly from the 5v. This sketch includes debouncing, telnet control, and OTA update abilities both with the IDE and directly to the ESP8266. This sketch uses a push button where all the other examples use a toggle switch so please keep that in mind if replacing the old sketch.

    As a note I have not tried uploading using the web page so if anyone wants to comment on how that works please let me know.

    To set up arduino to program the ESP8266 directly, please see this link.

    CREDS: Debouncing

    Programming

    WEMOS info

    OTA

    Direct Upload

    EEPROM

    IMPORTANT NOTE!!!!: The pins on the WEMOS are referenced by the GPIO number not the D1 number on the board

    You will have to update the SSID and Password but Should Work besides that.

    //Define all Libraries to be used
    
    #include <ESP8266WiFi.h>
    #include <ESP8266mDNS.h>
    #include <WiFiUdp.h>
    #include <ArduinoOTA.h>
    #include <EEPROM.h>
    #include <ESP8266WebServer.h>
    #include <ESP8266HTTPUpdateServer.h>
    
    //Define Outputs, inputs, and if started bit. Remember on the WEMOS board these are the GPIO numbers not what is on the board
    boolean LightStart = false;
    int LightRelay = 14;
    int Light = 0;
    int LightSwitch =2;
    
    static int relayValLight = 0;  //Define relayValLight as 0
    
    char ser;   //Define the character ser that will be used later
    
    int reading;           // the current reading from the input pin
    int previous = HIGH;    // the previous reading from the input pin
    
    void toggleLight(); //Define the toggle light function
    
    //Set Debounce Time
    
    long lastDebounceTime = 0;  // the last time the output pin was toggled
    long debounceDelay = 50;  // the debounce time; increase if the output flickers
    
    //how many clients should be able to telnet to this ESP8266
    #define MAX_SRV_CLIENTS 3
    
    //Define Wifi SSID and Password
    const char* ssid = "YourSSIDGoesHere";
    const char* password = "YourPasswordGoesHere";
    const char* host = "myesp8266"; // This value can be changed and should be if you use multiple devices
    
    //Define Port to start server on
    WiFiServer server(23);
    //Define Max Clients that can connect
    WiFiClient serverClients[MAX_SRV_CLIENTS];
    
    //Needed for httpUpgrade webpage. Define server at port 80
    ESP8266WebServer httpServer(80);
    ESP8266HTTPUpdateServer httpUpdater;
    
    
    void setup() {
     //EEPROM start. This is a function of the ESP8266 that is needed for EEPROM to work
      EEPROM.begin(512);
      WiFi.begin(ssid, password);
      uint8_t i = 0;
      while (WiFi.status() != WL_CONNECTED && i++ < 20) delay(500);
    
      Serial.begin(115200);
      server.begin();
      server.setNoDelay(true);
      
      //Setup Outputs and Inputs
      pinMode(LightSwitch, INPUT_PULLUP);
      pinMode(LightRelay, OUTPUT);
      pinMode(Light, OUTPUT);
      
    
    // WIFI OTA SECTION
    
      // Port defaults to 8266
      // ArduinoOTA.setPort(8266);
    
      // Hostname defaults to esp8266-[ChipID]
      ArduinoOTA.setHostname(host);
    
      // No authentication by default
      //ArduinoOTA.setPassword((const char *)"123");
    
      ArduinoOTA.onStart([]() {
        Serial.println("Start");
      });
      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")...
    Read more »

  • Wireless Programming

    thjubeck09/19/2016 at 05:15 0 comments

    For wireless programming/re-programming, I connect to the esp using hardware virtual serial port found here.

    Be sure to disable NVT in the settings or you will not be able to program the controller.


  • Phone Time

    thjubeck09/15/2016 at 17:51 0 comments

    Controlling the lights over a phone is relatively simple. I use two apps on my phone, Send/Expect https://play.google.com/store/apps/details?id=com.asif.plugin.sendexpect (Yes it is a paid app but there is a trial version available on their site for those just wanting to try it ) and Tasker https://play.google.com/store/apps/details?id=net.dinglisch.android.taskerm)

    The send variable is what controls the lights while the expect variable is how I am checking if the lights are on or off so if you just want a simple control, just use the configuration without the if or the expect as below.




  • Min Update

    thjubeck08/08/2016 at 03:25 0 comments

    If everything is working correctly, this is how the webpage should look. Note the fan icon is animated when on and the lights have two states as well.

  • Web Page

    thjubeck07/21/2016 at 05:03 0 comments

    Time for the webpage. The page is written in php it is not the easiest way but I liked writing it. If you would like a tutorial on how to set up a Linux LAMP server please reply in the comments and I will try to get that up.

    <?php
    
    if (isset($_POST["ON0"])) {
     $fp = fsockopen("10.125.1.20", 23, $errno, $errstr);  // Replace the  IP address with your own
    if (!$fp) {
        echo "$errstr ($errno)<br />\n";
    } else {
        fwrite($fp, "2");
        fclose($fp);
    	}
     }
     
    else if (isset($_POST["ON1"])) {
      $fp = fsockopen("10.125.1.20", 23, $errno, $errstr);   // Replace the  IP address with your own
    if (!$fp) {
        echo "$errstr ($errno)<br />\n";
    } else {
        fwrite($fp, "3");
        fclose($fp);
    	}
    } 
    
    else if (isset($_POST["ON2"])) {
      $fp = fsockopen("10.125.1.21", 23, $errno, $errstr);  // Replace the  IP address with your own
    if (!$fp) {
        echo "$errstr ($errno)<br />\n";
    } else {
        fwrite($fp, "2");
        fclose($fp);
    	}
    } 
    
    if (isset($_POST["ON3"])) {
    
    
    
    
    $f_pointer =fsockopen("10.125.1.20", 23, $errno, $errstr);  // Replace the  IP address with your own
    fwrite($f_pointer,'4'); 
    $fanstat=fread($f_pointer, 1); //1 is the character length to be read. arduino sends a char length data
    fclose($f_pointer);
    
    $f_pointer1 =fsockopen("10.125.1.20", 23, $errno, $errstr);   // Replace the  IP address with your own
    fwrite($f_pointer1,'5'); 
    $lightstat=fread($f_pointer1, 1); //1 is the character length to be read. arduino sends a char length data
    fclose($f_pointer1);
    
    
    $f_pointer2 =fsockopen("10.125.1.21", 23, $errno, $errstr);   // Replace the  IP address with your own
    fwrite($f_pointer2,'4'); 
    $lampstat=fread($f_pointer2, 1); //1 is the character length to be read. arduino sends a char length data
    fclose($f_pointer2);
    
    
    
    if ($lightstat == '1'){
    	$nLightstat= 2;
    	
    }
    else if ($lightstat == '0'){
    	$nLightstat= 0;
    }
    
    
    if ($lampstat == '1'){
    	$nLampstat = 0;
    }
    
    else if ($lampstat == '0'){
    	$nLampstat = 2;
    }
    
      $fp = fsockopen("10.125.1.20", 23, $errno, $errstr);      // Replace the  IP address with your own
      $fp1 = fsockopen("10.125.1.21", 23, $errno, $errstr);    // Replace the  IP address with your own
    if (!$fp ) {
        echo "$errstr ($errno)<br />\n";
    } 
    else {
        fwrite($fp, $nLightstat);
        fwrite($fp1,$nLampstat);
    
        fclose($fp);
        fclose($fp1);
    
    	}
    } 
    
    
    
    
    
    
    $f_pointer =fsockopen("10.125.1.20", 23, $errno, $errstr); // Replace the  IP address with your own
    fwrite($f_pointer,'4'); 
    $fanstat=fread($f_pointer, 1); //1 is the character length to be read. arduino sends a char length data
    fclose($f_pointer);
    
    $f_pointer1 =fsockopen("10.125.1.20", 23, $errno, $errstr); // Replace the  IP address with your own
    fwrite($f_pointer1,'5'); 
    $lightstat=fread($f_pointer1, 1); //1 is the character length to be read. arduino sends a char length data
    fclose($f_pointer1);
    
    $f_pointer2 =fsockopen("10.125.1.21", 23, $errno, $errstr); // Replace the  IP address with your own
    fwrite($f_pointer2,'4'); 
    $lampstat=fread($f_pointer2, 1); //1 is the character length to be read. arduino sends a char length data
    fclose($f_pointer2);
    
    if ($lightstat=='0') {
       $Source="/images/offbulb.png";
       $stat = "Off";
    } else {
      $Source="/images/onbulb.png";
      $stat = "On";
    }
    
    
    if ($fanstat=='0') {
       $Source1="/images/fan.png";
        $stat1 = "Off";
    } else {
        $Source1="/images/fan.gif";
         $stat1 = "On";
    }
    
    if ($lampstat=='0') {
       $Source3="/images/offbulb.png";
        $stat2 = "Off";
    } else {
        $Source3="/images/onbulb.png";
         $stat2 = "On";
    }
    
    
    
    $verz="1.0";
    
    ?>
    
    <html>
    <body>
    
    <center><h1>MY LIGHTS</h1><b>Version <?php echo $verz; ?></b></center><br/>
    <center><b>Lights <?php echo $stat; ?> <img src="<?php echo $Source; ?>"  alt="Light Off" height="42" width="42" </a> </b></center>
    <center><b>Fan <?php echo $stat1?>  <img src="<?php echo $Source1; ?>"  alt="Light On" height="42" width="42" </a> </b></center>
    <center><b>Lamp <?php echo $stat2?>  <img src="<?php echo $Source3; ?>"  alt="Light On" height="42" width="42" </a> </b></center>
    
    
    <form method="post" action="temp.php" >
    <center><h3>Bedroom</h3>
    
    <input type="submit" value="Lights" name="ON0"  action="temp.php" width=20% height=...
    Read more »

  • Mini Update

    thjubeck06/28/2016 at 07:17 0 comments

    This update covers power outages and what happens next. This code retains the last state of the relay and uses that as the initial value instead of the switch position. If you would rather have the light come on in the state of the switch on reset use the code in my other post.

    #include <EEPROM.h>
    boolean FanStart = false;
    boolean LightStart = false;
    
    int LightRelay = 7;  // pin the light relay is connected to 
    int FanRelay  = 6;  // pin the fan relay is connected to 
    
    int FanSwitch = 3;   // pin the fan switch is connected to 
    int LightSwitch =2;  // pin the light is connected to 
    
    int relayValLight = 0; // sets the lights initially to off
    int relayValFan = 0;  // sets the fan initially to off
    
    char ser;  // Serial character received
    
    int reading;           // the current reading from the input pin
    int previous = HIGH;    // the previous reading from the input pin
    
    int reading1;           // the current reading from the input pin
    int previous1 = HIGH;    // the previous reading from the input pin
    
    void setup(void){
     Serial.begin(115200);
     pinMode(FanSwitch,INPUT_PULLUP);
     pinMode(LightSwitch, INPUT_PULLUP);
     pinMode(LightRelay, OUTPUT);
     pinMode(FanRelay, OUTPUT);
     digitalWrite(FanRelay,LOW);
     digitalWrite(LightRelay,LOW);
     }
    
    void loop(void){
    if (Serial.available()) {
       ser = Serial.read();
       if (ser == '1')
         AllOff();
       else if(ser == '2')
        toggleFan();
       else if(ser == '3')
        toggleLight();
       else if(ser == '4')
       Serial.println(digitalRead(LightRelay));
       else if(ser == '5')
       Serial.println(digitalRead(FanRelay));
      }
    
      reading = digitalRead(FanSwitch);
      if (reading == HIGH && previous == LOW || reading == LOW && previous == HIGH){ 
       toggleFan();
      previous = reading;
      } 
      reading1 = digitalRead(LightSwitch);
      if (reading1 == HIGH && previous1 == LOW || reading1 == LOW && previous1 == HIGH){ 
       toggleLight();
      previous1 = reading1;
      } 
    }
    
    void toggleFan() //Function for fan
     {
     
     if (FanStart == true)
     {
       relayValFan ^= 1; // xor current value with 1 (causes value to toggle)
       
          digitalWrite(FanRelay, relayValFan);
          EEPROM.write(0,relayValFan);
        //  Serial.println("NoEEPROM"); 
        }
     
     else {
       relayValFan = EEPROM.read(0);
       digitalWrite(FanRelay,relayValFan);
       FanStart = true;
       // Serial.println("EEPROM"); 
     
     
     }
     }
    void toggleLight()  // Function for light
     {
     
     if (LightStart == true )
     {
       relayValLight ^= 1; // xor current value with 1 (causes value to toggle)
       
          digitalWrite(LightRelay, relayValLight);
          EEPROM.write(1,relayValLight);
        //  Serial.println("NoEEPROM"); 
        }
     
     else {
       relayValLight = EEPROM.read(1);
       digitalWrite(LightRelay,relayValLight);
       LightStart = true;
      // Serial.println("EEPROM"); 
       
     
     }
     }
    
    void AllOff() //Function to turn all lights off
    {
        relayValFan = 0;
        relayValLight = 0;
        
        digitalWrite(LightRelay, LOW);
        digitalWrite(FanRelay,LOW);
        
        EEPROM.write(0,relayValFan);
        EEPROM.write(1,relayValLight);
    }