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.