diff --git a/ESP32/vehicle-monitor.cpp b/ESP32/vehicle-monitor.cpp index 9d2feb5..e80e8f9 100644 --- a/ESP32/vehicle-monitor.cpp +++ b/ESP32/vehicle-monitor.cpp @@ -2,6 +2,7 @@ #include "IDECompat.h" #include +#include #include #include #include @@ -24,6 +25,11 @@ const float wheelCircumferenceMeters = wheelDiameterInches * 0.0254f * 3.1415f / int16_t batteryVoltage = -1; // in mV int16_t batteryCurrent = -1; // in mV +WiFiMulti wifiMulti; +wl_status_t wifi_STA_status = WL_NO_SHIELD; +unsigned long wifiConnexionBegin = 0; +const unsigned long retryWifiConnexionDelay = 60000; // in milliseconds + volatile bool debugLedState = true; volatile bool speedSensorState = false; @@ -81,6 +87,25 @@ float getSpeed() return speed; } +void connectWifi() +{ + wifiMulti = WiFiMulti(); + + const int numSSIDs = sizeof(wifi_STA_credentials)/sizeof(wifi_STA_credentials[0]); + if(numSSIDs > 0) + { + Serial.println("Connecting to wifi..."); + + for(int idx = 0; idx < numSSIDs; ++idx) + { + wifiMulti.addAP(wifi_STA_credentials[idx].SSID, wifi_STA_credentials[idx].password); + } + + wifiConnexionBegin = millis(); + wifiMulti.run(); + } +} + void setup() { pinMode(speedSensorPin, INPUT_PULLUP); @@ -96,17 +121,23 @@ void setup() return; } - // Connect to Wi-Fi - WiFi.begin(wifi_ssid, wifi_password); - while (WiFi.status() != WL_CONNECTED) + // Set WiFi mode to both AccessPoint and Station + WiFi.mode(WIFI_AP_STA); + + // Create the WiFi Access Point + if(wifi_AP_ssid != nullptr) { - delay(1000); - Serial.println("Connecting to Wifi..."); + Serial.println("Creating wifi access point..."); + WiFi.softAP(wifi_AP_ssid, wifi_AP_password); + + Serial.print("Wifi access point created, SSID="); + Serial.print(wifi_AP_ssid); + Serial.print(", IP="); + Serial.println(WiFi.softAPIP()); } - // Print ESP Local IP Address - Serial.print("Wifi connected, ip="); - Serial.println(WiFi.localIP()); + // Also connect as a station (if the configured remote access point is in range) + connectWifi(); server.on("/api/status", HTTP_GET, [](AsyncWebServerRequest *request){ int v = batteryVoltage; @@ -131,6 +162,45 @@ void setup() void loop() { + wl_status_t newWifiStatus = WiFi.status(); + if(newWifiStatus != wifi_STA_status) + { + if(newWifiStatus == WL_CONNECTED) + { + Serial.print("Connected to wifi ("); + Serial.print(WiFi.SSID().c_str()); + Serial.print("), ip="); + Serial.println(WiFi.localIP()); + } + else if(newWifiStatus == WL_DISCONNECTED) + { + char codeStr[16]; + sprintf(codeStr, "%d", (int)newWifiStatus); + Serial.print("Lost wifi connexion ("); + Serial.print(codeStr); + Serial.println(")"); + + connectWifi(); + } + else + { + char codeStr[16]; + sprintf(codeStr, "%d", (int)newWifiStatus); + Serial.print("Wifi state: "); + Serial.println(codeStr); + } + + wifi_STA_status = newWifiStatus; + } + + if(wifi_STA_status != WL_CONNECTED) + { + unsigned long now = millis(); + unsigned long elapsed = now > wifiConnexionBegin ? now - wifiConnexionBegin : (4294967295 - wifiConnexionBegin) + now; + if(elapsed > retryWifiConnexionDelay) + connectWifi(); + } + const int numSamples = 100; float averageV = 0.0f; diff --git a/ESP32/wifi-credentials.h.template b/ESP32/wifi-credentials.h.template index 7fe3fd9..a1b74d0 100644 --- a/ESP32/wifi-credentials.h.template +++ b/ESP32/wifi-credentials.h.template @@ -1,7 +1,22 @@ // To avoid saving your wifi credentials in the git repository, wifi-credentials.h.template is ignored by git // Copy this file and name it wifi-credentials.h -// Then edit your wifi SSID and password +// Then edit your wifi configuration -const char* wifi_ssid = "REPLACE_WITH_YOUR_SSID"; -const char* wifi_password = "REPLACE_WITH_YOUR_PASSWORD"; +struct WifiCredentials +{ + const char* SSID; + const char* password; +}; + +// Station config: for making the ESP32 connect to an existing remote access point +// You can add one or more SSID/password pairs here +// To disable station mode, add a single entry { NULL, NULL } +WifiCredentials wifi_STA_credentials[] = { + { "REPLACE_WITH_YOUR_SSID", "REPLACE_WITH_YOUR_PASSWORD" } +}; + +// Access point config: for turning the ESP32 into an access point (the ESP32 can work in both modes at the same time) +// Note that if you connect a smartphone to this AP, it will detect it has no internet access, and then won't send requests to it (which will result in a timeout). A workaround is to turn off mobile data to force the phone use the access point (but then you effectively don't have internet on the phone). A more practical setup is to create an access point on your phone, and have the ESP32 connect to it (in "station" mode) +const char* wifi_AP_ssid = "REPLACE_WITH_YOUR_SSID"; // set to NULL to disable access point mode +const char* wifi_AP_password = "REPLACE_WITH_YOUR_PASSWORD"; // set to NULL for an open access point (not recommended)