// ******************** SONOFF BASIC ******************************* // HTTP server - Access point mode V1.6 / 2018-03-18 for SONOFF BASIC // Copyright 2018 Pavel Janko, www.fancon.cz // MIT license, http://opensource.org/licenses/MIT // without any cloud // POST or GET method selector, // WiFi channel selector, // HTTP BASIC authentication, // supports simply OTA from browser. // Tested with ARDUINO ESP8266 2.4.1, IDE 1.8.5 // Sonoff BASIC has 1MB flash memory only ! // For flashing disconnect the external AC power! Power Sonoff only from // the USB to Serial converter for your safety ! // Uploading a new application to the Sonoff cancel original firmware ! // Set Generic ESP8266 or ESP8285 by chip types and 1MB flash memory // It can also be a classic esp8266 (with at least 1MB of memory for OTA). // After flash from serial, restart the device. // // IP address of AP is 192.168.4.1 // Default access point password is "password" // // For web authentication set #define WWWAUTHENTI true and // your WWWUSERNAME and WWWPASSWORD below only. // // For OTA activation set OTAUSER, OTAPASSWORD and then in operation // write to browser address row http://192.168.4.1/firmware and upload your *.bin // file. // // // |---------------|-----------|------------------| // | Button | GREEN LED | Action | // |---------------|-----------|------------------| // |short press |relay state|change relay state| // |long press > 3s| change |restart ESP8266 | // | -- |flashing |after restart | // | -- |short flash|client got page | // |before power on| -- |flash mode only | // |---------------|-----------|------------------| #include #include #include #include #define APSSID "SONOFF_AP"// AP SSID #define APPASSWORD "password" // AP password must be longer then 7 characters #define WIFICHANNEL 1 // Set WiFi Channel 1-13 #define WWWAUTHENTI false // Set true for web authentication #define WWWUSERNAME "admin" // Set www user name #define WWWPASSWORD "admin" // Set www user password #define OTAUSER "admin" // Set OTA user #define OTAPASSWORD "admin" // Set OTA password #define OTAPATH "/firmware"// Set path for update #define HTTPMETHOD "POST" // Set "GET" or "POST" method #define BUTTONPIN 0 // GPIO0 button pin #define RELAYPIN 12 // GPIO12 relay pin #define LEDPIN 13 // GPIO13 GREEN LED (active low) #define BUTTONTIME 0.25 // [s] time between button read #define SERVERPORT 80 #define BUTTONON "color: green; border: 3px #fff outset;" #define BUTTONOFF "color: red; border: 3px #fff outset;" #define BUTTONNOACT "color: black; border: 7px #fff outset;" bool LedState = true; // Green LED off bool RelayState = false; // Relay off bool ButtonFlag = false; char ButtonCount = 0; String OnButt; String OffButt; String buff; ESP8266WebServer HttpServer(SERVERPORT); ESP8266HTTPUpdateServer httpUpdater; Ticker ButtonTick; // Preparing for periodic button reading //----------------------------------------------------------------- void setup(void) { //Serial.begin(115200); WiFi.persistent(false); WiFi.softAP(APSSID, APPASSWORD, WIFICHANNEL); WiFi.mode(WIFI_AP); /* set ports */ pinMode(BUTTONPIN, INPUT); pinMode(LEDPIN, OUTPUT); pinMode(RELAYPIN, OUTPUT); RelaySet(RelayState); httpUpdater.setup(&HttpServer, OTAPATH, OTAUSER, OTAPASSWORD); HttpServer.on("/", HTTP_GET, ModifySendPage); HttpServer.on("/", HTTP_POST, ModifySendPage); HttpServer.onNotFound(handleNotFound); HttpServer.begin(); for (int i = 0; i < 20; i++) { GreenLedSet(!LedState); delay(100); } ButtonTick.attach(BUTTONTIME, ButtonFlagSet); } //----------------------------------------------------------------- void loop(void) { HttpServer.handleClient(); // Listen for HTTP requests from clients if (ButtonFlag) GetButton(); // Periodic serve button } //----------------------------------------------------------------- void SendPage() { GreenLedSet(!LedState); buff = "\n"; buff += "\n"; buff += "\n"; buff += "\n"; buff += "SONOFF - Basic\n"; buff += "
\n"; buff += "
\n"; buff += "

Sonoff ID : " + String(ESP.getChipId()) + "
\n"; buff += "\n"; buff += "\n"; buff += "

\n"; HttpServer.send(200, "text/html", buff); delay(20); GreenLedSet(!LedState); } /* Send HTTP status 404 Not Found */ void handleNotFound() { HttpServer.send(404, "text/plain", "404: Not found"); } /* Read button on GPIO0*/ void GetButton(void) { /* short press butoon to change state of relay */ if (digitalRead(BUTTONPIN) == false ) ++ButtonCount; if (digitalRead(BUTTONPIN) == true && ButtonCount > 1 && ButtonCount < 12 ) { RelaySet(!RelayState); // change relay } /* long press button restart */ if (ButtonCount > 12) { GreenLedSet(!LedState); ButtonTick.detach(); // Stop Tickers /* Wait for release button */ while (!digitalRead(BUTTONPIN))yield(); delay(100); ESP.restart(); } if (digitalRead(BUTTONPIN) == true ) ButtonCount = 0; ButtonFlag = false; } /* change state of relay */ void ModifySendPage(void) { if (WWWAUTHENTI == true) { /* request for www user/password from client */ if (!HttpServer.authenticate(WWWUSERNAME, WWWPASSWORD)) return HttpServer.requestAuthentication(); } if (HttpServer.arg("R1ON") == "ON")RelaySet(true); if (HttpServer.arg("R1OFF") == "OFF")RelaySet(false); SendPage(); } /* set relay */ void RelaySet(bool SetRelayState) { if (SetRelayState == true) { OnButt = BUTTONON; OffButt = BUTTONNOACT; } if (SetRelayState == false) { OnButt = BUTTONNOACT; OffButt = BUTTONOFF; } RelayState = SetRelayState; digitalWrite(RELAYPIN, RelayState); GreenLedSet(!SetRelayState); } /* set green LED */ void GreenLedSet(bool SetLedState) { LedState = SetLedState; // set green LED digitalWrite(LEDPIN, LedState); } void ButtonFlagSet(void) { ButtonFlag = true; }