Firmware v3.3 + calibration tool v3 : debug BLE, timeline tirs, minSensors
Firmware (xiao_airsoft_pro.ino) : - Persistance config en flash (InternalFileSystem / LittleFS) - Mode debug activable via BLE : octet fixe offset 28 du payload config - minSensors par défaut : 2 → 3 (exige les 3 capteurs simultanément) - Toutes les fenêtres trigger à 60ms (> DEBUG_RATE 50ms) Calibration tool (xiao_calibration_tool.py) : - Scan BLE par nom automatique (30s), connexion directe si adresse fournie - Config + debug FULL envoyés automatiquement à la connexion - NUM0 : cycle debug OFF/RAW/TRIGGERS/FULL - NUM6/4 : ajustement minSensors 1-3 en temps réel - 4ème graphique : timeline des tirs détectés (barres oranges) - Layout 4 sous-graphiques avec height_ratios=[3,3,3,1] Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -16,7 +16,9 @@
|
||||
#define LED_BLUE 13
|
||||
|
||||
// ====== FLASH ======
|
||||
#define FLASH_STORAGE_START 0x7F000
|
||||
#define FLASH_STORAGE_START 0x7F000 // Pairing MAC
|
||||
#define FLASH_CONFIG_START 0x7E000 // ShotConfig persistée
|
||||
#define CONFIG_MAGIC_NUMBER 0xDEADBEEF
|
||||
|
||||
// ====== ENUMS (déclarés en premier) ======
|
||||
enum LedState {
|
||||
@@ -168,10 +170,10 @@ void initDefaultConfig() {
|
||||
shotConfig.accelThreshold = 2.5f;
|
||||
shotConfig.gyroThreshold = 200.0f;
|
||||
shotConfig.audioThreshold = 3000; // Seuil PDM (0-32767)
|
||||
shotConfig.accelWindow = 20;
|
||||
shotConfig.gyroWindow = 20;
|
||||
shotConfig.audioWindow = 15;
|
||||
shotConfig.minSensors = 2;
|
||||
shotConfig.accelWindow = 60; // augmenté pour visibilité debug (>DEBUG_RATE 50ms)
|
||||
shotConfig.gyroWindow = 60; // augmenté pour visibilité debug (>DEBUG_RATE 50ms)
|
||||
shotConfig.audioWindow = 60; // augmenté pour visibilité debug (>DEBUG_RATE 50ms)
|
||||
shotConfig.minSensors = 3;
|
||||
shotConfig.shotCooldown = 80;
|
||||
shotConfig.useAccel = true;
|
||||
shotConfig.useGyro = true;
|
||||
@@ -235,6 +237,44 @@ bool isAuthorized(const char* mac) {
|
||||
return (strcmp(pairing.authorizedMAC, mac) == 0);
|
||||
}
|
||||
|
||||
// ════════════════════════════════════════════════
|
||||
// CONFIG FLASH (page 0x7E000)
|
||||
// ════════════════════════════════════════════════
|
||||
struct StoredConfig {
|
||||
uint32_t magic;
|
||||
ShotConfig config;
|
||||
uint8_t reserved[28]; // padding pour aligner sur 4 bytes
|
||||
};
|
||||
|
||||
void saveConfigToFlash() {
|
||||
StoredConfig sc;
|
||||
sc.magic = CONFIG_MAGIC_NUMBER;
|
||||
memcpy(&sc.config, &shotConfig, sizeof(ShotConfig));
|
||||
memset(sc.reserved, 0xFF, sizeof(sc.reserved));
|
||||
|
||||
NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Een; while(NRF_NVMC->READY==NVMC_READY_READY_Busy){}
|
||||
NRF_NVMC->ERASEPAGE = FLASH_CONFIG_START; while(NRF_NVMC->READY==NVMC_READY_READY_Busy){}
|
||||
NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Wen; while(NRF_NVMC->READY==NVMC_READY_READY_Busy){}
|
||||
uint32_t* src = (uint32_t*)≻
|
||||
uint32_t* dst = (uint32_t*)FLASH_CONFIG_START;
|
||||
for (int i = 0; i < (int)(sizeof(StoredConfig)/4); i++) {
|
||||
dst[i] = src[i]; while(NRF_NVMC->READY==NVMC_READY_READY_Busy){}
|
||||
}
|
||||
NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren; while(NRF_NVMC->READY==NVMC_READY_READY_Busy){}
|
||||
Serial.println("💾 Config sauvegardée en flash");
|
||||
}
|
||||
|
||||
void loadConfigFromFlash() {
|
||||
StoredConfig* sc = (StoredConfig*)FLASH_CONFIG_START;
|
||||
if (sc->magic == CONFIG_MAGIC_NUMBER) {
|
||||
memcpy(&shotConfig, &sc->config, sizeof(ShotConfig));
|
||||
Serial.println("📂 Config chargée depuis flash");
|
||||
} else {
|
||||
Serial.println("📂 Pas de config flash → valeurs par défaut");
|
||||
initDefaultConfig();
|
||||
}
|
||||
}
|
||||
|
||||
// ════════════════════════════════════════════════
|
||||
// CALLBACKS BLE
|
||||
// ════════════════════════════════════════════════
|
||||
@@ -263,6 +303,21 @@ void onConfigWrite(BLEDevice central, BLECharacteristic c) {
|
||||
if (len >= (int)sizeof(ShotConfig)) {
|
||||
memcpy(&shotConfig, data, sizeof(ShotConfig));
|
||||
Serial.println("⚙️ Config reçue"); printConfig();
|
||||
saveConfigToFlash();
|
||||
}
|
||||
// Octet optionnel : debug mode à l'offset fixe 28 (si != 0xFF)
|
||||
// Offset fixe 28 = après toute ShotConfig + padding, dans le zone de padding 32 bytes
|
||||
const int debugByteIdx = 28;
|
||||
if (len > debugByteIdx && data[debugByteIdx] != 0xFF) {
|
||||
uint8_t dm = data[debugByteIdx] & 0x03; // 0-3
|
||||
debugMode = (DebugMode)dm;
|
||||
Serial.print("🐛 Debug BLE → ");
|
||||
switch(debugMode){
|
||||
case DEBUG_OFF: Serial.println("OFF"); break;
|
||||
case DEBUG_RAW: Serial.println("RAW"); break;
|
||||
case DEBUG_TRIGGERS: Serial.println("TRIGGERS"); break;
|
||||
case DEBUG_FULL: Serial.println("FULL"); break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -405,7 +460,7 @@ void setup() {
|
||||
pinMode(LED_BLUE, OUTPUT);
|
||||
changeLedState(LED_BOOT);
|
||||
|
||||
initDefaultConfig();
|
||||
loadConfigFromFlash(); // charge depuis flash ou valeurs par défaut
|
||||
loadPairingData();
|
||||
|
||||
// IMU
|
||||
|
||||
Reference in New Issue
Block a user