/* --------------------- 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/MQTTUSER/[HOSTNAME]/gpio/[GPIO] and */ /* modified by publishin to */ /* /feeds/MQTTUSER/[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 "utils.h" #include "debug_sketch.h" #include "BMP180.h" #include "sensor_DHT.h" #include "dry_sensor.h" #include "MQTT.h" #include "Adafruit_MQTT.h" #include "Adafruit_MQTT_Client.h" #include "EEPROM.h" extern "C" { #include } #define BOOTMODE_SETUP 0 #define BOOTMODE_NORMAL 1 #define BOOTMODE_OTA 2 double temp, pressure; float dhtTemp, dhtHumidity; int dryness; uint8_t mode; const 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); void WifiSetup(int bootmode, char *confSsid, char *confPassword, char *confHost, int ip_config, uint32_t ip, uint32_t gw, uint32_t mask, uint32_t dns, uint32_t dns2) { IPAddress myIP; if (bootmode == BOOTMODE_SETUP) { SKETCH_DEBUG_PRINT("Configuring access point..."); SKETCH_DEBUG_PRINTLN(ssid); /* You can set a password to the AP here */ WiFi.softAP(ssid); myIP = WiFi.softAPIP(); } else { SKETCH_DEBUG_PRINTLN("Disable previous AP mode "); WiFi.softAPdisconnect(true); SKETCH_DEBUG_PRINTLN("Connecting to Wifi..."); if(ip_config == 1){ SKETCH_DEBUG_PRINTLN("Use static ip configuration"); WiFi.config(IPAddress(ip), IPAddress(gw), IPAddress(mask), IPAddress(dns), IPAddress(dns2)); } WiFi.begin(confSsid, confPassword); while (WiFi.status() != WL_CONNECTED) { delay(500); SKETCH_DEBUG_PRINT("."); } SKETCH_DEBUG_PRINTLN(""); SKETCH_DEBUG_PRINTLN("WiFi connected"); #ifdef CONFIG_ENABLE_MDNS if (!MDNS.begin(confHost)) { SKETCH_DEBUG_PRINTLN("Error setting up MDNS responder!"); while (1) { delay(1000); } } SKETCH_DEBUG_PRINTLN("mDNS responder started"); #endif 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%%\n", (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 ; int ip_mode = 0; uint32_t ip = 0; uint32_t gw = 0; uint32_t mask = 0; uint32_t dns = 0; uint32_t dns2 = 0; delay(1000); SKETCH_DEBUG_INIT(115200); SKETCH_DEBUG_PRINTLN(); // Get GPIO 3 Status Serial.swap(); //Switch Serial on GPIO 13 & 15 pinMode(CONFIG_SETUP_GPIO, INPUT_PULLUP); int txStatus = digitalRead(CONFIG_SETUP_GPIO); #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, ip_mode, ip, gw, mask, dns, dns2); 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(); if(txStatus == 0){ mode = BOOTMODE_SETUP; } WifiSetup(mode, confSsid, confPassword, confHost, ip_mode, ip, gw, mask, dns, dns2); if (mode == BOOTMODE_NORMAL) { MqttSetup(mqttServer, mqttUser, mqttPasswd, mqttPort, confHost); MqttIPPublish(WiFi.localIP().toString()); } if (mode == BOOTMODE_OTA) { OTASetup(); } else { if (!BMP180Setup(CONFIG_BMP180_SDA, CONFIG_BMP180_SCL)){ SKETCH_DEBUG_PRINTLN("BMP180 init success"); } if (!DHTSetup(CONFIG_DHT_PIN)){ SKETCH_DEBUG_PRINTLN("DHT init success"); } if (!DrySetup(CONFIG_DRY_POWER_PIN)){ SKETCH_DEBUG_PRINTLN("DRY init success"); } WebSetupServer(mode); } #ifdef CONFIG_ENABLE_POWER_SAVE wifi_set_sleep_type(LIGHT_SLEEP_T); #endif } uint nbCycle = CONFIG_SAMPLING_PERIODE_MS / CONFIG_WEB_DELAY_MS; 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 (!BMP180GetTempAndPressure(temp, pressure)) { SKETCH_DEBUG_PRINT("Current T°C "); SKETCH_DEBUG_PRINT(temp); SKETCH_DEBUG_PRINT(" Pressure mB "); SKETCH_DEBUG_PRINTLN(pressure); MqttPublish(temp, pressure); } if (!DHTGetTempAndHumidity(dhtTemp, dhtHumidity)) { SKETCH_DEBUG_PRINT("Current T°C "); SKETCH_DEBUG_PRINT(dhtTemp); SKETCH_DEBUG_PRINT(" Humidity "); SKETCH_DEBUG_PRINTLN(dhtHumidity); MqttDhtPublish(dhtTemp, dhtHumidity); } if (!DryGetMeasure(dryness)){ SKETCH_DEBUG_PRINT("Current dryness "); SKETCH_DEBUG_PRINT((dryness*100)/1024); SKETCH_DEBUG_PRINTLN("%"); MqttDryPublish(dryness); } nbCycle = 0; } } }