feat(firmware): integrate WiFiManager for improved WiFi configuration and connection handling

This commit is contained in:
2025-11-24 23:21:18 +08:00
parent d583370c6d
commit 6014114098
3 changed files with 174 additions and 101 deletions

View File

@@ -17,5 +17,6 @@ lib_deps =
matth-x/MicroOcppMongoose@^1.2.0 matth-x/MicroOcppMongoose@^1.2.0
roboticsbrno/SmartLeds@^3.1.5 roboticsbrno/SmartLeds@^3.1.5
miguelbalboa/MFRC522@^1.4.12 miguelbalboa/MFRC522@^1.4.12
tzapu/WiFiManager@^2.0.17
build_flags = -DMO_PLATFORM=MO_PLATFORM_ARDUINO -DMO_MG_USE_VERSION=MO_MG_V715 -DMO_NUMCONNECTORS=3 build_flags = -DMO_PLATFORM=MO_PLATFORM_ARDUINO -DMO_MG_USE_VERSION=MO_MG_V715 -DMO_NUMCONNECTORS=3
board_build.partitions = partitions.csv board_build.partitions = partitions.csv

View File

@@ -1,9 +1,8 @@
#define CFG_WIFI_SSID "MisakaNetwork"
#define CFG_WIFI_PASS "20211028"
#define CFG_WIFI_MAXIMUM_RETRY 5 #define CFG_WIFI_MAXIMUM_RETRY 5
#define CFG_OCPP_BACKEND "ws://192.168.1.100:8180/steve/websocket/CentralSystemService" #define CFG_OCPP_BACKEND "ws://csms.helios.bh8.ga:8180/steve/websocket/CentralSystemService"
#define CFG_CP_IDENTIFIER "CQWU_HHB_0001" #define CFG_CP_IDENTIFIER "CQWU_HHB_0001"
#define CFG_CB_SERIAL "REDAone_prototype00" #define CFG_CB_SERIAL "REDAone_prototype00"
#define CFG_CP_FW_VERSION "1.0.0"
#define CFG_CP_MODAL "Helios DA One" #define CFG_CP_MODAL "Helios DA One"
#define CFG_CP_VENDOR "RayineElec" #define CFG_CP_VENDOR "RayineElec"
#define CFG_AUTHORIZATIONKEY "my_secret_key" #define CFG_AUTHORIZATIONKEY "my_secret_key"

View File

