OneWire: the bus under the DS18B20
OneWire, maintained by Paul Stoffregen, drives Maxim鈥檚 1-Wire bus: one data wire plus ground, a 4.7 k pull-up to the supply, and any number of devices hanging off it, each with a unique 64-bit ROM address burned in at the factory. The DS18B20 thermometer is the device almost everyone meets it through.
Built in on Mokxi: #include <OneWire.h> and it builds, with nothing to install. Free, and no account needed.
What OneWire does
The library works at the level of the bus itself. reset() checks whether any device is present, search() walks the bus and hands back one address at a time, select() talks to one address, and read() and write() move bytes. Every address ends in a CRC byte, and OneWire::crc8() lets you check it.
Most temperature sketches never call OneWire directly; they create a OneWire object and pass it to DallasTemperature, which does the commands for them. Reach for OneWire on its own to list the addresses on a bus, to read a device DallasTemperature does not know, or to see exactly what the bytes say.
| Library Manager name | OneWire |
|---|---|
| Author | Paul Stoffregen |
| Include | #include <OneWire.h> |
| Boards | every board Mokxi compiles for but ATtiny85 |
| In the simulator | Simulated: it runs against the part the way it does on the bench. |
| Parts it drives | Temperature sensor, DS18B20 |
Install it
It builds on every board Mokxi compiles for but ATtiny85.
In Mokxi it is built in: #include <OneWire.h> and the sketch compiles, with no download, no zip and no Library Manager.
On a real board, install "OneWire" by Paul Stoffregen from the Arduino IDE鈥檚 Library Manager (Sketch, Include Library, Manage Libraries), or add OneWire to lib_deps in PlatformIO. Mokxi follows the calls of release 2.3.8, so a sketch written here builds there too.
ESP32-C3 路 Arduino Uno 路 Arduino Nano 路 Arduino Mega 2560 路 Arduino Leonardo 路 SparkFun Pro Micro 路 Arduino Micro 路 ESP32-C6 路 Raspberry Pi Pico 路 Raspberry Pi Pico W 路 Seeed XIAO SAMD21 路 STM32 路 STM32 Nucleo-F411RE 路 STM32 Blue Pill 路 micro:bit V2 路 Arduino Uno R4 路 ESP32 DevKit 路 ESP32-S3-DevKitC-1 路 ESP8266 NodeMCU 路 Arduino Pro Mini 3.3 V 路 Seeed XIAO ESP32-C3 路 ESP32-C3 SuperMini 路 Seeed XIAO ESP32-C6 路 ESP32-DevKitC V4 路 LOLIN32 Lite 路 Wemos D1 R32 路 Cheap Yellow Display 路 TTGO T-Display 路 Seeed XIAO ESP32-S3 路 Arduino Nano ESP32 路 Arduino Nano RP2040 Connect 路 Seeed XIAO RP2040 路 Waveshare RP2040-Zero 路 Arduino Uno R4 WiFi
The calls you will use
In the order a sketch meets them.
OneWire ds(2)
Creates a 1-Wire bus on pin 2. The pin needs a 4.7 k pull-up to the supply.
ds.search(addr)
Finds the next device and copies its 8-byte address into addr. Returns false when there are no more.
byte addr[8];
while (ds.search(addr)) {
for (byte i = 0; i < 8; i++) Serial.print(addr[i], HEX);
Serial.println();
}ds.reset_search()
Starts the next search() from the first device again.
OneWire::crc8(addr, 7)
The CRC of the first seven address bytes, which must equal addr[7] for a good read.
ds.reset()
Sends a reset pulse. Returns 1 if any device answered with a presence pulse.
ds.select(addr)
Addresses one device, so the commands that follow go to it alone. skip() addresses every device at once.
ds.write(0x44, 1)
Sends a byte, here the DS18B20鈥檚 "convert temperature" command, keeping the line powered for parasite-powered sensors.
Example: Thermometers on one wire
On the Arduino Uno R3. It runs in the browser exactly as printed.
// Two DS18B20 thermometers on one wire.
//
// Both sensors share pin 2, with a single 4k7 pull-up to 5 V for the whole
// bus. Each has its own 64-bit ROM code, and the 1-Wire search finds them one
// by one: every sensor still in the search sends its next bit and then its
// complement, the open-drain wire ANDs them together, and where they disagree
// the master picks a branch and the sensors on the other one drop out.
//
// The sketch finds them once, keeps their addresses, and after that asks each
// one by name. Drag the sliders on the two sensors to warm or cool them.
//
// getTemp() is the reading as the library keeps it, a whole number of 1/128ths
// of a degree, and the sketch prints it with integer sums. getTempC() hands
// back a float instead, which prints just as well, but the float printing
// alone would take this example past the 8 KB an Uno example is allowed.
#include <OneWire.h>
#include <DallasTemperature.h>
OneWire oneWire(2);
DallasTemperature sensors(&oneWire);
DeviceAddress found[2];
int count = 0;
void printAddress(const uint8_t *address) {
for (int i = 0; i < 8; i++) {
if (address[i] < 16) Serial.print('0');
Serial.print(address[i], HEX);
}
}
void setup() {
Serial.begin(9600);
sensors.begin();
count = sensors.getDeviceCount();
if (count > 2) count = 2;
Serial.print(count);
Serial.println(" sensors on the wire");
for (int i = 0; i < count; i++) {
sensors.getAddress(found[i], i);
Serial.print("sensor ");
Serial.print(i);
Serial.print(" is ");
printAddress(found[i]);
Serial.println();
}
}
void loop() {
// One CONVERT T for everybody: both sensors measure at once, 750 ms.
sensors.requestTemperatures();
for (int i = 0; i < count; i++) {
long raw = sensors.getTemp(found[i]);
Serial.print("sensor ");
Serial.print(i);
Serial.print(": ");
if (raw == DEVICE_DISCONNECTED_RAW) {
Serial.print("gone");
} else {
// Hundredths of a degree, rounded, then the two halves either side of
// the point. A negative reading carries its own minus sign.
long hundredths = (raw * 100 + (raw < 0 ? -64 : 64)) / 128;
if (hundredths < 0) {
Serial.print('-');
hundredths = -hundredths;
}
Serial.print(hundredths / 100);
Serial.print('.');
if (hundredths % 100 < 10) Serial.print('0');
Serial.print(hundredths % 100);
Serial.print(" C");
}
Serial.print(i + 1 < count ? " " : "\n");
}
}Open it in the editor, wired and ready to run 路 Thermometers on one wire: the project page
Common errors and how to fix them
search() never finds anything
Almost always the pull-up. Put a 4.7 k resistor between the data pin and the supply (3.3 or 5 V), check the device鈥檚 pinout (on a DS18B20 flat face toward you: ground, data, VDD) and make sure the pin number matches.
CRC is not valid!
The bytes were corrupted on the way in. Shorten the wires, use a stronger pull-up (2.2 k) on a long cable, and keep the data line away from motor and mains wiring.
Readings of 85 C or -127 C
85 C is the DS18B20鈥檚 power-up value, read before a conversion finished; wait 750 ms after the convert command. -127 is DallasTemperature鈥檚 code for a sensor that did not answer at all.
Projects that use OneWire
Built-in projects that include it. Each page has the full sketch and opens in the editor, already wired.
Keep going
More communication libraries
Try OneWire without installing anything
Open the example, change the sketch, and keep your version in a free account.