Using an esp8266, arduino nano, a salvaged usb power supply, and a couple relays you can automate anything
To make the experience fit your profile, pick a username and tell us what interests you.
We found and based on your interests.
20160527_014937.jpgJPEG Image - 2.90 MB - 03/19/2018 at 04:11 |
|
|
20160527_015122.jpgJPEG Image - 2.56 MB - 03/19/2018 at 04:11 |
|
|
20160527_015002.jpgJPEG Image - 2.75 MB - 03/19/2018 at 04:11 |
|
|
20160527_014942.jpgJPEG Image - 2.19 MB - 03/19/2018 at 04:11 |
|
|
Old Version.zipx-zip-compressed - 20.93 MB - 03/19/2018 at 04:10 |
|
This project is going to become a more professional project in terms of the protocol used.
I have been working on a MQTT controlled version of this project and am currently working on documenting the newest revision on a new page that I will link soon.
I currently have a version working with MQTT and as well as some big surprises planned stay tuned for more information in the next couple weeks.
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
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
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.
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
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>
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:
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 »
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
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 »
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.
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.
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 »
Create an account to leave a comment. Already have an account? Log In.
The diagram is just an example, I'm actually using 5v optocoupled relays. While there are several examples using the ESP8266 itself as the micro-controller, the esp-link firmware makes it a breeze for connecting to wifi with a gui interface no extra programming required each time you change the ssid. This configuration also allows me to remote program very easily which, yes it can be done with the ESP8266 as well but this project keeps it simple as far as connection is concerned.
Added a direct method. After figuring out the little stuff it wasn't as bad as I thought.
Become a member to follow this project and never miss any updates
I miss drive transistors for the relays! Normal Microcontroller outputs have not enough drive strength for relays (>=100mA). A small NPN or NMOS transistor is necessary.
It would also possible to omit the extra Arduino. You need only 4 IO Pins. There are libraries to program the ESP8266 itself like an arduino. It contains already a 32bit CPU.