/* --------------------- CONFIG ---------------------------------- */ /* Adapt this sketch to your needs by modifying the config_device.h*/ /* --------------------- GPIO ------------------------------------ */ /* Generic GPIO Control by HTTP REST interface */ /* Modify GPIO by accessing DEVICE_IP/gpio?gpio=[GPIO]&value=[0|1] */ /* -------------------- SETUP ------------------------------------ */ /* 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 and a mqtt server */ /* In this mode, device will be available at 192.168.4.1 */ /* --------------------- OTA ------------------------------------- */ /* 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 to save some place for the sketch to upload */ /* Use espota.py to upload OTA */ /* After passing in OTA mode, next boot will be in setup mode */ /* --------------------- BMP180 -----------------------------------*/ /* if BMP180 is available temperature will be published by mqtt */ /* and on web server interface */ /* --------------------- MQTT ------------------------------------ */ /* Send information to mqtt server configured in the setup mode */ /* GPIO value configured in config_device.h can be get by */ /* subscribing to /feeds/[HOSTNAME]/gpio/[GPIO] and modified by */ /* publishing to /feeds/[HOSTNAME]/gpio/[GPIO]/set */ /* BMP180 will be published to /feeds/[HOSTNAME]/temperature and */ /* /feeds/[HOSTNAME]/pressure */ #include #include #include #include #include #include #include #include "config.h" #include "debug_sketch.h" #include "BMP180.h" #include "Adafruit_MQTT.h" #include "Adafruit_MQTT_Client.h" #define CONFIG_EEPROM_SIZE 256 char eeprom[CONFIG_EEPROM_SIZE]; #define BOOTMODE_SETUP 0 #define BOOTMODE_NORMAL 1 #define BOOTMODE_OTA 2 double temp, pressure; uint8_t mode; char *hostName = ""; /* Set these to your desired credentials. */ const char *ssid = CONFIG_SSID_NAME; ESP8266WebServer server(80); /* WebServer decl*/ void WebHandleRoot(); void WebHandleSetup(); void WebHandleGpio(); void WebHandleSave(); void WebHandleOTA(); void WebHandleNotFound(); void WebSetupServer(int bootmode); /* EEPROM decl */ int EepromSaveConfig(uint8_t bootMode, String ssid, String password, String host, String mqttServer, String mqttUser, String mqttpasswd, int mqttPort); int EepromSaveBootMode(uint8_t bootMode); void EepromReadConfig(uint8_t &bootMode, char **ssid, char **password, char **host, char **mqttServer, char **mqttUser, char **mqttPasswd, int &mqttPort); /* MQTT decl */ int MqttConnect(); int MqttIsConnected(); int MqttSetup(char *server, char *user, char *passwd, int port, char * hostname); int MqttPublish(double temp, double pressure); void MqttCheckSubscription(); void MqttChangeGpioValue(int gpio, int value); void WifiSetup(int bootmode, int forceSetup, char *confSsid, char *confPassword, char *confHost) { IPAddress myIP; if (bootmode == BOOTMODE_SETUP || forceSetup) { SKETCH_DEBUG_PRINTLN("Configuring access point..."); /* You can set a password to the AP here */ WiFi.softAP(ssid); myIP = WiFi.softAPIP(); } else { SKETCH_DEBUG_PRINTLN("Connecting to Wifi..."); WiFi.begin(confSsid, confPassword); while (WiFi.status() != WL_CONNECTED) { delay(500); SKETCH_DEBUG_PRINT("."); } SKETCH_DEBUG_PRINTLN(""); SKETCH_DEBUG_PRINTLN("WiFi connected"); if (!MDNS.begin(confHost)) { SKETCH_DEBUG_PRINTLN("Error setting up MDNS responder!"); while (1) { delay(1000); } } SKETCH_DEBUG_PRINTLN("mDNS responder started"); myIP = WiFi.localIP(); } SKETCH_DEBUG_PRINT("My IP address: "); SKETCH_DEBUG_PRINTLN(myIP); } void OTASetup() { // 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 EepromSaveBootMode(BOOTMODE_SETUP); ArduinoOTA.onStart([]() { SKETCH_DEBUG_PRINTLN("Start"); }); ArduinoOTA.onEnd([]() { SKETCH_DEBUG_PRINTLN("\nEnd"); }); ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) { SKETCH_DEBUG_PRINTF("Progress: %u%%\r", (progress / (total / 100))); }); ArduinoOTA.onError([](ota_error_t error) { SKETCH_DEBUG_PRINTF("Error[%u]: ", error); if (error == OTA_AUTH_ERROR){ SKETCH_DEBUG_PRINTLN("Auth Failed");} else if (error == OTA_BEGIN_ERROR){ SKETCH_DEBUG_PRINTLN("Begin Failed");} else if (error == OTA_CONNECT_ERROR){ SKETCH_DEBUG_PRINTLN("Connect Failed");} else if (error == OTA_RECEIVE_ERROR){ SKETCH_DEBUG_PRINTLN("Receive Failed");} else if (error == OTA_END_ERROR){ SKETCH_DEBUG_PRINTLN("End Failed");} }); ArduinoOTA.begin(); SKETCH_DEBUG_PRINTLN("Ready"); SKETCH_DEBUG_PRINT("IP address: "); SKETCH_DEBUG_PRINTLN(WiFi.localIP()); SKETCH_DEBUG_PRINT("Free Space: "); SKETCH_DEBUG_PRINTLN(ESP.getFreeSketchSpace()); } void setup() { pinMode(3, OUTPUT); char *confSsid; char *confPassword; char *confHost; char *mqttServer; char *mqttUser; char *mqttPasswd; int mqttPort; delay(1000); SKETCH_DEBUG_INIT(115200); SKETCH_DEBUG_PRINTLN(); // Get GPIO 3 Status Serial.swap(); //Switch Serial on GPIO 13 & 15 pinMode(3, INPUT_PULLUP); int txStatus = digitalRead(3); #ifndef CONFIG_ENABLE_EXTRA_GPIO Serial.swap(); // Switch back on GPIO 1 & 3 #endif EEPROM.begin(CONFIG_EEPROM_SIZE); EepromReadConfig(mode, &confSsid, &confPassword, &confHost, &mqttServer, &mqttUser, &mqttPasswd, mqttPort); hostName = confHost; if (mode == BOOTMODE_NORMAL || mode == BOOTMODE_OTA) { SKETCH_DEBUG_PRINTLN("Configuration Found !:"); SKETCH_DEBUG_PRINTLN(mode); SKETCH_DEBUG_PRINTLN(confSsid); SKETCH_DEBUG_PRINTLN(confPassword); SKETCH_DEBUG_PRINTLN(confHost); SKETCH_DEBUG_PRINTLN(mqttServer); SKETCH_DEBUG_PRINTLN(mqttUser); SKETCH_DEBUG_PRINTLN(mqttPasswd); SKETCH_DEBUG_PRINTLN(mqttPort); SKETCH_DEBUG_PRINTLN(); } else { SKETCH_DEBUG_PRINTLN("No configuration saved"); } SKETCH_DEBUG_PRINT("Force Setup Mode ? :"); SKETCH_DEBUG_PRINT(txStatus ? "No" : "Yes"); SKETCH_DEBUG_PRINTLN(); WifiSetup(mode, txStatus == 0, confSsid, confPassword, confHost); MqttSetup(mqttServer, mqttUser, mqttPasswd, mqttPort, confHost); if (mode == BOOTMODE_OTA) { OTASetup(); } else { if (BMP180Setup(CONFIG_BMP180_SDA, CONFIG_BMP180_SCL)) SKETCH_DEBUG_PRINTLN("BMP180 init success"); WebSetupServer(mode); } } uint nbCycle = 0; void loop() { if (mode == BOOTMODE_OTA) { ArduinoOTA.handle(); } else { server.handleClient(); MqttCheckSubscription(); delay(CONFIG_WEB_DELAY_MS); nbCycle++; if (nbCycle > CONFIG_SAMPLING_PERIODE_MS / CONFIG_WEB_DELAY_MS) { if (BMP180IsConnected() && BMP180GetTempAndPressure(temp, pressure) == 0) { SKETCH_DEBUG_PRINT("Current T°C "); SKETCH_DEBUG_PRINT(temp); SKETCH_DEBUG_PRINT( " Pressure mB "); SKETCH_DEBUG_PRINTLN(pressure); MqttPublish(temp, pressure); } else { SKETCH_DEBUG_PRINTLN("Cannot get T°C"); } nbCycle = 0; } } }