@@ -1,5 +1,5 @@
#include <Arduino.h> #include <Arduino.h>
#include <WiFi.h> #include <WiFiManager.h>
#include <string.h> #include <string.h>
#include <MicroOcpp.h> #include <MicroOcpp.h>
@@ -10,7 +10,6 @@
#include <MFRC522.h> #include <MFRC522.h>
#include "esp_system.h" #include "esp_system.h"
#include "smartconfig.h"
#include "config.h" #include "config.h"
/* LED State Enum */ /* LED State Enum */
@@ -22,8 +21,6 @@ enum LEDState
LED_ERROR // Red - Error state LED_ERROR // Red - Error state
}; };
/* FreeRTOS event group to signal when we are connected*/
static volatile bool s_wifi_connected = false;
static int s_retry_num = 0; static int s_retry_num = 0;
static volatile bool s_ocpp_connected = false; static volatile bool s_ocpp_connected = false;
static volatile LEDState s_led_state = LED_INITIALIZING; static volatile LEDState s_led_state = LED_INITIALIZING;
@@ -35,7 +32,6 @@ uint8_t mac[6];
char cpSerial[13]; char cpSerial[13];
struct mg_mgr mgr; struct mg_mgr mgr;
// MicroOcpp::MOcppMongooseClient *client = nullptr;
/** /**
* WS2812B LED Pin * WS2812B LED Pin
@@ -47,44 +43,6 @@ struct mg_mgr mgr;
SmartLed leds(LED_WS2812B, LED_COUNT, LED_PIN, 0, DoubleBuffer); SmartLed leds(LED_WS2812B, LED_COUNT, LED_PIN, 0, DoubleBuffer);
// WiFi event handler
static void WiFiEvent(WiFiEvent_t event)
{
switch (event)
{
case ARDUINO_EVENT_WIFI_STA_START:
Serial.println("WiFi STA started");
s_led_state = LED_INITIALIZING;
break;
case ARDUINO_EVENT_WIFI_STA_DISCONNECTED:
if (s_retry_num < CFG_WIFI_MAXIMUM_RETRY)
{
s_retry_num++;
Serial.println("Retry to connect to the AP");
s_led_state = LED_INITIALIZING;
}
else
{
s_wifi_connected = false;
Serial.println("Failed to connect to AP");
s_led_state = LED_ERROR;
}
break;
case ARDUINO_EVENT_WIFI_STA_CONNECTED:
Serial.println("WiFi connected");
Serial.printf("- Hostname: %s\n", WiFi.getHostname());
break;
case ARDUINO_EVENT_WIFI_STA_GOT_IP:
Serial.println("Got IP: " + WiFi.localIP().toString());
s_retry_num = 0;
s_wifi_connected = true;
s_led_state = LED_WIFI_CONNECTED;
break;
default:
break;
}
}
/* LED Control Functions */ /* LED Control Functions */
void updateLED() void updateLED()
{ {
@@ -152,73 +110,188 @@ void setup()
s_blink_last_time = 0; s_blink_last_time = 0;
s_blink_on = false; s_blink_on = false;
// Initialize WiFi leds[0] = Rgb{255, 255, 0};
// WiFi.onEvent(WiFiEvent); leds.show();
// WiFi.mode(WIFI_STA);
// WiFi.setHostname((CFG_CP_MODAL + String("_") + String(cpSerial).substring(String(cpSerial).length() - 6)).c_str());
// WiFi.begin(CFG_WIFI_SSID, CFG_WIFI_PASS);
// Wait for WiFi connection with LED updates WiFiManager wm;
// int retry = 0; const char *customHeadElement = R"rawliteral(
// while (WiFi.status() != WL_CONNECTED && retry < 20) <style>
// { :root {
// delay(200); font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
// updateLED(); // Update LED while waiting for WiFi color: #1f2a37;
// Serial.print("."); --primarycolor: #2563eb;
// retry++; }
// }
// Serial.println();
if (!connectToSavedWiFi()) body,
body.invert {
margin: 0;
background: #f4f6fb;
min-height: 100vh;
display: flex;
justify-content: center;
align-items: center;
padding: 16px;
color: #1f2a37;
}
.wrap {
width: min(360px, 100%);
background: #fff;
border-radius: 16px;
padding: 24px;
box-shadow: 0 8px 24px rgba(15, 23, 42, 0.12);
text-align: left;
}
h1,
h2,
h3,
h4 {
color: #111827;
margin-top: 0;
text-align: center;
}
label {
display: block;
margin-bottom: 6px;
font-weight: 600;
}
input,
select,
button {
border-radius: 10px;
width: 100%;
font-size: 1rem;
box-sizing: border-box;
}
input[type="text"],
input[type="password"],
input[type="number"],
input[type="email"],
select {
padding: 12px;
margin: 0 0 16px 0;
border: 1px solid #d0d7e2;
background: #f9fafc;
transition: border 0.2s, box-shadow 0.2s, background 0.2s;
}
input:focus,
select:focus {
outline: none;
border-color: #2563eb;
background: #fff;
box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.15);
}
button,
input[type="submit"],
button.D {
padding: 12px;
border: none;
background: #2563eb;
color: #fff;
font-weight: 600;
cursor: pointer;
transition: background 0.2s, transform 0.1s;
}
button.D {
background: #dc2626;
}
button:hover,
input[type="submit"]:hover {
background: #1d4ed8;
}
button:active,
input[type="submit"]:active {
transform: scale(0.99);
}
.msg {
border-radius: 12px;
border: 1px solid #e5e7eb;
background: #f9fafb;
padding: 16px;
color: #374151;
}
.msg.P {
border-color: #2563eb;
background: rgba(37, 99, 235, 0.08);
color: #1f2a37;
}
.msg.S {
border-color: #16a34a;
background: rgba(22, 163, 74, 0.08);
}
.msg.D {
border-color: #dc2626;
background: rgba(220, 38, 38, 0.08);
}
.q {
display: none;
}
a {
color: #2563eb;
font-weight: 600;
}
hr {
border: none;
height: 1px;
background: #e5e7eb;
margin: 24px 0;
}
</style>
)rawliteral";
wm.setCustomHeadElement(customHeadElement);
bool autoConnectRet = wm.autoConnect((String("HLCP_") + String(cpSerial).substring(String(cpSerial).length() - 6)).c_str(), cpSerial);
if (!autoConnectRet)
{ {
String ssidPrefix = CFG_CP_MODAL + String("_") + String(cpSerial).substring(String(cpSerial).length() - 6); Serial.println("Failed to connect and hit timeout");
char ssidPrefixBuffer[32]; s_led_state = LED_ERROR;
strcpy(ssidPrefixBuffer, ssidPrefix.c_str());
startSmartConfig(ssidPrefixBuffer, cpSerial);
} }
else
{
Serial.println("WiFi connected successfully");
s_led_state = LED_WIFI_CONNECTED;
mg_mgr_init(&mgr); mg_mgr_init(&mgr);
MicroOcpp::MOcppMongooseClient *client = new MicroOcpp::MOcppMongooseClient(&mgr, CFG_OCPP_BACKEND, CFG_CP_IDENTIFIER, CFG_AUTHORIZATIONKEY, "", MicroOcpp::makeDefaultFilesystemAdapter(MicroOcpp::FilesystemOpt::Use_Mount_FormatOnFail), MicroOcpp::ProtocolVersion(1, 6));
MicroOcpp::MOcppMongooseClient *client = new MicroOcpp::MOcppMongooseClient(&mgr, CFG_OCPP_BACKEND, CFG_CP_IDENTIFIER, CFG_AUTHORIZATIONKEY, "", MicroOcpp::makeDefaultFilesystemAdapter(MicroOcpp::FilesystemOpt::Use_Mount_FormatOnFail), MicroOcpp::ProtocolVersion(1, 6)); mocpp_initialize(*client, ChargerCredentials(CFG_CP_MODAL, CFG_CP_VENDOR, CFG_CP_FW_VERSION, cpSerial, nullptr, nullptr, CFG_CB_SERIAL, nullptr, nullptr), MicroOcpp::makeDefaultFilesystemAdapter(MicroOcpp::FilesystemOpt::Use_Mount_FormatOnFail));
mocpp_initialize(*client, ChargerCredentials(CFG_CP_MODAL, CFG_CP_VENDOR, "1.0.0", cpSerial, nullptr, nullptr, CFG_CB_SERIAL, nullptr, nullptr), MicroOcpp::makeDefaultFilesystemAdapter(MicroOcpp::FilesystemOpt::Use_Mount_FormatOnFail)); }
} }
void loop() void loop()
{ {
if (!smartconfig_done)
{
dnsServer.processNextRequest();
server.handleClient();
}
if (should_reboot)
{
Serial.println("Rebooting...");
delay(1000);
ESP.restart();
}
mg_mgr_poll(&mgr, 10); mg_mgr_poll(&mgr, 10);
mocpp_loop(); mocpp_loop();
// Check OCPP connection status auto ctx = getOcppContext();
// if (s_wifi_connected) if (ctx && ctx->getConnection().isConnected())
// { {
// auto ctx = getOcppContext(); if (s_led_state != LED_OCPP_CONNECTED)
// if (ctx && ctx->getConnection().isConnected()) {
// { s_led_state = LED_OCPP_CONNECTED;
// if (s_led_state != LED_OCPP_CONNECTED) }
// { }
// s_led_state = LED_OCPP_CONNECTED; else
// } {
// } if (s_led_state != LED_WIFI_CONNECTED)
// else {
// { s_led_state = LED_WIFI_CONNECTED;
// if (s_led_state != LED_WIFI_CONNECTED) }
// { }
// s_led_state = LED_WIFI_CONNECTED;
// }
// }
// }
updateLED(); updateLED();