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.

Note: You can attach multiple 1-wire devices to a single microcontroller I/O pin.

TIP: Make sure and read this warning lower in this page (Click here to jump down the page).

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.

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. Note - 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" librarySee 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 DallasTemperature 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 float).

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 DallasTemperature Library:

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?
  if (!waitForConversion) return; 
  blockTillConversionComplete(&bitResolution, 0);

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

Functions Within MAX31850 DallasTemperature

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)


Since the above library talks about the MAX31850 I thought I would discuss it a bit here.

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!

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) to measure temperature with ±2°C accuracy. As with the DSB1820 it has 12bit resolution.

Using a Thermocouple increases the maximum  temperature range you can measure e.g type K has a -200°C to 1350°C range.

Jump from DS18B20 to the home page.

All trademarks are the property of their respective owners.

New! Comments

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

Claim Your: Useful

"Arduino Software Guide"

   Right Now...

Privacy Policy | Contact | About Me

Site Map | Terms of Use

Visit our Facebook Page:

   Click Here

Recent Articles

  1. 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

  2. How to use the DHT22 (or DHT11) with an Arduino; full code and description. Also including a comparison of the DHT11 vs DHT22.

    The Essential Guide to the DHT22/11 humidity sensor including a library code guide for the Arduino. Learn how to determine Humidity, Dew point and Heat Index.

    Read more

  3. How to Use the MAX7219 to drive an 8x8 LED display Matrix on the Arduino.

    The Essential Guide to the MAX7219; What it is and how you can easily use one in any of your projects.

    Read more

Sign up for MicroZine
''The'' Microcontroller Newsletter

Enter your first Name and primary email address in the form below:

And receive absolutely FREE a full project for:

"Measuring Analogue Voltages
Without An ADC"

(Using only one pin).

Instant Download:
You Can
Get It Right Now

Warning: This project could be  Removed 
at any time.  

It will  NOT be 
available indefinitely SO
To avoid 
disappointment  get it:


Don't worry -- your e-mail address is totally secure. I promise to use it only to send you MicroZine
Remember this is a project with full description and fully debugged C Source code - and it's not available from the main website.

You can only get it through this newsletter.

To get exclusive access Enter your first name Name and primary email address Now in the form above.:

But wait !

There's more...

You'll receive more
free and exclusive reports as well as site information and site product updates

Scroll up to the form above and sign up NOW. Don't forget it's FREE and if you don't like it, you can unsubscribe at any time.

Click Here Now to use the form above to get your Valuable information absolutely free.

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