Maquette avec capteur à ultrasons pour mesure la hauteur de la cuve à eau. Utilisation d’un capteur HC-SR04 (un standard dans cette application), un Raspberry Pico W et Thonny pour l’éditeur MicroPython
Le but : mettre à dispo une page web accessible sur l’intranet local pour connaitre la hauteur vide dans la cuve (en donc en déduire la hauteur d’eau puis le volume d’eau). Exploitation en json pour simplifier les choses où l’on souhaite récupérer la hauteur vide et calculer directement le volume d’eau de la cuve
Matériel nécessaire
- Rpi Pico W
- Sensor HC-SR04
- Un résistor de 1kΩ
- Un résistor de 2kΩ
- Une platine de test et de cablage
- Des jarretières
- Un fer à souder
- De l’étain fin

Prérequis de configuration réseau
- Ajout d’un fichier dans secrets.py pour insérer les références de l’accès WiFi et la clef
- Mise en place d’un adresse IP statique IPv4 sur le DHCP
- Mise en place d’un nom de domaine lié à ce périphérique
Développement micro-python
main.py. Inspiré de différent exemple de code trouvé sur le net.
import rp2
import network
import ubinascii
import machine
import urequests as requests
import time
from secrets import secrets
import socket
from machine import Pin
# Set country to avoid possible errors
rp2.country('FR')
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
# If you need to disable powersaving mode
# wlan.config(pm = 0xa11140)
# See the MAC address in the wireless chip OTP
mac = ubinascii.hexlify(network.WLAN().config('mac'),':').decode()
print('mac = ' + mac)
# Other things to query
# print(wlan.config('channel'))
# print(wlan.config('essid'))
# print(wlan.config('txpower'))
# Load login data from different file for safety reasons
ssid = secrets['ssid']
pw = secrets['pw']
wlan.connect(ssid, pw)
# Wait for connection with 10 second timeout
timeout = 10
while timeout > 0:
if wlan.status() < 0 or wlan.status() >= 3:
break
timeout -= 1
print('Waiting for connection...')
time.sleep(1)
# Define blinking function for onboard LED to indicate error codes
def blink_onboard_led(num_blinks):
led = machine.Pin('LED', machine.Pin.OUT)
for i in range(num_blinks):
led.on()
time.sleep(.2)
led.off()
time.sleep(.2)
# Handle connection error
# Error meanings
# 0 Link Down
# 1 Link Join
# 2 Link NoIp
# 3 Link Up
# -1 Link Fail
# -2 Link NoNet
# -3 Link BadAuth
wlan_status = wlan.status()
blink_onboard_led(wlan_status)
if wlan_status != 3:
raise RuntimeError('Wi-Fi connection failed')
else:
print('Connected')
status = wlan.ifconfig()
print('ip = ' + status[0])
print('mask = ' + status[1])
print('gateway = ' + status[2])
print('DNS = ' + status[3])
# Function to load in html page
def get_html(html_name):
with open(html_name, 'r') as file:
html = file.read()
return html
# HTTP server with socket
addr = socket.getaddrinfo('0.0.0.0', 80)[0][-1]
s = socket.socket()
s.bind(addr)
s.listen(1)
print('Listening on', addr)
led = machine.Pin('LED', machine.Pin.OUT)
# Listen for connections
while True:
try:
cl, addr = s.accept()
print('Client connected from', addr)
r = cl.recv(1024)
r = str(r)
###SENSOR MESURE START
trig = Pin(17, Pin.OUT)
echo = Pin(16, Pin.IN, Pin.PULL_DOWN)
trig.value(0)
time.sleep(0.1)
trig.value(1)
time.sleep_us(2)
trig.value(0)
while echo.value()==0:
pulse_start = time.ticks_us()
while echo.value()==1:
pulse_end = time.ticks_us()
pulse_duration = pulse_end - pulse_start
distance = pulse_duration * 17165 / 1000000
distance = round(distance, 0)
print ('Distance:',"{:.0f}".format(distance),'cm')
distanceString = str("{:.0f}".format(distance))
time.sleep(1)
###SENSOR MESURE END
pageResponse = '{ \"distance\" : \"',distanceString,'\" }'
cl.send('HTTP/1.0 200 OK\r\nContent-type: application/json\r\n\r\n')
cl.send('{ \"distance\" : \"')
cl.send(distanceString)
cl.send('\" }, { \"units\" : \"cm\"}')
cl.close()
except OSError as e:
cl.close()
s.close()
print('Connection closed')
Quelques débogages et ajustement et voici l’output CLI :
>>> %Run -c $EDITOR_CONTENT
mac = XX:XX:XX:XX:XX:XX
Connected
ip = 192.168.A.B
mask = 255.255.255.0
gateway = 192.168.A.C
DNS = 192.168.A.D
Listening on ('0.0.0.0', 80)
Client connected from ('192.168.XX.E', 52583)
Distance: 96 cm
Client connected from ('192.168.XX.E', 52584)
Distance: 96 cm
Et côté web :
{ "distance" : "96" }, { "units" : "cm"}
Reste à calculer le volume vide en connaissant la hauteur de vide et en déduire le volume d’eau
La cuve est assimilable à un cylindre mais couché, ce qui ne simplifie pas le calcul par rapport à un simple cylindre débout. On sait que la cuve fait 5m3, 1.52m de hauteur et 2.75m de long. Détail de la cuve ici.

Il faut donc trouver l’aire du morceau de cercle doit correspondre à un profil d’arc-tangente. On peut déjà sortir les 3 vérités suivantes, h étant la hauteur d’eau pleine perpendiculaire à la surface d’eau de la cuve et passant par le centre du cercle.
- Si h=0 alors V=0 (cuve vide)
- Si h=1.52 alors V=5000 (cuve moitié-pleine)
- Si h=0.76 alors V=2500 (cuve pleine)
La formule semble être :
2.75*(0.76²*ACOS((0.76-h)/0.76)-(0.76-h)*RACINE(2*0.76*h-h²))