← Contadores persistentes con NVS Preferences en PLC ESP32
Piso móvil hidráulico (app BLE)ESP32 PLC 38RNVSDatalogging
Contadores persistentes con NVS Preferences en PLC ESP32 — ejemplo completo
Guarda contadores de ciclos, números de serie y totales en la flash NVS del ESP32 para que sobrevivan a reinicios. Ejemplo con Preferences para el PLC 38R.
Programa completo y ejecutable para el ESP32 PLC 38R (nvs-persistent-counters-38r.ino): incluye cabecera de conexionado, requisitos y notas de integración.
Descarga el pack completo del proyecto — gratisEste ejemplo + los relacionados + lista de materiales
Vista de solo lectura.
/*
* COMPLETE EXAMPLE — Persistent counters in non-volatile memory (Preferences)
*
* Hardware: ESP32 PLC 38R (Industrial Shields)
* Based on: hydraulic moving floor project, AppLink.cpp (NVS)
*
* Wiring:
* I0_0 "Load cycle" push button (simulates end of load)
* I0_1 "Unload cycle" push button (simulates end of unload)
*
* Logic:
* - Serial number, load / unload / lifetime counters, oil volume and
* activation flag are stored in NVS ("nvdata" partition).
* - They survive reboots, power outages and OTA reflashes.
* - Writes are deferred (dirty flag + minimum interval) to avoid
* wearing out the flash on every pulse.
*
* Integration with other catalog modules:
* - The counters are reported to the app over BLE as [C1]loads [C2]unloads
* (see ejemplos/piso-movil/ble-mobile-app-control-38r.ino).
* - The oil volume is computed with the pulse flow meter
* (see ejemplos/piso-movil/pulse-flow-meter-38r.ino).
*/
#include
#define BTN_LOAD I0_0
#define BTN_UNLOAD I0_1
// NVS keys (max. 15 characters)
#define KEY_SERIAL "serial_num"
#define KEY_LOADS "cnt_load"
#define KEY_UNLOADS "cnt_unload"
#define KEY_LIFE "cnt_life"
#define KEY_OIL "oil_volume"
#define KEY_ACTIVE "activated"
#define SAVE_INTERVAL_MS 5000 // minimum time between flash writes
Preferences prefs;
String serialNum;
int counterLoad = 0;
int counterUnload = 0;
int counterLife = 0; // total machine cycles
float oilVolume = 0.0; // liters of oil moved
bool activated = false;
bool dirty = false; // there is data pending to be saved
uint32_t lastSaveMs = 0;
void loadNVS() {
prefs.begin("nvdata", true); // read-only
serialNum = prefs.getString(KEY_SERIAL, "SN-0000");
counterLoad = prefs.getInt(KEY_LOADS, 0);
counterUnload = prefs.getInt(KEY_UNLOADS, 0);
counterLife = prefs.getInt(KEY_LIFE, 0);
oilVolume = prefs.getFloat(KEY_OIL, 0.0);
activated = prefs.getBool(KEY_ACTIVE, false);
prefs.end();
}
void saveNVS() {
prefs.begin("nvdata", false); // read/write
prefs.putInt(KEY_LOADS, counterLoad);
prefs.putInt(KEY_UNLOADS, counterUnload);
prefs.putInt(KEY_LIFE, counterLife);
prefs.putFloat(KEY_OIL, oilVolume);
prefs.putBool(KEY_ACTIVE, activated);
prefs.end();
dirty = false;
lastSaveMs = millis();
Serial.println("-> NVS saved");
}
void setup() {
Serial.begin(115200);
pinMode(BTN_LOAD, INPUT);
pinMode(BTN_UNLOAD, INPUT);
loadNVS(); // the counters come back exactly as they were after every reboot
Serial.println("=== Persistent counters (NVS) ===");
Serial.println("Serial: " + serialNum);
Serial.println("Loads: " + String(counterLoad));
Serial.println("Unloads: " + String(counterUnload));
Serial.println("Lifetime: " + String(counterLife));
Serial.println("Oil: " + String(oilVolume, 1) + " L");
Serial.println("Activated: " + String(activated ? "yes" : "no"));
}
void loop() {
// Rising edge with simple debounce
static bool prevLoad = false, prevUnload = false;
bool load = digitalRead(BTN_LOAD);
bool unload = digitalRead(BTN_UNLOAD);
if (load && !prevLoad) {
counterLoad++;
counterLife++;
oilVolume += 12.5; // estimated liters per load cycle
dirty = true;
Serial.println("Load #" + String(counterLoad));
}
if (unload && !prevUnload) {
counterUnload++;
counterLife++;
dirty = true;
Serial.println("Unload #" + String(counterUnload));
}
prevLoad = load;
prevUnload = unload;
// Deferred write: protects the flash from a write on every pulse
if (dirty && millis() - lastSaveMs > SAVE_INTERVAL_MS) {
saveNVS();
}
delay(50);
}
Descarga el pack completo del proyecto — gratisEste ejemplo + los relacionados + lista de materiales