Read DS18B20 on ESP32 without hanging the main loop
The DS18B20 communicates via 1-Wire, and at a resolution of 12 bits, it takes 750 milliseconds to complete one measurement. In a textbook way, the main loop would sit still for those exact 750ms — on a device that also needs to blink an LED and respond to a button press, the user will notice immediately.
The common mistake that everyone writes first
import time, onewire, ds18x20
from machine import Pin
ds = ds18x20.DS18X20(onewire.OneWire(Pin(4)))
roms = ds.scan()
while True:
ds.convert_temp()
time.sleep_ms(750) # <-- cả con chip đứng ở đây
for rom in roms:
print(ds.read_temp(rom))750ms multiplied by each measurement cycle. If measuring every second, then three-quarters of the chip's lifespan is spent waiting for a sensor.
Separate the measurement request from the reading of the result.
1-Wire does not require waiting. Send the conversion command, go do other work, come back to read when the 750ms is up:
import time, onewire, ds18x20
from machine import Pin
ds = ds18x20.DS18X20(onewire.OneWire(Pin(4)))
roms = ds.scan()
deadline = 0
pending = False
while True:
now = time.ticks_ms()
if not pending:
ds.convert_temp()
deadline = time.ticks_add(now, 760) # 750 + biên an toàn
pending = True
elif time.ticks_diff(deadline, now) <= 0:
for rom in roms:
print(ds.read_temp(rom))
pending = False
nhap_nhay_led() # vòng lặp chính vẫn chạy`ticks_diff` instead of a normal subtraction: MicroPython's counter overflows, and a direct subtraction will yield an enormous negative number right when it overflows — this error only appears after several dozen days of continuous operation, the hardest type of error to catch.
Two things often forgotten
A pull-up resistor of 4.7kΩ between DQ and VCC. Without it, the circuit may still 'run' on the bench, but will have erratic readings as the wires get longer.
Configurable resolution. Dropping to 9 bits only requires 94ms, trading off for a measurement step of 0.5°C — for the problem of monitoring room temperature, that is a worthwhile trade-off.