Become a subscriber (Free)

Join 29,000 other subscribers to receive subscriber sale discounts and other free resources.
Don't worry -- your e-mail address is totally secure. I promise to use it only to send you MicroZine.

All About the DS18B20 Serial Digital Temperature Sensor

On this page you can find out how to use the DS18B20 temperature sensor effectively, and also how you use it on an Arduino Uno R3. All you need is a microcontroller with a bi-directional I/O pin i.e. virtually any modern microcontroller - then all you need is a bit of code.

Note: The DS18B20 can take its power entirely from a data line pin requiring no positive supply other than that pin - this means you can place it in locations that do not have an easily accessible power source.

The really good thing about this sensor is that it uses a 1-wire interface for multiple 1-wire devices (not necessarily just temperature sensors). Each 1-wire device, including the DS18B20, has a unique laser engraved identifier so you can individually communicate with 1-wire devices. This is how the 1-wire protocol distinguishes between multiple devices attached to a single 1-wire bus.

This is both good and bad; good because you can attach multiple devices and bad (but not too bad) because you have to identify and locate each device e.g in a large building installation you have to get the ID and log it in some software that shows where it is.

The 1-wire interface is actually signal and ground so it should really be called a '2-wire' interface; It is called 1-wire because it is taken for granted that there is always a ground return path.

The DS18B20 is a digital sensor with a basic accuracy of 0.5°C (and it only outputs data in °C) - it also has an adjustable resolution from 0.5°C (9bits) to 0.0625°C (12 bits) - the acquisition speed is affected by the chosen resolution - from 93ms (9bit res.) up to 750ms - nearly 1s - for max. res. of 12bits.

