Close

Mini Update Configuration Portal and Optimized Code

A project log for Home automation on the cheap

Using an esp8266, arduino nano, a salvaged usb power supply, and a couple relays you can automate anything

thjubeckthjubeck 01/11/2017 at 08:460 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 this section to show the ip address in serial monitor 
   Serial.println("Ready");
   Serial.print("IP address: ");
   Serial.println(WiFi.localIP());
 */
}

void loop() {
   //Watch for update from http
  httpServer.handleClient();
  //Watch for ota update
  ArduinoOTA.handle();
  
  //check if there are any new clients
  if (server.hasClient()){
    for(i = 0; i < MAX_SRV_CLIENTS; i++){
      //find free/disconnected spot
      if (!serverClients[i] || !serverClients[i].connected()){
        if(serverClients[i]) serverClients[i].stop();
        serverClients[i] = server.available();
        continue;
      }
    }
    //no free/disconnected spot so reject
    WiFiClient serverClient = server.available();
    serverClient.stop();
  }
  
  //check clients for data
  for(i = 0; i < MAX_SRV_CLIENTS; i++){
    if (serverClients[i] && serverClients[i].connected()){
      if(serverClients[i].available()){
        //get data from the telnet client and push it to the UART
        while(serverClients[i].available())     
            //read data from client 
             ser = serverClients[i].read();
    
            //If input from client is 4 then run toggle light function
              if(ser == '2')
                    toggleLight();
            //If input from client is 4 then read the pin and give feedback
              else if(ser == '4')
                   serverClients[i].println(digitalRead(LightRelay));
      }
    }
  }
//Take reading of switch
reading = digitalRead(LightSwitch);

 //Check if debounce time has passed
  if ( (millis() - lastDebounceTime) > debounceDelay) { 
  // Check reading against previous 
    if (reading == LOW && previous == HIGH){ 
      //if something has changed run toggle light function
              toggleLight(); 
         } 
  }
//After checking if anything changed and setting output store reading as previous
previous = reading;
}

//Toggle light function
void toggleLight()
 {
  //Check if this is the first run
  if (LightStart == true){
  //If it is not first run then toggle light value
      relayValLight ^= 1; // xor current value with 1 (causes value to toggle)
      digitalWrite(LightRelay, relayValLight);
      digitalWrite(Light, relayValLight);
    //set last debounce to the current time
      lastDebounceTime = millis(); 
    //store the value to EEPROM address 0 and commit changes to EEPROM
      EEPROM.write(0,relayValLight);
      EEPROM.commit();
  }
  //If this is the first run then set all values accordingly
  else {
  //Set relay variable from the EEPROM
      relayValLight = EEPROM.read(0);
      digitalWrite(LightRelay,relayValLight);
      digitalWrite(Light,relayValLight);
   //Set the start bit to true. This function is only ran once at startup
      LightStart = true;
  }
 }

Discussions