from machine import Pin, time_pulse_us
import time
import ujson
IR_PIN = 13
TRIG_PIN = 5
ECHO_PIN = 18
LED_PASSAGE_PIN = 2
LED_STOCK_OK_PIN = 15
LED_STOCK_LOW_PIN = 4
HAUTEUR_BAC_CM = 35.0
SEUIL_STOCK_FAIBLE_CM = 25.0
STOCK_INTERVAL_MS = 1000
IR_MIN_INTERVAL_MS = 800
LED_PASSAGE_DURATION_MS = 150
ir_sensor = Pin(IR_PIN, Pin.IN, Pin.PULL_UP)
trig = Pin(TRIG_PIN, Pin.OUT)
echo = Pin(ECHO_PIN, Pin.IN)
led_passage = Pin(LED_PASSAGE_PIN, Pin.OUT)
led_stock_ok = Pin(LED_STOCK_OK_PIN, Pin.OUT)
led_stock_low = Pin(LED_STOCK_LOW_PIN, Pin.OUT)
last_ir_state = 1
last_ir_event_ms = time.ticks_ms() - IR_MIN_INTERVAL_MS
last_passage_led_ms = 0
last_stock_measure_ms = time.ticks_ms() - STOCK_INTERVAL_MS
last_stock_state = None
passage_count = 0
def clamp(value, low, high):
return max(low, min(high, value))
def read_distance_cm():
trig.value(0)
time.sleep_us(2)
trig.value(1)
time.sleep_us(10)
trig.value(0)
try:
duration_us = time_pulse_us(echo, 1, 30000)
except OSError:
return None
if duration_us <= 0:
return None
return duration_us * 0.0343 / 2.0
def print_json(payload):
print(ujson.dumps(payload))
def handle_ir(now_ms):
global last_ir_state, last_ir_event_ms, last_passage_led_ms, passage_count
ir_state = ir_sensor.value()
ir_detected = ir_state == 0
if (
ir_detected
and last_ir_state == 1
and time.ticks_diff(now_ms, last_ir_event_ms) >= IR_MIN_INTERVAL_MS
):
last_ir_event_ms = now_ms
last_passage_led_ms = now_ms
passage_count += 1
led_passage.value(1)
print_json({
"type": "ir_passage",
"capteur_id": "IR_P1",
"poste": "P1",
"node_id": "WOKWI_PICO_IR_US",
"ir": 1,
"piece_increment": 1,
"passage_count": passage_count,
})
last_ir_state = ir_state
if led_passage.value() and time.ticks_diff(now_ms, last_passage_led_ms) >= LED_PASSAGE_DURATION_MS:
led_passage.value(0)
def handle_stock(now_ms):
global last_stock_measure_ms, last_stock_state
if time.ticks_diff(now_ms, last_stock_measure_ms) < STOCK_INTERVAL_MS:
return
last_stock_measure_ms = now_ms
distance_cm = read_distance_cm()
if distance_cm is None:
print_json({
"type": "stock_ultrason_error",
"capteur_id": "US_P1",
"poste": "P1",
"node_id": "WOKWI_PICO_IR_US",
"etat": "ERREUR_MESURE",
})
return
distance_cm = round(distance_cm, 1)
distance_limited = clamp(distance_cm, 0.0, HAUTEUR_BAC_CM)
niveau_estime_percent = round(100.0 * (1.0 - distance_limited / HAUTEUR_BAC_CM), 1)
stock_faible = distance_cm >= SEUIL_STOCK_FAIBLE_CM
etat_stock = "FAIBLE" if stock_faible else "OK"
led_stock_ok.value(0 if stock_faible else 1)
led_stock_low.value(1 if stock_faible else 0)
payload = {
"type": "stock_ultrason",
"capteur_id": "US_P1",
"poste": "P1",
"node_id": "WOKWI_PICO_IR_US",
"distance_cm": distance_cm,
"niveau_estime_percent": niveau_estime_percent,
"stock_faible": stock_faible,
"etat_stock": etat_stock,
"seuil_stock_faible_cm": SEUIL_STOCK_FAIBLE_CM,
"hauteur_bac_cm": HAUTEUR_BAC_CM,
}
print_json(payload)
if last_stock_state is not None and last_stock_state != etat_stock:
alert_payload = dict(payload)
alert_payload["type"] = "stock_alert"
alert_payload["alerte"] = "STOCK_FAIBLE" if stock_faible else "STOCK_OK"
print_json(alert_payload)
last_stock_state = etat_stock
print("Simulation Wokwi Raspberry Pi Pico prete: IR + ultrason.")
print("Bouton IR: appui = passage piece. HC-SR04: distance_cm mesuree, stock estime par calcul.")
while True:
now = time.ticks_ms()
handle_ir(now)
handle_stock(now)
time.sleep_ms(10)