Note: You can attach multiple 1-wire devices to a single microcontroller I/O pin.
TIP: Make sure and read this warning on using a pull-up resistor (it won't work without one!) lower in this page (Click here to jump down the page).

Internal NV Memory

One of the key points about the device is that it does not always have to be fully active because it performs a temperature conversion at higher power and then stores the value in its own internal NV memory. This important if you use the two wire mode GND and signal - where the signal wire also powers the device.

DS18B20 Specifications

Parameter DS18B20
Temperature Range -55°C ~ 125°C
Temperature Accuracy: 0.5°C (-10 ~ 85°C)
Temperature Accuracy: 2°C (-55 ~ 125°C)
Resolution 0.0625°C ~ 0.5°C
Drift 0.2°C 1000-hour stress at 125°C
Power Supply: 3.0 ~5.5V
Active Supply Current: 1 ~ 1.5mA
Idle Supply Current: 0.75mA ~ 1mA (max)

DS18B20 Acquisition Speed vs Acquisition time

No. Bits Max Conversion Time Resolution Bits to Ignore
9 93.75ms 0.500°C 2,1,0
10 187.5ms 0.250°C 1,0
11 375ms 0.125°C 0
12 750ms 0.0625°C -

[Source : datasheet below - No. bits,Max Conversion Time]

Note: Resolution is calculated from the data representation in Table 1 in the datasheet below where hex code 0 is 0°C and hex code 8 is 0.5°C therefore 1 bit represents 0.5/8 °C or 0.0625°C (at 12 bit resolution).

Remember that the lower bits of the device output hex data must be ignored when using lower resolutions because the values of these bits are undefined so make sure they are zero when you use the output data.

DS18B20 Datasheet

Powering the DS18B20

There are two ways to power a DS18B20 :

  1. External 3-5V power supply.
  2. Parasitic power (from the data line of the microcontroller).
Warning : I thought I could get away with just powering the DS18B20 using GND and VDD, and using only a signal wire : Nope - you must have a pullup resistor from the chip control pin to Vcc of about 4k7 As Well (I used 3k3 at a pinch).

If you don't, the Arduino library (1st example below) can not see the device. The device must be pulled-up with a resistor when the signal wire is tristate (even with GND and VCC supplied). If you do not do this you'll just see the message "No more addresses.". This be due to the signal method used (open collector) - so don't forget (as I did) that the pull-up is not just supplying power.

Only a single pull-up will be needed and it can be placed close to the microcontroller pin.

DS18B20 External Power Supply

The first method "external power" is the easier route for ensuring correct operation but requires a local source of power. Since these devices can operate over very long cable distances i.e. within a building it is not always convenient to connect to a power supply where you want to measure the temperature.

You can either use an extra wire to carry power or use the Parasitic Power Supply method but there are complications.

DS18B20 Parasitic power

Parasitic power is power derived from the single 4k7 pull-up resistor on the One-Wire bus. Parasitic power charges an internal capacitor in the 1-wire devices so there is still some energy there when the bus is pulled low by another device. The key issue with this is that during an internal EEPROM write (to the DS18B20) or while updating the temperature reading, up to 1.5mA can be drawn.

Using the pull-up resistor alone to supply power, can cause the voltage supplied to the DS18B20 to drop possibly causing a reset. One solution is to use a stronger pull-up resistor e.g. 1kΩ.

The datasheet indicates that a strong current driver (a MOSFET from Vcc to the 1-wire bus) should be used to supply power while these actions are executing i.e. to override the 4k7 pull-up - allowing more current to the sensor.

The problem is that during the strong pullup action no other communication can be made over the onewire bus. A write to the NV (twr in the datasheet) EEPROM can take a maximum of 10ms (for the copy scratchpad command) - for a convert command the pull-up is held for the conversion time (93ms ~ 750ms)- that is how long the strong pull-up must be held to ensure valid operation!

For continuous comms. i.e. communication with other devices use a power individually supplied to vcc of the DS18B20. This may mean using a 3 core wire instead of 2 wire or using a separate power supply at the DS18B20 device location.

In the 'DallasTemperature' library provision is made to hold the microcontroller pin high for a time to perform a similar action to the MOSFET - most microcontroller pins have fairly high output current capability ~20mA. Using this method will still stop comms. though.

Note: You can mix parasitic and external power devices on the same 1-wire bus. There is a mechanism to query the device on how it is powered i.e. to avoid having to use strong pull-up for an external powered device (see the datasheet).

DS18B20 Connection

The recommended wire is CAT5 and you arrange them as a bus (daisy chained) not as a star network - this helps to avoid transmission line reflection problems.

Arduino Temperature Sensor DS18B20 Alarm

You can program into the DS18B20 upper and lower temperatures (into non-volatile memory - internal EEPROM) so that if the temperature goes outside the upper or lower limits an alarm condition is created.

The master controller can issue an alarm search command at regular intervals- any DS18B20 connected to the 1-wire bus that has an alarm condition will respond. The controller can then find out which device has the alarm condition flag set.

Note: Functions are defined for setting alarms in the "MAX31850 Dallas Temperature" library. See note at the end on the MAX31850.

DS18B20 Arduino Software Setup:

IDE Version Used : 1.6.4
Board used : Arduino Uno R3
Library : OneWire V2.2

Parts for the DS18B20 project:

  1. Device Used : DS18B20 (either on a breakout board or stand-alone).
  2. 4k7.
  3. Breadboard.
  4. Arduino Uno R3.
  5. 10uF Electrolytic.

DS18B20 connections

Do not wire this backwards - it will blow up!

Note: Some datasheets use the label "ds18b20-par" - the par text just stands for parasitic powered.

ds18b20 pin connections

Example 1

Arduino Circuit layout 1; DS18B20 wire connection:

Both parasitic and external power connections can be used on the same One-wire bus.

Note: Two DS18B20 devices are shown in the following circuits, but the code will work just fine with one - since it auto detects devices attached to the one wire bus.

The left hand device is parasitic powered (the so-called 1-wire interface which is actually a 2 - wire interface - GND and signal) while the right hand device is externally powered (3 - wire interface - GND, signal and power).

  • You can remove either device from the solderless breadboard and you'll still get a temperature reading from the other one!

DS18B20 arduino layout with external power and parasitic power connections

Arduino DS18B20 Library 1

The first library is a user contributed i.e not included with the Arduino IDE but you can still install it using the Arduino IDE library manager.

Install Library 1

  1. Goto Menu Sketch --> Include Library --> Manage Libraries...
  2. In the Filter Search type onewire.
  3. Click on the OneWire Library.
  4. Hit install.

Note: If you don't see the above library structure then you have got the wrong IDE (the correct one is from

You can now find the sketch example in Menu:

Files --> Examples --> OneWire --> DS18x20_Temperature

Arduino Sketch 1 : DS18B20

The following code is the example included with the OneWire library (only changed to put the OneWire bus (for the DS18B20) on pin 4 of the Arduino Uno R3:

Note: Clicking any text in the box below will copy it to the clipboard.

#include <OneWire.h>

// OneWire DS18S20, DS18B20, DS1822 Temperature Example
// The DallasTemperature library can do all this work for you!

OneWire  ds(4);  // on signal pin (a single 4.7K resistor is necessary)

void setup(void) {

void loop(void) {
  byte i;
  byte present = 0;
  byte type_s;
  byte data[12];
  byte addr[8];
  float celsius, fahrenheit;

  if ( ! {
    Serial.println("No more addresses.");

  Serial.print("ROM =");
  for( i = 0; i < 8; i++) {
    Serial.write(' ');
    Serial.print(addr[i], HEX);

  if (OneWire::crc8(addr, 7) != addr[7]) {
      Serial.println("CRC is not valid!");

  // the first ROM byte indicates which chip
  switch (addr[0]) {
    case 0x10:
      Serial.println("  Chip = DS18S20");  // or old DS1820
      type_s = 1;
    case 0x28:
      Serial.println("  Chip = DS18B20");
      type_s = 0;
    case 0x22:
      Serial.println("  Chip = DS1822");
      type_s = 0;
      Serial.println("Device is not a DS18x20 family device.");

  ds.write(0x44, 1);        // start conversion, with parasite power on at the end

  delay(1000);     // maybe 750ms is enough, maybe not
  // we might do a ds.depower() here, but the reset will take care of it.

  present = ds.reset();;
  ds.write(0xBE);         // Read Scratchpad

  Serial.print("  Data = ");
  Serial.print(present, HEX);
  Serial.print(" ");
  for ( i = 0; i < 9; i++) {           // we need 9 bytes
    data[i] =;
    Serial.print(data[i], HEX);
    Serial.print(" ");
  Serial.print(" CRC=");
  Serial.print(OneWire::crc8(data, 8), HEX);

  // Convert the data to actual temperature
  // because the result is a 16 bit signed integer, it should
  // be stored to an "int16_t" type, which is always 16 bits
  // even when compiled on a 32 bit processor.
  int16_t raw = (data[1] << 8) | data[0];
  if (type_s) {
    raw = raw << 3; // 9 bit resolution default
    if (data[7] == 0x10) {
      // "count remain" gives full 12 bit resolution
      raw = (raw & 0xFFF0) + 12 - data[6];
  } else {
    byte cfg = (data[4] & 0x60);
    // at lower res, the low bits are undefined, so let's zero them
    if (cfg == 0x00) raw = raw & ~7;  // 9 bit resolution, 93.75 ms
    else if (cfg == 0x20) raw = raw & ~3; // 10 bit res, 187.5 ms
    else if (cfg == 0x40) raw = raw & ~1; // 11 bit res, 375 ms
    //// default is 12 bit resolution, 750 ms conversion time
  celsius = (float)raw / 16.0;
  fahrenheit = celsius * 1.8 + 32.0;
  Serial.print("  Temperature = ");
  Serial.print(" Celsius, ");
  Serial.println(" Fahrenheit");

Warning: Again as with the DHT22 code the above code uses hard coded delays - they are also the maximum delays, so even for 9bits the code uses a 1s delay! Of course you can change that but you have to be aware of it.

See the Dallas Temperature library: Asynchronous mode for a different solution.

Output from above code (oneWire Library).

This is the output from the Arduino serial monitor showing:

  • ROM data (The hard coded chip code and family code (28)),
  • Chip Type,
  • Scratch pad data,
  • Temperature in and °C and °F ( °F is calculated using a floating point calculation).

Output with one DS18B20 sensor:

Output with two DS18B20 sensors:

ds18B20 with parasitic and external power connections

Output with three DS18B20 sensors:

DS18B20 3 sensors 1 external power 2 -parasitic power

Arduino DS18B20 Library 2

This library builds on the OneWire Library (references to the OneWire library are accessed through the variable '_wire' in DallasTemperature.cpp). It gives you a more complete access mechanism to control devices on the bus. In addition it tailors the delays required before update to the resolution in use (delays change with resolution). There is also an asynchronous mechanism to avoid wasting processor time while the sensor updates.

Install Library 2

  1. Goto Menu Sketch --> Include Library --> Manage Libraries...
  2. In the Filter Search type dallas.
  3. Click on the MAX31850 DallasTemp Library (this also supports DS18B20).
  4. Hit install.

You can now find the sketch examples in Menu:

Files --> Examples --> MAX31850 DallasTemp --> (as below):

Open the Simple example above.

Arduino Sketch 2

The following sketch uses the OneWire and DallasTemperature libraries (Maxim bought Dallas - hence the old name).

The first sketch is labelled "Simple"; Edit the pin 2 changing it to pin 4. Then use saveas to Simple_DallasTemp in your Arduino Library folder (default location). In the sketch below I added 2 more outputs as I have 3 DS18B20 devices on the bus - you can add as many output statements as device you have.

#include <OneWire.h>
#include <DallasTemperature.h>
// Data wire is plugged into port 2 on the Arduino
#define ONE_WIRE_BUS 4

// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
OneWire oneWire(ONE_WIRE_BUS);

// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire);

void setup(void) {
// start serial port
Serial.println("Dallas Temperature IC Control Library Demo");

// Start up the library
sensors.begin(); }

void loop(void) { // call sensors.requestTemperatures() to issue a global temperature
// request to all devices on the bus
Serial.print("Requesting temperatures...");
sensors.requestTemperatures(); // Send the command to get temperatures
Serial.print("Temperature for the device 1 (index 0) is: ");
Serial.println(sensors.getTempCByIndex(0)); Serial.print("Temperature for the device 2 (index 1) is: ");
Serial.println(sensors.getTempCByIndex(1)); Serial.print("Temperature for the device 3 (index 2) is: ");

Output with three DS18B20 sensors

Asynchronous Delays

If you want the processor to do something else while waiting for a temperature update there is a mechanism in the DallasTemperature.cpp code you can activate called ASYNC Mode - a private boolean flag (waitForConversion) is controlled from a public function:

// sets the value of the waitForConversion flag // TRUE : function requestTemperature() etc returns when conversion is ready // FALSE: function requestTemperature() etc returns immediately (USE WITH CARE!!) // (1) programmer has to check if the needed delay has passed // (2) but the application can do meaningful things in that time
void DallasTemperature::setWaitForConversion(bool flag) {
waitForConversion = flag; }

// gets the value of the waitForConversion flag
bool DallasTemperature::getWaitForConversion() {
return waitForConversion; }

Simplifying the above, the member functions are:

setWaitForConversion(bool flag)

You can query the flag state using the public function:

bool getWaitForConversion()

Basically, if the flag is true and you initiate a temperature update for a device, then the code will return immediately - it is up to you to wait for the required time. You could make an interrupt timer to trigger fetching of the temperature while your code does something else e.g. updates a display, reads a keyboard or reads another device such as a humidity sensor.

Note: The asynchronous delay mechanism allows you to avoid wasting processing time while a sensor updates BUT it is up to you to wait the appropriate length of time.

This mechanism is encoded within the library like this:

// ASYNC mode

So the routine either returns to your code immediately or performs a delay wait.


The MAX31850 is a Cold-Junction Compensated Thermocouple sensor that is also a OneWire sensor meaning you can choose any of the available thermocouples (K, J, N, T, and E). As with the DSB1820 it has 12bit resolution.

You buy a different MAX31850 (with different end code in the part number) that is matched to a specific thermocouple type (K, J, N, T, and E).

Note: To use the MAX31850 they say (Adafruit) that you need to use the OneWire Library supplied by Adafruit - which is a a bit naughty since they are making branches in code instead of updating the original. I have not looked at it though - best to do as they say if you want a MAX31850 to work!

Using a different thermocouple type increases the max min range or sensitivity e.g type K has a -200?C to 1350?C range.

MAX31850 Library Functions

The "MAX31850 Dallas Temperature" library has many useful functions that are built on top of the OneWire library and if you are going to seriously use the Maxim OneWire devices, then it is worth studying. To give you an overview here's a list of the functions it provides:

DallasTemperature(OneWire* _oneWire) DallasTemperature::alarmSearch(uint8_t* newAddr) DallasTemperature::begin(void) DallasTemperature::blockTillConversionComplete(uint8_t* bitResolution, uint8_t* deviceAddress) DallasTemperature::calculateTemperature(uint8_t* deviceAddress, uint8_t* scratchPad) DallasTemperature::defaultAlarmHandler(uint8_t* deviceAddress) DallasTemperature::getAddress(uint8_t* deviceAddress, uint8_t index) DallasTemperature::getCheckForConversion() DallasTemperature::getDeviceCount(void) DallasTemperature::getHighAlarmTemp(uint8_t* deviceAddress) DallasTemperature::getLowAlarmTemp(uint8_t* deviceAddress) DallasTemperature::getResolution() DallasTemperature::getResolution(uint8_t* deviceAddress) DallasTemperature::getTempC(uint8_t* deviceAddress) DallasTemperature::getTempCByIndex(uint8_t deviceIndex) DallasTemperature::getTempF(uint8_t* deviceAddress) DallasTemperature::getTempFByIndex(uint8_t deviceIndex) DallasTemperature::getWaitForConversion() DallasTemperature::hasAlarm(uint8_t* deviceAddress) DallasTemperature::hasAlarm(void) DallasTemperature::isConnected(uint8_t* deviceAddress) DallasTemperature::isConnected(uint8_t* deviceAddress, uint8_t* scratchPad) DallasTemperature::isConversionAvailable(uint8_t* deviceAddress) DallasTemperature::isParasitePowerMode(void) DallasTemperature::processAlarms(void) DallasTemperature::readPowerSupply(uint8_t* deviceAddress) DallasTemperature::readScratchPad(uint8_t* deviceAddress, uint8_t* scratchPad) DallasTemperature::requestTemperatures() DallasTemperature::requestTemperaturesByAddress(uint8_t* deviceAddress) DallasTemperature::requestTemperaturesByIndex(uint8_t deviceIndex) DallasTemperature::resetAlarmSearch() DallasTemperature::setAlarmHandler(AlarmHandler *handler) DallasTemperature::setCheckForConversion(bool flag) DallasTemperature::setHighAlarmTemp(uint8_t* deviceAddress, char celsius) DallasTemperature::setLowAlarmTemp(uint8_t* deviceAddress, char celsius) DallasTemperature::setResolution(uint8_t newResolution) DallasTemperature::setResolution(uint8_t* deviceAddress, uint8_t newResolution) DallasTemperature::setWaitForConversion(bool flag) DallasTemperature::toCelsius(float fahrenheit) DallasTemperature::toFahrenheit(float celsius)
DallasTemperature::validAddress(uint8_t* deviceAddress) DallasTemperature::writeScratchPad(uint8_t* deviceAddress, const uint8_t* scratchPad)

Jump from DS18B20 to the home page.

New! Comments

Have your say about what you just read! Leave me a comment in the box below.

Privacy Policy | Contact | About Me

Site Map | Terms of Use

Visit our Facebook Page:

   Click Here

Recent Articles

  1. Easily make an IR Pulse Rate Sensor with one opamp, an Arduino, and a matched Infrared phototransistor and LED pair.

    How to make a Pulse Rate Sensor using a simple single opamp circuit with an Arduino and a few other components.

    Read more

  2. 74HC595

    74HC595 : How to add nearly unlimited outputs to any microcontoller.

    Read more

  3. Using the MAX6675 or How to easily measure Extreme temperatures

    How to use the MAX6675 and an Arduino to measure temperatures from 0°C to 1024°C with two components: A chip - the MAX6675, and a Sensor: - a type-K thermocouple.

    Read more

Readers Comments

"I wanted to thank
you so so so much
for all the information
you have provided in
your site it's


- Ranish Pottath

"This site really is
the best and my favorite.
I find here many useful
projects and tips."

- Milan


"Awesome site,
very, very easy and nice
to navigate!"

- Matt

Learn Microcontrollers

"Interested in

Sign up for The
Free 7 day guide:


"I am a newbie to PIC
and I wanted to say
 how great your
site has been for me."

- Dave


"Your site is a great
and perfect work.

- Suresh


"I couldn't find the correct
words to define
yourweb site.

Very useful, uncovered,
honest and clear.

Thanks so much for
your time and works.

- Anon