niveau_cuve.ino
El sensor ToF montado sobre un depósito convierte la distancia en porcentaje de llenado: altura constante, resta y umbral de aviso en el LED verde. Medición de nivel sin contacto, sin flotador ni piezas en contacto con el líquido.
Hardware
Una Arduino Nicla Vision (STM32H7 M7+M4, 23×23 mm) con cámara GC2145, IMU LSM6DSOX, micrófono PDM, ToF (VL53Lx), módulo ESP32 Wi-Fi/BLE y LED RGB (LEDR/G/B). La placa fijada a la tapa, ventana ToF hacia abajo; depósito de altura conocida (600 mm aquí). Ojo con líquidos muy claros o espumosos que engañan al infrarrojo.
Cableado
Sin cableado para el ToF embarcado. Alimentar la placa de forma estable (USB o 3,3 V) y evitar el sol directo sobre la ventana del sensor.
Funcionamiento
La medida continua da la distancia sensor/superficie en mm; llenado = 100 − (vacío × 100 / altura). Los límites 20-1000 mm rechazan lecturas fuera de rango del ToF.
Ejecución
Programación desde Arduino IDE (core ArduinoCore-mbed) por USB-C; librerías Camera, PDM, LSM6DSOX, WiFiNINA y ArduinoBLE.
Variantes
Calibrar la altura inicializando con el depósito vacío, promediar 10 medidas para líquidos agitados o teleleer el nivel por BLE/Wi-Fi a un cuadro de mando.
niveau_cuve.ino
// Niveau de cuve par ToF : distance capteur → surface = vide.
// Cuve de HAUTEUR constante : remplissage = 100 - vide%.
#include <Wire.h>
#include <VL53L1X.h>
VL53L1X tof;
#define HAUTEUR_CUVE_MM 600 // 60 cm de fond à capteur
void setup() {
Serial.begin(115200);
Wire.begin();
tof.setTimeout(500);
if (!tof.init()) {
Serial.println("ToF absent");
while (1) { ; }
}
tof.startContinuous();
}
void loop() {
uint16_t mm = tof.readRangeContinuousMillimeters();
if (!tof.timeoutOccurred() && mm > 20 && mm < 1000) {
int remplissage = 100 - (mm * 100 / HAUTEUR_CUVE_MM);
if (remplissage < 0) remplissage = 0;
if (remplissage > 100) remplissage = 100;
Serial.print("vide="); Serial.print(mm);
Serial.print(" mm -> niveau ");
Serial.print(remplissage);
Serial.println(" %");
if (remplissage < 15) {
digitalWrite(LEDG, HIGH); // alerte niveau bas (LEDG = 24)
} else {
digitalWrite(LEDG, LOW);
}
}
delay(500);
}