#include #include #include #include #include #include #include #include "Config.h" #define ENDLESS_LOOP() while(true) { delay(100); } #define BME680_UPDATE_INTERVAL 10000 // milliseconds ESP8266WiFiMulti wiFiMulti; ESP8266WebServer httpServer(80); Adafruit_BME680 bme680; unsigned long bme680LastReadingTime; unsigned long bme680ReadingDuration; String bme680_json_cache; void httpHandleIndex(void) { httpServer.send(200, F("application/json"), bme680_json_cache); } void httpHandle404(void) { httpServer.send(404, F("text/plain"), F("This is not the page you are looking for.")); } void wifi_setup(void) { Serial.println(F("Trying to connect...")); //WiFi.setHostname(F("mlmini"); bool led_on = true; for(size_t tries = 0; tries < 300; tries++) { if(wiFiMulti.run() == WL_CONNECTED) { Serial.println(F("")); Serial.println(F("WiFi connected")); Serial.println(F("IP address: ")); Serial.println(WiFi.localIP()); break; } led_on = !led_on; digitalWrite(LED_BUILTIN, led_on); delay(100); Serial.print(F(".")); } if(WiFi.status() != WL_CONNECTED) { Serial.println(F("Connection failed, setting up access point...")); IPAddress apIP(192, 168, 42, 1); WiFi.mode(WIFI_AP); WiFi.softAPConfig(apIP, apIP, IPAddress(255, 255, 255, 0)); WiFi.softAP(F("☀️🌧️🌩️"), F("How'sTheWeather?")); WiFi.enableAP(true); digitalWrite(LED_BUILTIN, false); // LED ON (active low) } else { digitalWrite(LED_BUILTIN, true); // LED OFF (active low) } } void bme680_setup(void) { if(!bme680.begin()) { Serial.println(F("Could not initialize BME680 sensor!")); ENDLESS_LOOP(); } // Set up oversampling and filter initialization bme680.setTemperatureOversampling(BME680_OS_8X); bme680.setHumidityOversampling(BME680_OS_2X); bme680.setPressureOversampling(BME680_OS_4X); bme680.setIIRFilterSize(BME680_FILTER_SIZE_3); bme680.setGasHeater(320, 150); // 320*C for 150 ms } void httpserver_setup() { httpServer.on("/", httpHandleIndex); httpServer.onNotFound(httpHandle404); httpServer.begin(); } void setup() { Serial.begin(115200); pinMode(LED_BUILTIN, OUTPUT); Serial.println(F("Hello World!")); if(!LittleFS.begin()) { Serial.println(F("LittleFS setup failed!")); ENDLESS_LOOP(); } bme680_setup(); Config::instance().load(); // Connect the WiFi network (or start an AP if that doesn't work) for (auto &net : Config::instance().getWLANList()) { Serial.print(F("Adding network ")); Serial.println(net.ssid.c_str()); wiFiMulti.addAP(net.ssid.c_str(), net.password.c_str()); } wifi_setup(); httpserver_setup(); bme680LastReadingTime = millis() + 10000; bme680ReadingDuration = 0; bme680_json_cache = F("{}"); } void update_bme680_json(void) { std::ostringstream oss; oss << "{\n"; oss << "\"temperature\": {\"value\": " << bme680.temperature << ", \"unit\": \"°C\"},\n"; oss << "\"pressure\": {\"value\": " << (bme680.pressure / 100.0) << ", \"unit\": \"hPa\"},\n"; oss << "\"humidity\": {\"value\": " << bme680.humidity << ", \"unit\": \"%rH\"},\n"; oss << "\"gas_resistance\": {\"value\": " << bme680.gas_resistance << ", \"unit\": \"Ohm\"},\n"; oss << "\"generated_at_millis\": " << millis() << "\n"; oss << "}"; bme680_json_cache = oss.str().c_str(); } void loop() { unsigned long now = millis(); if((now - bme680LastReadingTime) >= BME680_UPDATE_INTERVAL) { // Tell BME680 to begin measurement. bme680ReadingDuration = bme680.beginReading(); if (bme680ReadingDuration == 0) { Serial.println(F("Failed to begin BME680 reading :(F(")); return; } bme680LastReadingTime = now; bme680ReadingDuration -= now; // so far, the "duration" contained the absolute end time. Make it relative to the current timestamp } if((bme680ReadingDuration != 0) && ((millis() - bme680LastReadingTime) >= bme680ReadingDuration)) { if(!bme680.endReading()) { Serial.println(F("Could not finalize BME680 reading.")); } else { // reading is good update_bme680_json(); } bme680ReadingDuration = 0; } // TODO: do something else? httpServer.handleClient(); }