DS18B20 1-Wire thermometer
The three-legged digital thermometer, also sold sealed in steel waterproof probes. Aliases: Dallas temperature sensor, 1-Wire probe, 18B20.
It measures -55 to 125 °C to a sixteenth of a degree and sends the answer as a number, so there is no analog reading to calibrate. What makes it worth learning is the bus: every DS18B20 carries a 64-bit serial number burned in at the factory, and any number of them share one data wire, each picked out by that number.
Pins
| Pin | What it does |
|---|---|
GND |
Ground. The left leg with the flat face towards you. |
DQ |
The data line: open drain, and needs a pull-up. |
VDD |
Supply, 3.0 to 5.5 V. |
DQ needs a 4.7 kΩ resistor to VDD. A bare DS18B20 has none, and neither does
the board's pin, so without it the line floats and the sensor is never found. One
resistor serves the whole bus, however many sensors are on it. The three-pin modules
with a little board behind the legs carry that resistor; tick pullup for one of
those.
Properties
temperature is what the sensor is touching, in °C, and the slider on the part
changes it while the circuit runs. serial is the 48-bit serial number as twelve hex
digits; leave it blank and Mokxi makes one from the part's name, so two sensors
dropped on a canvas never clash and keep their numbers from one run to the next.
pullup fits the module's 4.7 kΩ.
The libraries
OneWire.h and DallasTemperature.h both work as the tutorials use them:
#include <OneWire.h>
#include <DallasTemperature.h>
OneWire oneWire(2);
DallasTemperature sensors(&oneWire);
void setup() {
Serial.begin(9600);
sensors.begin();
Serial.print(sensors.getDeviceCount());
Serial.println(" sensors");
}
void loop() {
sensors.requestTemperatures();
for (int i = 0; i < sensors.getDeviceCount(); i++) {
float c = sensors.getTempCByIndex(i);
if (c != DEVICE_DISCONNECTED_C) Serial.println(c);
}
delay(1000);
}
requestTemperatures() starts every sensor converting at once and waits for them,
750 ms at the default twelve bits. The readings come back as floats built exactly
from the sensor's sixteenths, so 23.5625 prints as 23.56, and sums on them in the
sketch, c * 1.8 + 32, work on every board. getTempF() does that one for you, and
getTemp() gives the raw count in 1/128ths of a degree, an ordinary integer.
What the model gets right
The wire, bit by bit, with the datasheet's timings: the 480 µs reset and the presence pulse after it, write slots sampled 30 µs in, read slots where a 0 holds the line low from the master's fall. The ROM commands (READ ROM, MATCH ROM, SKIP ROM, SEARCH ROM and ALARM SEARCH) and the function commands (CONVERT T, READ and WRITE SCRATCHPAD, COPY SCRATCHPAD, RECALL E2, READ POWER SUPPLY), with the Dallas CRC-8 on the ROM code and on the scratchpad.
The search works because the wire does. Several sensors on one net answer a
SEARCH ROM together and the open-drain line ANDs what they send, exactly as on the
bench, so search() finds every one of them. Nothing in the part arbitrates.
Resolution costs time. Nine bits (half a degree) convert in 93.75 ms and twelve bits (a sixteenth) in 750 ms, the datasheet's worst case, and the undefined low bits of a coarse reading read zero. Read slots after CONVERT T return 0 until it is done.
Before the first conversion the temperature register holds +85 °C, as a real one does at power-up. A sketch that reads without converting prints 85, which is the most famous number in the datasheet.
What it does not model
Parasite power. A real DS18B20 can run with VDD tied to ground, living off the
data line, if the master holds the line hard high during a conversion. Here a DS18B20
with no VDD is off the bus, and READ POWER SUPPLY always answers "external".
No error in the reading. The part reports temperature exactly, to its
resolution, with none of the ±0.5 °C a real one is allowed, and it does not warm
itself up. The EEPROM keeps the alarm limits and resolution for the run, not between
runs.
Common mistakes
Forgetting the 4.7 kΩ pull-up, so the sensor is never found. Wiring it back to front:
with the flat face towards you the pins are GND DQ VDD, and a reversed TO-92 gets
hot on a real bench. Reading before requestTemperatures() and getting 85.