working version
This commit is contained in:
+9
-7
@@ -4,11 +4,12 @@
|
||||
// Flag to signal that a new reading is ready to be processed
|
||||
volatile bool newReadingAvailable = false;
|
||||
volatile int lastReadFPS = 0;
|
||||
|
||||
static NimBLEScan* pScan;
|
||||
static NimBLEClient* _pClient = nullptr;
|
||||
static ChronoBLE::ConnectionState currentState;
|
||||
static const NimBLEAdvertisedDevice* advDevice = nullptr;
|
||||
static uint32_t scanTimeMs = 5000;
|
||||
static uint32_t scanTimeMs = 1000; //5000
|
||||
static uint32_t scanTimeoutMs = 1000;
|
||||
static NimBLEUUID deviceUUID("0000180a-0000-1000-8000-00805f9b34fb");
|
||||
static NimBLEUUID serviceUUID("00001623-88EC-688C-644B-3FA706C0BB75");
|
||||
static NimBLEUUID speedCharacteristicUUID("00001624-88EC-688C-644B-3FA706C0BB75");
|
||||
@@ -58,7 +59,8 @@ class ScanCallbacks : public NimBLEScanCallbacks {
|
||||
/** Callback to process the results of the completed scan or restart it */
|
||||
void onScanEnd(const NimBLEScanResults& results, int reason) override {
|
||||
//Serial.printf("Scan Ended, reason: %d, device count: %d; Restarting scan\n", reason, results.getCount());
|
||||
NimBLEDevice::getScan()->start(scanTimeMs, false, true);
|
||||
delay(scanTimeoutMs);
|
||||
pScan->start(scanTimeMs, false, false);
|
||||
}
|
||||
} scanCallbacks;
|
||||
|
||||
@@ -94,11 +96,11 @@ ChronoBLE::ChronoBLE() {
|
||||
void ChronoBLE::init() {
|
||||
NimBLEDevice::init("FX-Chrono-Client");
|
||||
NimBLEDevice::setPower(3); /** 3dbm */
|
||||
NimBLEScan* pScan = NimBLEDevice::getScan();
|
||||
pScan = NimBLEDevice::getScan();
|
||||
pScan->setScanCallbacks(&scanCallbacks, false);
|
||||
pScan->setInterval(100);
|
||||
pScan->setWindow(100);
|
||||
pScan->setActiveScan(true);
|
||||
pScan->setWindow(99);
|
||||
pScan->setActiveScan(false);
|
||||
}
|
||||
void ChronoBLE::_setState(ConnectionState state){
|
||||
currentState=state;
|
||||
@@ -122,7 +124,7 @@ bool ChronoBLE::foundDevice(){if (advDevice!=nullptr){return true;}return false;
|
||||
void ChronoBLE::startScan(){
|
||||
Serial.println("starting scan!!!");
|
||||
_setState(SCANNING);
|
||||
NimBLEDevice::getScan()->start(scanTimeMs, false, true);
|
||||
pScan->start(scanTimeMs, false, false);
|
||||
}
|
||||
void ChronoBLE::_disconnectDevice(){
|
||||
_setState(IDLE);
|
||||
|
||||
Binary file not shown.
Binary file not shown.
+249
-17
@@ -7,9 +7,37 @@
|
||||
#include <GunProfile.h>
|
||||
#include <Update.h>
|
||||
#include "Display.h"
|
||||
#include <nvs_flash.h>
|
||||
|
||||
static const char *SSID_KEY = "wifi_ssid";
|
||||
static const char *PASSWORD_KEY = "wifi_password";
|
||||
static Preferences preferences;
|
||||
|
||||
String getWifiSsid() {
|
||||
String ssid = "";
|
||||
if (preferences.begin("wifi", true)) {
|
||||
ssid = preferences.getString(SSID_KEY, "");
|
||||
preferences.end();
|
||||
}
|
||||
return ssid;
|
||||
}
|
||||
|
||||
String getWifiPassword() {
|
||||
String password = "";
|
||||
if (preferences.begin("wifi", true)) {
|
||||
password = preferences.getString(PASSWORD_KEY, "");
|
||||
preferences.end();
|
||||
}
|
||||
return password;
|
||||
}
|
||||
|
||||
void saveWifiCredentials(const String& ssid, const String& password) {
|
||||
preferences.begin("wifi", false);
|
||||
preferences.putString(SSID_KEY, ssid);
|
||||
preferences.putString(PASSWORD_KEY, password);
|
||||
preferences.end();
|
||||
}
|
||||
|
||||
const char *ssid = "routeguy";
|
||||
const char *password = "wrangleR621!";
|
||||
WebServer _server(80);
|
||||
void (*testModeCallback)();
|
||||
|
||||
@@ -132,15 +160,81 @@ void ChronoWebServer::_handleRoot() {
|
||||
});\
|
||||
});\
|
||||
});\
|
||||
function saveWifi(){\
|
||||
const ssid = document.getElementById('wifiSsidInput').value;\
|
||||
const password = document.getElementById('wifiPasswordInput').value;\
|
||||
if (!ssid) {\
|
||||
alert('Please enter a WiFi SSID');\
|
||||
return;\
|
||||
}\
|
||||
const formData = new URLSearchParams();\
|
||||
formData.append('ssid', ssid);\
|
||||
formData.append('password', password);\
|
||||
fetch('/wifisave', {\
|
||||
method: 'POST',\
|
||||
body: formData\
|
||||
})\
|
||||
.then(response => response.text())\
|
||||
.then(data => {\
|
||||
console.log(data);\
|
||||
alert('WiFi settings saved! Device will restart to connect.');\
|
||||
window.location.href = '/';\
|
||||
})\
|
||||
.catch(error => console.error('Error:', error));\
|
||||
}\
|
||||
function clearWifi(){\
|
||||
if(confirm('Clear saved WiFi credentials? Device will start its own AP after reboot.')){\
|
||||
fetch('/clearwifi', {\
|
||||
method: 'POST',\
|
||||
body: new URLSearchParams()\
|
||||
})\
|
||||
.then(response => response.text())\
|
||||
.then(data => {\
|
||||
console.log(data);\
|
||||
alert('WiFi credentials cleared. Device will restart.');\
|
||||
})\
|
||||
.catch(error => console.error('Error:', error));\
|
||||
}\
|
||||
}\
|
||||
fetch('/version').then(r=>r.json()).then(v=>{document.getElementById('currentVersion').textContent=v.version}).catch(()=>{});\
|
||||
fetch('/wifi').then(r=>r.text()).then(ssid=>{document.getElementById('wifiSsid').textContent=ssid || 'Not configured'}).catch(()=>{});\
|
||||
fetch('/wifimode').then(r=>r.text()).then(mode=>{\
|
||||
const modeEl = document.getElementById('wifiMode');\
|
||||
if (mode === 'AP') {\
|
||||
modeEl.textContent = 'Access Point (AP) Mode';\
|
||||
document.getElementById('wifiFormContainer').style.display = 'block';\
|
||||
} else if (mode === 'STA') {\
|
||||
modeEl.textContent = 'Station (STA) Mode - Connected to WiFi';\
|
||||
document.getElementById('wifiFormContainer').style.display = 'block';\
|
||||
} else {\
|
||||
modeEl.textContent = 'Unknown Mode';\
|
||||
}\
|
||||
}).catch(()=>{});\
|
||||
</script>\
|
||||
<h1>ChronoDisplay Settings</h1>\
|
||||
<div style='margin-top:50px; position:relative;'>\
|
||||
<h3>Control Panel</h3>\
|
||||
<button onclick='exportData()'>Export</button>\
|
||||
<button onclick='reset()'>Reset</button>\
|
||||
<button onclick='format()'>Format</button>\
|
||||
<button onclick='exportData()'>Export Data</button>\
|
||||
<button onclick='reset()'>Reset Data</button>\
|
||||
<button onclick='format()'>Delete Profiles</button>\
|
||||
<button onclick='toggleTestMode()'>Toggle Test Mode</button>\
|
||||
</div>\
|
||||
<div style='margin-top:20px; padding: 10px; border: 1px solid #999;'>\
|
||||
<h3>WiFi Configuration</h3>\
|
||||
<p style='font-size: 12px; color: #666;'>Mode: <strong id='wifiMode'>Unknown</strong></p>\
|
||||
<p style='font-size: 12px; color: #666;'>Current WiFi: <strong id='wifiSsid'>Not configured</strong></p>\
|
||||
<div id='wifiFormContainer' style='margin-top: 10px;'>\
|
||||
<form id='wifiForm'>\
|
||||
<label for='wifiSsidInput'>SSID:</label><br/>\
|
||||
<input type='text' id='wifiSsidInput' style='width: 200px; margin-bottom: 10px;'></input><br/>\
|
||||
<label for='wifiPasswordInput'>Password:</label><br/>\
|
||||
<input type='password' id='wifiPasswordInput' style='width: 200px; margin-bottom: 10px;'></input><br/>\
|
||||
<button type='button' onclick='saveWifi()' style='margin-top: 5px; padding: 8px 16px; background-color: #2196F3; color: white; border: none; border-radius: 4px; cursor: pointer;'>Save WiFi</button>\
|
||||
</form>\
|
||||
<p style='font-size: 12px; color: #666;'>After saving, the device will attempt to connect to the new WiFi network.</p>\
|
||||
<button type='button' onclick='clearWifi()' style='margin-top: 10px; padding: 8px 16px; background-color: #f44336; color: white; border: none; border-radius: 4px; cursor: pointer;'>Clear WiFi Credentials</button>\
|
||||
</div>\
|
||||
</div>\
|
||||
<div style='margin-top:20px; padding: 10px; border: 1px solid #999;'>\
|
||||
<h3>OTA Firmware Update</h3>\
|
||||
<p style='font-size: 12px; color: #666;'>Current Version: <strong id='currentVersion'>Unknown</strong></p>\
|
||||
@@ -508,21 +602,107 @@ void handleOtaUpdateEnd() {
|
||||
ESP.restart();
|
||||
}
|
||||
}
|
||||
void ChronoWebServer::init(){
|
||||
WiFi.mode(WIFI_STA);
|
||||
WiFi.begin(ssid, password);
|
||||
while (WiFi.status() != WL_CONNECTED) {
|
||||
delay(500);
|
||||
Serial.print(".");
|
||||
}
|
||||
Serial.println("");
|
||||
Serial.print("Connected to ");
|
||||
void setupSoftAp(const char* ssid, const char* password) {
|
||||
|
||||
WiFi.mode(WIFI_AP);
|
||||
IPAddress local_ip(192, 168, 4, 1);
|
||||
IPAddress gateway(192, 168, 4, 1);
|
||||
IPAddress subnet(255, 255, 255, 0);
|
||||
|
||||
WiFi.softAPConfig(local_ip, gateway, subnet);
|
||||
delay(100);
|
||||
|
||||
WiFi.softAP(ssid, password);//, password);
|
||||
delay(100);
|
||||
|
||||
Serial.print("AP started: ");
|
||||
Serial.println(ssid);
|
||||
Serial.print("IP address: ");
|
||||
Serial.println(WiFi.localIP());
|
||||
Serial.println(WiFi.softAPIP());
|
||||
}
|
||||
|
||||
if (MDNS.begin("esp32")) {
|
||||
Serial.println("MDNS responder started");
|
||||
bool attemptStaConnection(const String& ssid, const String& password, int timeoutMs) {
|
||||
WiFi.mode(WIFI_STA);
|
||||
WiFi.begin(ssid.c_str(), password.c_str());
|
||||
|
||||
int attempts = 0;
|
||||
int maxAttempts = timeoutMs / 500;
|
||||
|
||||
while (WiFi.status() != WL_CONNECTED && attempts < maxAttempts) {
|
||||
delay(500);
|
||||
Serial.print(".");
|
||||
attempts++;
|
||||
}
|
||||
|
||||
return WiFi.status() == WL_CONNECTED;
|
||||
}
|
||||
|
||||
void ChronoWebServer::init(){
|
||||
// Initialize NVS flash and erase WiFi config partition
|
||||
esp_err_t err = nvs_flash_init();
|
||||
if (err == ESP_ERR_NVS_NO_FREE_PAGES || err == ESP_ERR_NVS_NEW_VERSION_FOUND) {
|
||||
Serial.println("NVS partition was truncated, erasing...");
|
||||
ESP_ERROR_CHECK(nvs_flash_erase());
|
||||
err = nvs_flash_init();
|
||||
}
|
||||
ESP_ERROR_CHECK(err);
|
||||
|
||||
// Erase WiFi storage in NVS
|
||||
nvs_handle_t handle;
|
||||
err = nvs_open("storage", NVS_READWRITE, &handle);
|
||||
if (err == ESP_OK) {
|
||||
nvs_erase_all(handle);
|
||||
nvs_commit(handle);
|
||||
nvs_close(handle);
|
||||
Serial.println("WiFi NVS storage erased");
|
||||
} else {
|
||||
Serial.println("No WiFi NVS storage to erase");
|
||||
}
|
||||
|
||||
WiFi.disconnect(true, true);
|
||||
WiFi.mode(WIFI_OFF);
|
||||
delay(100);
|
||||
|
||||
// Try to load saved WiFi credentials
|
||||
String savedSsid = getWifiSsid();
|
||||
String savedPassword = getWifiPassword();
|
||||
|
||||
Serial.print("Saved SSID from Preferences: '");
|
||||
Serial.print(savedSsid);
|
||||
Serial.println("'");
|
||||
Serial.print("Saved Password length: ");
|
||||
Serial.println(savedPassword.length());
|
||||
|
||||
bool connected = false;
|
||||
|
||||
if (savedSsid.length() > 0) {
|
||||
Serial.print("Attempting to connect to saved WiFi: ");
|
||||
Serial.println(savedSsid);
|
||||
connected = attemptStaConnection(savedSsid, savedPassword, 7000);
|
||||
|
||||
if (connected) {
|
||||
Serial.println("");
|
||||
Serial.print("Connected to ");
|
||||
Serial.println(savedSsid);
|
||||
Serial.print("IP address: ");
|
||||
Serial.println(WiFi.localIP());
|
||||
} else {
|
||||
Serial.println("");
|
||||
Serial.println("Failed to connect to saved WiFi - starting AP mode");
|
||||
WiFi.disconnect(true, true);
|
||||
WiFi.mode(WIFI_OFF);
|
||||
delay(100);
|
||||
}
|
||||
} else {
|
||||
Serial.println("No saved WiFi credentials - starting AP mode");
|
||||
}
|
||||
|
||||
if (!connected) {
|
||||
setupSoftAp("ChronoDisplay", "12345678");
|
||||
|
||||
if (MDNS.begin("esp32")) {
|
||||
Serial.println("MDNS responder started");
|
||||
}
|
||||
}
|
||||
|
||||
_server.on("/gunprofile/add", _handleAddGunProfile);
|
||||
@@ -538,9 +718,14 @@ void ChronoWebServer::init(){
|
||||
_server.on("/format", _handleFormat);
|
||||
_server.on("/testmode", _handleTestMode);
|
||||
_server.on("/ota", HTTP_POST, [](){handleOtaUpdateEnd();}, [](){handleOtaUpdate();});
|
||||
_server.on("/wifi", HTTP_GET, _handleWifi);
|
||||
_server.on("/wifisave", HTTP_POST, _handleWifiSave);
|
||||
_server.on("/clearwifi", HTTP_POST, _handleClearWifi);
|
||||
_server.on("/wifimode", HTTP_GET, _handleWifiMode);
|
||||
_server.on("/version", HTTP_GET, _handleVersion);
|
||||
_server.on("/", _handleRoot);
|
||||
_server.begin();
|
||||
|
||||
}
|
||||
|
||||
void ChronoWebServer::process(){
|
||||
@@ -550,4 +735,51 @@ void ChronoWebServer::process(){
|
||||
void ChronoWebServer::_handleVersion() {
|
||||
String versionJson = String("{\"version\":\"") + CHRONO_VERSION + "\",\"major\":" + String(CHRONO_VERSION_MAJOR) + ",\"minor\":" + String(CHRONO_VERSION_MINOR) + ",\"patch\":" + String(CHRONO_VERSION_PATCH) + "}";
|
||||
_server.send(200, "application/json", versionJson);
|
||||
}
|
||||
|
||||
void ChronoWebServer::_handleWifi() {
|
||||
String ssid = getWifiSsid();
|
||||
_server.send(200, "text/plain", ssid);
|
||||
}
|
||||
|
||||
void ChronoWebServer::_handleWifiSave() {
|
||||
if (_server.method() == HTTP_POST) {
|
||||
String ssid = "";
|
||||
String password = "";
|
||||
if (_server.hasArg("ssid")) {
|
||||
ssid = _server.arg("ssid");
|
||||
}
|
||||
if (_server.hasArg("password")) {
|
||||
password = _server.arg("password");
|
||||
}
|
||||
saveWifiCredentials(ssid, password);
|
||||
_server.send(200, "text/html", "ok");
|
||||
delay(1000);
|
||||
ESP.restart();
|
||||
}
|
||||
}
|
||||
|
||||
void ChronoWebServer::_handleClearWifi() {
|
||||
if (_server.method() == HTTP_POST) {
|
||||
preferences.begin("wifi", false);
|
||||
preferences.clear();
|
||||
preferences.end();
|
||||
_server.send(200, "text/html", "ok");
|
||||
delay(1000);
|
||||
ESP.restart();
|
||||
}
|
||||
}
|
||||
|
||||
void ChronoWebServer::_handleWifiMode() {
|
||||
String mode;
|
||||
if (WiFi.getMode() == WIFI_STA) {
|
||||
mode = "STA";
|
||||
} else if (WiFi.getMode() == WIFI_AP) {
|
||||
mode = "AP";
|
||||
} else if (WiFi.getMode() == WIFI_AP_STA) {
|
||||
mode = "AP+STA";
|
||||
} else {
|
||||
mode = "NONE";
|
||||
}
|
||||
_server.send(200, "text/plain", mode);
|
||||
}
|
||||
@@ -6,6 +6,7 @@
|
||||
#include <NetworkClient.h>
|
||||
#include <ESPmDNS.h>
|
||||
#include <Update.h>
|
||||
#include <Preferences.h>
|
||||
#include <ChronoBLE.h>
|
||||
#include <GunProfile.h>
|
||||
#include "ChronoVersion.h"
|
||||
@@ -36,6 +37,10 @@ class ChronoWebServer {
|
||||
static void _handleTestMode();
|
||||
static void _handleOta();
|
||||
static void _handleVersion();
|
||||
static void _handleWifi();
|
||||
static void _handleWifiSave();
|
||||
static void _handleClearWifi();
|
||||
static void _handleWifiMode();
|
||||
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user