Overview
The DS18B20 is a classic digital temperature sensor: range -55°C ~ +125°C (accuracy ±0.5°C within -10~+85°C), and at 12-bit resolution it can distinguish as little as 0.0625°C. It also communicates over a single-wire bus (one wire carries both data and clock), and every DS18B20 is burned with a unique 64-bit serial number at the factory — so multiple sensors can be daisy-chained in parallel on one data wire and read separately (this tutorial reads one first). This tutorial uses the Ai-WB2 development board to read the DS18B20's temperature, printing it on the serial in real time, and walks through the full flow of wiring → coding → building → flashing (writing the compiled program into the board's chip) → running and verification.
In plain words: the DS18B20 is like a digital thermometer with a unique "ID card" (64-bit serial number). The main controller "talks" to it over one wire by sending pulses of specific lengths: first a "reset" pulse wakes it up, then a "read temperature" command, and it sends the 12-bit temperature data back bit by bit over that wire. Note it needs a pull-up resistor (a small resistor holding the line high by default) because its data line is open-drain — without the pull-up, you read nothing.
This tutorial is based on the official Ai-Thinker SDK (Ai-Thinker-Open/Ai-Thinker-WB2, version
release_bl_iot_sdk_1.6.40) exampleapplications/iot-solution/demo_ds18b20; the code can be found directly in the local SDK.
Wire per the official example (see the SDK’s applications/iot-solution/demo_ds18b20/README.md), using dupont wires (jumper wires with pins at both ends):
| Ai-WB2 Pin | DS18B20 Pin |
|---|---|
| IO4 | DQ (DATA) |
| 3V3 | VCC (red wire) |
| GND | GND (black wire) |
⚠️ You must connect a 4.7kΩ pull-up resistor between DQ and 3V3 (a small resistor holding the line high by default). The DS18B20’s data line is open-drain (can only pull low, not high) — without the pull-up you read no data. This is the easiest pitfall of this sensor. 💡 The DS18B20 accepts 3.3V~5V supply; this tutorial uses 3.3V throughout. Pinch the TO-92 sensor between your fingers and the temperature rises slowly — handy for verification.
This tutorial directly uses the demo_ds18b20 example project shipped with the official SDK; open a terminal and enter it:
cd ~/Ai-Thinker-WB2/applications/iot-solution/demo_ds18b20
Note:
cdis the “change directory” command — entering the DS18B20 example project directory; all subsequentmakebuild andmake flashflash commands must run in this directory first.
This is a multi-file project: main program + the official ported DS18B20 driver library (from the open-source LibDriver, wrapping the single-wire reset/read-write-bit/read-write-byte timing):
| File | Purpose |
|---|---|
demo_ds18b20/main.c |
Main program source, the main file this tutorial looks at |
demo_ds18b20/driver_ds18b20_basic.c/h |
Basic read/write interface (init, read temperature) |
demo_ds18b20/driver_ds18b20.c/h |
Single-wire timing core (reset, read/write bit, read/write byte) |
demo_ds18b20/driver_ds18b20_alarm.c/h |
Alarm (threshold) feature, not used in this tutorial |
demo_ds18b20/driver_ds18b20_search.c/h |
Searching multiple sensors on the bus (64-bit serial numbers), not used in this tutorial |
demo_ds18b20/driver_ds18b20_interface_bl602.c |
Platform adaptation layer: hooks the driver to the WB2’s GPIO4 |
Makefile |
Build entry, usually no changes needed |
Open demo_ds18b20/main.c — the complete code for this step has been moved to the end of this page:
📜 Full Code — in the “Full Code” section below, collapsed by default — click to expand, identical to the official example (
applications/iot-solution/demo_ds18b20/demo_ds18b20/main.c).
Code highlights:
| Code | Purpose |
|---|---|
ds18b20_basic_init() |
Initializes the DS18B20 driver (configures the single-wire pin IO4); without it the driver can’t communicate |
ds18b20_basic_read(&temperature) |
Triggers one temperature conversion and reads back the 12-bit temperature data (resolution 0.0625°C); a failed read returns 1 |
blog_info("%.2f C degree", temperature) |
Prints the temperature on the serial (°C, 2 decimals); no print = no visible result |
vTaskDelay(pdMS_TO_TICKS(500)) |
Samples every 500 ms; too fast and the temperature conversion (12-bit takes ~750ms) isn’t done, so you read stale values |
Build in the project directory:
make -j8
Note:
makeis the “build” command, turning code into firmware (the program file) the board can run;-j8builds with 8 parallel CPU cores, faster.
On success a firmware build_out/demo_ds18b20.bin is generated.
⚠️ If it reports
riscv64-unknown-elf-gcc: command not found, the toolchain permissions aren’t configured — runcd toolchain/riscv/Linux && . chmod755.shfirst, then rebuild.
Keep the board connected via USB, confirm the serial device (usually /dev/ttyUSB0 on Linux), and flash:
make flash p=/dev/ttyUSB0 b=921600
Note:
make flashis the “flash” command, writing the compiled firmware into the board’s chip. Afterp=comes the serial device (change it to your computer’s actual one — check withls /dev/ttyUSB*),b=is the flash baud rate (transfer speed).
⏳ During flashing, press and hold the EN button on the board when prompted to enter download mode (some boards enter automatically); wait for the progress bar to complete — that means the flash succeeded. For flashing on Windows, see Windows Quick Start.
After flashing, the board automatically restarts and runs; open the serial assistant (baud rate 921600 — the baud rate is the serial transfer speed, both ends must be set the same) and temperature prints every 500 ms:
26.50 C degree
26.50 C degree
...
Pinch the sensor between your fingers — the temperature should rise slowly; release it and it slowly falls back.
Seeing the serial print temperature every 500 ms means success; if the temperature is stuck at 85.00 C degree (the DS18B20’s power-on default) or nothing prints, it hasn’t succeeded yet — check the FAQ at the end.
💡 Watch the IO4 waveform with a logic analyzer to see the single-wire reset pulse and data bit timing (see the official example’s
img/logic_analyzer.jpg).
API Summary for This Tutorial
ds18b20_basic_init()
Initializes the DS18B20 driver: registers the platform interface functions (GPIO read/write, microsecond delay, interrupt disable) and completes the sensor reset self-check.
Parameters:
- None
Return: 0 on success; 1 on failure (e.g. sensor not responding). Driver implementation in demo_ds18b20/driver_ds18b20_basic.c
ds18b20_basic_read(temperature)
Triggers one temperature conversion and reads the result: single-wire reset → send read-temperature command → read back 2 bytes of raw temperature → convert to float temperature (°C).
Parameters:
temperature:float *output pointer, receives the temperature (°C, e.g.26.50), required
Return: 0 on success; 1 on failure (read failure or CRC error). Driver implementation in demo_ds18b20/driver_ds18b20_basic.c
blog_info(fmt, ...)
Prints an INFO-level log (UART0, subject to level filtering); this tutorial prints the temperature with it.
Parameters:
fmt: format string, same usage asprintf, required...: variadic args matching thefmtplaceholders; can be omitted
Return: none
vTaskDelay(ms)
Suspends the current task for the given milliseconds, yielding the CPU to other tasks.
Parameters:
ms: delay in milliseconds, values: any non-negative integer (internally converted to system ticks viapdMS_TO_TICKS)
Return: none
Full Code
Below is the complete demo_ds18b20/main.c source, identical to the official example (applications/iot-solution/demo_ds18b20/demo_ds18b20/main.c). This is a multi-file project; the rest of the driver files (driver_ds18b20*.c/h, driver_ds18b20_interface_bl602.c) live in the same directory, no changes needed:
📜 Click to expand the full demo_ds18b20/main.c code
#include <stdio.h>
#include <FreeRTOS.h>
#include <task.h>
#include <blog.h>
#include "driver_ds18b20_basic.h"
int main(void)
{
ds18b20_basic_init();
float temperature;
for (;;) {
ds18b20_basic_read(&temperature);
blog_info("%.2f C degree\r\n", temperature);
vTaskDelay(pdMS_TO_TICKS(500));
}
return 0;
}FAQ & Troubleshooting
⚠️ Temperature stuck at 85.00°C (no real reading)
Cause: 85.00 is the DS18B20's power-on default — whenever communication fails (most often forgetting the 4.7kΩ pull-up resistor), the reading stays at this value
Fix: confirm a 4.7kΩ pull-up between DQ and 3V3; check the wiring (VCC red, GND black, DQ on IO4); re-seat the dupont wires
⚠️ The serial never prints (can't read)
Cause: wrong wiring, DQ not on IO4, a damaged sensor, or insufficient 3.3V supply
Fix: check the wiring table one by one; confirm VCC to 3V3 and GND to GND (common ground = the two devices' grounds must be joined, otherwise voltage has no reference point); try another DS18B20
⚠️ Temperature jumps around or stays fixed
Cause: wires too long/poor contact causing timing jitter, or the read interval too short so the conversion isn't done
Fix: shorten the dupont wires (<20cm); confirm the pull-up resistor is soldered reliably; you can raise vTaskDelay to 1000 and retry
⚠️ Serial device not found or no permission
Cause: on Linux /dev/ttyUSB0 doesn't exist or permission denied; on Windows the USB-to-serial driver isn't installed
Fix: on Linux check with ls /dev/ttyUSB*; if permission denied run sudo usermod -aG dialout $USER and log back in; on Windows install the driver in Device Manager and confirm the COM port
⚠️ Flashing keeps waiting, progress bar doesn't move
Cause: download mode wasn't entered, or the cable only charges and can't transfer data
Fix: press and hold EN during flashing to enter download mode as prompted; try a Type-C data-capable cable
⚠️ make reports Makefile not found
Cause: the build command ran in the wrong directory (must be inside the example project directory)
Fix: run cd ~/Ai-Thinker-WB2/applications/iot-solution/demo_ds18b20 first, then make -j8
Self-Check
The serial prints temperature every 500 ms; pinching the sensor makes it rise slowly (no longer stuck at the fixed 85.00) — the DS18B20 temperature measurement is verified.

