diff --git a/WifiControlSensor/BMP180.ino b/WifiControlSensor/BMP180.ino new file mode 100644 index 0000000..abe3ea0 --- /dev/null +++ b/WifiControlSensor/BMP180.ino @@ -0,0 +1,16 @@ +int getTemperature(double &t) { + char status; + status = pressure.startTemperature(); + if (status != 0) + { + // Wait for the measurement to complete: + delay(status); + status = pressure.getTemperature(t); + if (status != 0) + return 0; + else + return -1; + } else { + return -1; + } +} diff --git a/WifiControlSensor/EEPROM.ino b/WifiControlSensor/EEPROM.ino new file mode 100644 index 0000000..24b21ad --- /dev/null +++ b/WifiControlSensor/EEPROM.ino @@ -0,0 +1,75 @@ +/* EEPROM LAYOUT + "BOOTMODE;SSID;PASSWORD;HOSTNAME;" + BOOTMODE could be 0 for Setup, 1 for normal use, 2 for OTA + Setup mode is trigger by setting GPIO3 to ground or at first boot +*/ + + +int saveConfig(int bootMode, String ssid, String password, String host ) { + String eeprom; + + eeprom = String(bootMode) + ";" + ssid + ";" + password + ";" + host + ";"; + + if (eeprom.length() > EEPROM_SIZE ) + return -EMSGSIZE; + + Serial.println("Saving " + eeprom); + + for (int i = 0; i < eeprom.length() && i < EEPROM_SIZE; i++) { + EEPROM.write(i, eeprom.charAt(i)); + } + + EEPROM.commit(); + delay(100); + + return 0; +} + +int saveBootMode(int bootMode){ + EEPROM.write(0,String(bootMode).charAt(0)); + EEPROM.commit(); + delay(100); + return 0; +} + +void readEEPROM(int &bootMode, char **ssid, char **password, char **host) { + + int i = 2; + + int boot = EEPROM.read(0); + + if (boot == '1') { + bootMode = BOOTMODE_NORMAL; + } else if (boot == '2') { + bootMode = BOOTMODE_OTA; + } else { + //Do not need to parse EEPROM when not configured + bootMode = BOOTMODE_SETUP; + return; + } + + //Read SSID + *ssid = &eeprom[2]; + do { + eeprom[i] = EEPROM.read(i); + i++; + } while (i < EEPROM_SIZE && eeprom[i - 1] != ';'); + eeprom[i - 1] = '\0'; + + //Read password + *password = &eeprom[i]; + do { + eeprom[i] = EEPROM.read(i); + i++; + } while (i < EEPROM_SIZE && eeprom[i - 1] != ';'); + eeprom[i - 1] = '\0'; + + //Read HostName + *host = &eeprom[i]; + do { + eeprom[i] = EEPROM.read(i); + i++; + } while (i < EEPROM_SIZE && eeprom[i - 1] != ';'); + eeprom[i - 1] = '\0'; + +} diff --git a/WifiControlSensor/WebServer.ino b/WifiControlSensor/WebServer.ino new file mode 100644 index 0000000..9c8fbb2 --- /dev/null +++ b/WifiControlSensor/WebServer.ino @@ -0,0 +1,84 @@ +void handleRoot() { + server.send(200, "text/html", "

You are connected


" + "Setup
" + "OTA mode
" + "ON
" + "OFF
" + ); +} + +void handleSetup() { + server.send(200, "text/html", "
" + "
" + "
" + "
" + "
" + "
"); +} + +void handleGpio() { + if (!server.hasArg("gpio") || !server.hasArg("value")) { + server.send(500, "text/plain", "Bad arguments\r\n"); + return; + } + + pinMode(server.arg("gpio").toInt(), OUTPUT); + digitalWrite(server.arg("gpio").toInt(), server.arg("value").toInt()); + server.send(200, "text/html", "

GPIO" + server.arg("gpio") + " changed to " + server.arg("value") + "

"); +} + +void handleSave() { + String password; + String ssid; + String hostName; + + if (!server.hasArg("ssid") || !server.hasArg("password") || !server.hasArg("host")) { + server.send(500, "text/plain", "Bad arguments\r\n"); + return; + } + + if (saveConfig(BOOTMODE_NORMAL, server.arg("ssid"), server.arg("password"), server.arg("host")) < 0) { + server.send(500, "text/plain", "Cannot Save Credentials (Too long ?Contains \";\"?)\r\n"); + return; + } + + server.send(200, "text/html", "

Configuration Saved


" + "You can reboot now"); +} + +void handleOTA() { + Serial.println("Boot mode Set to OTA"); + saveBootMode(BOOTMODE_OTA); + server.send(200, "text/html", "

OTA Mode set


" + "You can reboot now"); +} + +void handleNotFound() { + String message = "File Not Found\n\n"; + message += "URI: "; + message += server.uri(); + message += "\nMethod: "; + message += (server.method() == HTTP_GET) ? "GET" : "POST"; + message += "\nArguments: "; + message += server.args(); + message += "\n"; + for (uint8_t i = 0; i < server.args(); i++) { + message += " " + server.argName(i) + ": " + server.arg(i) + "\n"; + } + server.send(404, "text/plain", message); +} + +void setupWebServer(int bootmode) { + server.on("/", handleRoot); + server.on("/setup", handleSetup); + server.on("/save", handleSave); + if (bootmode == BOOTMODE_NORMAL){ + server.on("/gpio", handleGpio); + server.on("/otamode", handleOTA); + } + server.onNotFound(handleNotFound); + server.begin(); + Serial.println("HTTP server started"); +} + + diff --git a/WifiControlSensor/WifiControlSensor.ino b/WifiControlSensor/WifiControlSensor.ino new file mode 100644 index 0000000..b8c83d1 --- /dev/null +++ b/WifiControlSensor/WifiControlSensor.ino @@ -0,0 +1,203 @@ +/* Generic GPIO Control by HTTP REST interface */ +/* Modify GPIO by accessing DEVICE_IP/gpio?gpio=[GPIO]&value=[0|1] */ +/* At first boot it creates a WiFi access point */ +/* and provide a web server on it, so you can configure Wifi ssid */ +/* Wifi passwd, and a mDNS hostname */ +/* In this mode, device will be available at 192.168.4.1 */ +/* Device can also be put in OTA Mode: In this case, if you have */ +/* a little flash (512K), it better to disable SPIFFS in */ +/* "Flash Size" Menu. Use espota.py to upload OTA */ +/* After passing in OTA mode, next boot will be in setup mode */ + +/* To Use GPIO 3 And 1, uncomment #define ENABLE_EXTRA_GPIO */ +/* but Serial will be available on GPIO 15 and 13 */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +//#define ENABLE_EXTRA_GPIO + +#define EEPROM_SIZE 512 +char eeprom[EEPROM_SIZE]; + +#define WEB_DELAY_MS 100 +#define SAMPLING_PERIODE_MS 5000 + +/* I2C pin used*/ +#define SDA 2 +#define SCL 14 + +#define BOOTMODE_SETUP 0 +#define BOOTMODE_NORMAL 1 +#define BOOTMODE_OTA 2 + +int mode; + +/* Set these to your desired credentials. */ +const char *ssid = "ESPConfigurator"; + +ESP8266WebServer server(80); +SFE_BMP180 pressure; + +/* WebServer decl*/ +void handleRoot(); +void handleSetup(); +void handleGpio(); +void handleSave(); +void handleOTA(); +void handleNotFound(); +void setupWebServer(int bootmode); + +/* EEPROM decl */ +int saveConfig(int bootMode, String ssid, String password, String host ); +int saveBootMode(int bootMode); +void readEEPROM(int &bootMode, char **ssid, char **password, char **host); + +/* BMP180 decl */ +int getTemperature(double &t); + +void setupWifi(int bootmode, int forceSetup, char *confSsid, char *confPassword, char *confHost) { + IPAddress myIP; + if (bootmode == BOOTMODE_SETUP || forceSetup) { + Serial.println("Configuring access point..."); + /* You can set a password to the AP here */ + WiFi.softAP(ssid); + myIP = WiFi.softAPIP(); + } else { + Serial.println("Connecting to Wifi..."); + WiFi.begin(confSsid, confPassword); + while (WiFi.status() != WL_CONNECTED) { + delay(500); + Serial.print("."); + } + Serial.println(""); + Serial.println("WiFi connected"); + + if (!MDNS.begin(confHost)) { + Serial.println("Error setting up MDNS responder!"); + while (1) { + delay(1000); + } + } + Serial.println("mDNS responder started"); + myIP = WiFi.localIP(); + } + + Serial.print("My IP address: "); + Serial.println(myIP); +} + +void setupOTA() { + // Port defaults to 8266 + // ArduinoOTA.setPort(8266); + + // Hostname defaults to esp8266-[ChipID] + // ArduinoOTA.setHostname("myesp8266"); + + // No authentication by default + // ArduinoOTA.setPassword((const char *)"123"); + + //Disable OTA mode to avoid forever loop + //Force BOOTMODE_SETUP in case eeprom layout have changed + saveConfig(BOOTMODE_SETUP, "", "", "" ); + + 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(); + Serial.println("Ready"); + Serial.print("IP address: "); + Serial.println(WiFi.localIP()); + Serial.print("Free Space: "); + Serial.println(ESP.getFreeSketchSpace()); +} + +void setup() { + pinMode(3, OUTPUT); + + char *confSsid; + char *confPassword; + char *confHost; + + delay(1000); + Serial.begin(115200); + Serial.println(); + + // Get GPIO 3 Status + Serial.swap(); //Switch Serial on GPIO 13 & 15 + pinMode(3, INPUT_PULLUP); + int txStatus = digitalRead(3); +#ifndef ENABLE_EXTRA_GPIO + Serial.swap(); // Switch back on GPIO 1 & 3 +#endif + + EEPROM.begin(EEPROM_SIZE); + readEEPROM(mode, &confSsid, &confPassword, &confHost); + if (mode == BOOTMODE_NORMAL || mode == BOOTMODE_OTA) { + Serial.println("Configuration Found !:"); + Serial.println(mode); + Serial.println(confSsid); + Serial.println(confPassword); + Serial.println(confHost); + Serial.println(); + } else { + Serial.println("No configuration saved"); + } + + Serial.print("Force Setup Mode ? :"); + Serial.print(txStatus?"No":"Yes"); + Serial.println(); + + setupWifi(mode, txStatus == 0, confSsid, confPassword, confHost); + + if (mode == BOOTMODE_OTA) { + setupOTA(); + } else { + if (pressure.begin(SDA, SCL)) + Serial.println("BMP180 init success"); + setupWebServer(mode); + } +} + +uint nbCycle = 0; +double temp; +void loop() { + if (mode == BOOTMODE_OTA) { + ArduinoOTA.handle(); + } else { + server.handleClient(); + delay(WEB_DELAY_MS); + nbCycle++; + if (nbCycle > SAMPLING_PERIODE_MS/WEB_DELAY_MS){ + if(getTemperature(temp) == 0){ + Serial.print("Sampling :"); + Serial.println(temp); + }else{ + Serial.println("Cannot get T°C"); + } + nbCycle = 0; + } + } +}