/* 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 #include "Adafruit_MQTT.h" #include "Adafruit_MQTT_Client.h" //#define ENABLE_EXTRA_GPIO #define EEPROM_SIZE 1024 char eeprom[EEPROM_SIZE]; #define WEB_DELAY_MS 100 #define SAMPLING_PERIODE_MS 60000 /* I2C pin used*/ #define SDA 2 #define SCL 14 #define BOOTMODE_SETUP 0 #define BOOTMODE_NORMAL 1 #define BOOTMODE_OTA 2 double temp, pressure; uint8_t mode; /* Set these to your desired credentials. */ const char *ssid = "ESPConfigurator"; ESP8266WebServer server(80); SFE_BMP180 bmp180; /* WebServer decl*/ void handleRoot(); void handleSetup(); void handleGpio(); void handleSave(); void handleOTA(); void handleNotFound(); void setupWebServer(int bootmode); /* EEPROM decl */ int saveConfig(uint8_t bootMode, String ssid, String password, String host, String mqttServer, String mqttUser, String mqttpasswd, int mqttPort); int saveBootMode(uint8_t bootMode); void readEEPROM(uint8_t &bootMode, char **ssid, char **password, char **host, char **mqttServer, char **mqttUser, char **mqttPasswd, int &mqttPort); /* BMP180 decl */ int getTemperature(double &t); int getTempAndPressure(double &t, double &p); /* MQTT decl */ int MQTT_connect(); int MQTT_isConnected(); int setupMQTT(char *server, char *user, char *passwd, int port); int publishMQTT(double temp, double pressure); 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 saveBootMode(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; char *mqttServer; char *mqttUser; char *mqttPasswd; int mqttPort; 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, &mqttServer, &mqttUser, &mqttPasswd, mqttPort); 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(mqttServer); Serial.println(mqttUser); Serial.println(mqttPasswd); 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); setupMQTT(mqttServer, mqttUser, mqttPasswd, mqttPort); if (mode == BOOTMODE_OTA) { setupOTA(); } else { if (bmp180.begin(SDA, SCL)) Serial.println("BMP180 init success"); setupWebServer(mode); } } uint nbCycle = 0; 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 (getTempAndPressure(temp, pressure) == 0) { Serial.print("Current T°C "); Serial.print(temp); Serial.print( " Pressure mB "); Serial.println(pressure); publishMQTT(temp, pressure); } else { Serial.println("Cannot get T°C"); } nbCycle = 0; } } }