OTA & NVS — mise à jour par le Wi-Fi et réglages persistants#
← Protocoles · Programme · Matrices LED →
Preferences : réglages persistants#
La flash de l'ESP32 contient une partition NVS (non-volatile storage) : un petit stockage clé → valeur qui survit aux redémarrages et aux nouveaux uploads. Idéal pour un seuil calibré, un nom d'appareil, un compteur, des identifiants Wi-Fi.
#include <Arduino.h>
#include <Preferences.h>
Preferences prefs; // stockage clé → valeur dans la flash (NVS), conservé hors tension
void setup() {
Serial.begin(115200);
delay(1000);
prefs.begin("settings", false); // espace de noms "settings", lecture/écriture
uint32_t bootCount = prefs.getUInt("boot", 0) + 1; // 0 = valeur par défaut si la clé n'existe pas
prefs.putUInt("boot", bootCount);
int threshold = prefs.getInt("threshold", 2000);
Serial.printf("Démarrage n°%u, seuil enregistré : %d\n", bootCount, threshold);
Serial.println("Tapez un nombre dans le moniteur série pour changer le seuil.");
}
void loop() {
if (Serial.available()) {
int threshold = Serial.parseInt();
prefs.putInt("threshold", threshold); // n'écrit que si la valeur change (la flash s'use)
Serial.printf("Seuil enregistré : %d (gardé après redémarrage)\n", threshold);
}
}
- Types :
putInt/getInt,putFloat,putBool,putString,putBytes(unestructentière)… - Clés : 15 caractères maximum. Un espace de noms (
"settings") regroupe des clés, comme un dossier. - La flash supporte environ 100 000 écritures par secteur : n'écrivez pas à chaque tour de
loop(), seulement quand la valeur change. prefs.clear()efface l'espace de noms ;pio run -t eraseefface toute la flash.
OTA : envoyer un programme par le Wi-Fi#
Plus besoin de câble pour mettre à jour une carte cachée dans une installation : le nouveau programme arrive par le réseau, s'écrit dans la deuxième partition d'application, puis la carte redémarre dessus. La partition default.csv prévoit déjà les deux emplacements (2 × 1,25 Mo).
#include <Arduino.h>
#include <WiFi.h>
#include <ArduinoOTA.h>
const char* SSID = "MySSID";
const char* PASS = "Enjmin666";
void setup() {
Serial.begin(115200);
WiFi.mode(WIFI_STA);
WiFi.begin(SSID, PASS);
while (WiFi.status() != WL_CONNECTED) delay(100);
ArduinoOTA.setHostname("enjmin-01"); // → enjmin-01.local (mDNS inclus)
ArduinoOTA.setPassword("enjmin"); // évite qu'un voisin flashe votre carte
ArduinoOTA.onStart([]() { Serial.println("Mise à jour OTA…"); });
ArduinoOTA.onProgress([](unsigned int done, unsigned int total) {
Serial.printf("%u %%\r", done * 100 / total);
});
ArduinoOTA.onEnd([]() { Serial.println("\nTerminé, redémarrage"); });
ArduinoOTA.onError([](ota_error_t e) { Serial.printf("Erreur OTA %u\n", e); });
ArduinoOTA.begin();
Serial.printf("Prêt pour l'OTA : %s\n", WiFi.localIP().toString().c_str());
}
void loop() {
ArduinoOTA.handle(); // à appeler régulièrement
// … le reste du programme (sans longs delay())
}
Premier envoi par le câble, puis les suivants par le Wi-Fi avec l'environnement ota du platformio.ini :
[env:ota]
extends = env:usb-jtag
upload_protocol = espota
upload_port = enjmin-01.local ; ou l'adresse IP de la carte
upload_flags = --auth=enjmin ; le mot de passe de setPassword()
pio run -e ota -t upload
- Chaque nouveau programme doit contenir le code OTA : sinon, la carte n'acceptera plus de mise à jour par le Wi-Fi (il faudra revenir au câble).
- L'ordinateur et la carte doivent être sur le même réseau, et le pare-feu de l'ordinateur doit laisser passer la connexion de retour.
- Sans câble, plus de moniteur série : pour suivre ce qui se passe, envoyez vos logs par le réseau (OSC, WebSocket).