mirror of
https://github.com/SlimeVR/SlimeVR-Tracker-ESP.git
synced 2026-04-06 02:01:57 +02:00
Implement ESP-Now based wifi provisioning
This commit is contained in:
@@ -52,7 +52,7 @@ build_flags =
|
||||
|
||||
build_unflags = -Os -std=gnu++11 -std=gnu++17
|
||||
|
||||
; If you want to enable OTA Updates, uncomment and set OTA password here and in credentials.h
|
||||
; If you want to enable OTA Updates, uncomment and set OTA password here and in credentials.cpp
|
||||
; You can set upload_port to device's ip after it's set up for the first time
|
||||
; Use the same password in SlimeVR Server to let it OTA Update the device
|
||||
;upload_protocol = espota
|
||||
|
||||
@@ -1,4 +1,24 @@
|
||||
#pragma once
|
||||
/* SlimeVR Code is placed under the MIT license
|
||||
Copyright (c) 2025 Gorbit99 & SlimeVR Contributors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
// The OTA password is public, server should know it for OTA updates,
|
||||
// and devices don't have any authentication anyway.
|
||||
@@ -7,6 +27,7 @@
|
||||
// firmware. We don't have any hardware buttons for the user to confirm
|
||||
// OTA update, so this is the best way we have.
|
||||
// OTA is allowed only for the first 60 seconds after device startup.
|
||||
|
||||
const char* otaPassword
|
||||
= "SlimeVR-OTA"; // YOUR OTA PASSWORD HERE, LEAVE EMPTY TO DISABLE OTA UPDATES
|
||||
|
||||
|
||||
@@ -52,6 +52,8 @@ bool WiFiNetwork::isConnected() const {
|
||||
|
||||
void WiFiNetwork::setWiFiCredentials(const char* SSID, const char* pass) {
|
||||
wifiProvisioning.stopSearchForProvider();
|
||||
wifiProvisioning.stopProvisioning();
|
||||
WiFi.persistent(true);
|
||||
tryConnecting(false, SSID, pass);
|
||||
retriedOnG = false;
|
||||
// Reset state, will get back into provisioning if can't connect
|
||||
@@ -65,7 +67,7 @@ void WiFiNetwork::setUp() {
|
||||
// Don't need to save the already saved credentials or the hardcoded ones
|
||||
WiFi.persistent(false);
|
||||
wifiHandlerLogger.info("Setting up WiFi");
|
||||
WiFi.mode(WIFI_STA);
|
||||
WiFi.mode(WIFI_AP_STA);
|
||||
WiFi.hostname("SlimeVR FBT Tracker");
|
||||
wifiHandlerLogger.info(
|
||||
"Loaded credentials for SSID '%s' and pass length %d",
|
||||
@@ -201,26 +203,8 @@ void WiFiNetwork::upkeep() {
|
||||
return;
|
||||
case WiFiReconnectionStatus::Failed: // Couldn't connect with second set of
|
||||
// credentials or server credentials
|
||||
// Return to the default PHY Mode N.
|
||||
#if ESP8266
|
||||
if constexpr (USE_ATTENUATION) {
|
||||
WiFi.setOutputPower(20.0 - ATTENUATION_N);
|
||||
}
|
||||
WiFi.setPhyMode(WIFI_PHY_MODE_11N);
|
||||
#endif
|
||||
// Start smart config
|
||||
if (!hadWifi && !WiFi.smartConfigDone()
|
||||
&& millis() - wifiConnectionTimeout
|
||||
>= static_cast<uint32_t>(WiFiTimeoutSeconds * 1000)) {
|
||||
if (WiFi.status() != WL_IDLE_STATUS) {
|
||||
wifiHandlerLogger.error(
|
||||
"Can't connect from any credentials, error: %d, reason: %s.",
|
||||
static_cast<int>(statusToFailure(WiFi.status())),
|
||||
statusToReasonString(WiFi.status())
|
||||
);
|
||||
wifiConnectionTimeout = millis();
|
||||
}
|
||||
wifiProvisioning.startProvisioning();
|
||||
if (startedProvisioning) {
|
||||
return;
|
||||
}
|
||||
wifiHandlerLogger.error(
|
||||
"Can't connect from any credentials, error: %d, reason: %s.",
|
||||
@@ -229,6 +213,7 @@ void WiFiNetwork::upkeep() {
|
||||
);
|
||||
wifiHandlerLogger.info("Starting wifi provisioning");
|
||||
wifiProvisioning.startSearchForProvider();
|
||||
startedProvisioning = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,6 +55,7 @@ public:
|
||||
void setWiFiCredentials(const char* SSID, const char* pass);
|
||||
static IPAddress getAddress();
|
||||
WiFiReconnectionStatus getWiFiState();
|
||||
bool startedProvisioning = false;
|
||||
|
||||
private:
|
||||
static constexpr float WiFiTimeoutSeconds = 11;
|
||||
|
||||
@@ -21,11 +21,11 @@
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "DirectSPIInterface.h"
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <PinInterface.h>
|
||||
|
||||
#include "DirectSPIInterface.h"
|
||||
|
||||
namespace SlimeVR {
|
||||
|
||||
DirectSPIInterface::DirectSPIInterface(SPIClass& spiClass, SPISettings spiSettings)
|
||||
@@ -51,4 +51,6 @@ void DirectSPIInterface::endTransaction(PinInterface* csPin) {
|
||||
|
||||
const SPISettings& DirectSPIInterface::getSpiSettings() { return m_spiSettings; }
|
||||
|
||||
void WiFiProvisioning::delPeer(uint8_t* macAddress) { esp_now_del_peer(macAddress); }
|
||||
|
||||
} // namespace SlimeVR
|
||||
|
||||
@@ -23,6 +23,10 @@
|
||||
|
||||
#include "SensorInterface.h"
|
||||
|
||||
#if ESP32
|
||||
#include <esp_now.h>
|
||||
#endif
|
||||
|
||||
namespace SlimeVR {
|
||||
|
||||
EmptySensorInterface EmptySensorInterface::instance;
|
||||
|
||||
@@ -35,12 +35,12 @@
|
||||
#endif
|
||||
|
||||
#ifdef EXT_SERIAL_COMMANDS
|
||||
#define CALLBACK_SIZE 7 // Increase callback size to allow for debug commands
|
||||
#define CALLBACK_SIZE 8 // Increase callback size to allow for debug commands
|
||||
#include "i2cscan.h"
|
||||
#endif
|
||||
|
||||
#ifndef CALLBACK_SIZE
|
||||
#define CALLBACK_SIZE 6 // Default callback size
|
||||
#define CALLBACK_SIZE 7 // Default callback size
|
||||
#endif
|
||||
|
||||
namespace SerialCommands {
|
||||
@@ -470,6 +470,18 @@ void cmdScanI2C(CmdParser* parser) {
|
||||
}
|
||||
#endif
|
||||
|
||||
void cmdStart(CmdParser* parser) {
|
||||
if (parser->getParamCount() == 1) {
|
||||
logger.info("Usage:");
|
||||
logger.info(" START PROVISION: start wifi provisioning");
|
||||
return;
|
||||
}
|
||||
|
||||
if (parser->equalCmdParam(1, "PROVISION")) {
|
||||
wifiProvisioning.startProvisioning();
|
||||
}
|
||||
}
|
||||
|
||||
void setUp() {
|
||||
cmdCallbacks.addCmd("SET", &cmdSet);
|
||||
cmdCallbacks.addCmd("GET", &cmdGet);
|
||||
@@ -477,6 +489,7 @@ void setUp() {
|
||||
cmdCallbacks.addCmd("REBOOT", &cmdReboot);
|
||||
cmdCallbacks.addCmd("DELCAL", &cmdDeleteCalibration);
|
||||
cmdCallbacks.addCmd("TCAL", &cmdTemperatureCalibration);
|
||||
cmdCallbacks.addCmd("START", &cmdStart);
|
||||
#if EXT_SERIAL_COMMANDS
|
||||
cmdCallbacks.addCmd("SCANI2C", &cmdScanI2C);
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user