Arduino 1-wire temperature sensors

So you have played a bit with your Arduino, and have heard about other people using it to monitor the temperature, but weren’t sure how they did it – Here is how I did.

Maxim make a very simple 1-wire temperature sensor – the DS18B20 (the replacement to the DS1820). This 3 pin sensor looks just like a transistor, and can work with only two wires, combined data+power and ground. You can put several on the same wire and address them all separately.

The DS18B20 is less that £4 from RS, so not exactly expensive.

Wiring up the 1-wire sensors is fairly simple:

You can power them with either dedicated power wires (exercise for the reader), or use their “parasitic mode” where they use power from the same wire as data. To wire them this way you need to wire pins 1 and 3 (ground and Vcc) from the DS18B20 both to ground. Pin 2 goes to your Arduino (any digital I/O pin), and also 5v DC through a 4.7kΩ resistor (if you have a lot of 1-wire devices, there are reports that you may need to reduce this down to 2kΩ).
If you have long wires you may need to start looking at dedicated power, but certainly for testing parasitic power will be fine.

Stringing multiple 1-wire sensors together is as simple as connecting all the pins up in parallel.

Wiring DS18B20

To actually query the devices on your Arduino, you will need the 1-wire and Dallas temperature sensor libraries (unzip them to your Arduino editors’ libraries/ folder).

Examples of using the sensors are all over the place (also examples of querying the ID’s of the devices), or you can try mine below which prints to the serial connection the hex ID’s for each 1-wire device found, and the temperature of each every 10 sec.

// OneWire and DallasTemperature libraries from
//   http://milesburton.com/index.php?title=Dallas_Temperature_Control_Library
// Code based on examples from above and at
//   http://www.hacktronics.com/Tutorials/arduino-1-wire-address-finder.html
// See also http://www.arduino.cc/playground/Learning/OneWire
 
#include <onewire .h>
#include <dallastemperature .h>
 
// Data wire is plugged into pin 2 on the Arduino (can be any digital I/O pin)
#define ONE_WIRE_BUS 2
 
// 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(&amp;oneWire);
 
int numberOfSensors;
 
void setup(void)
{
  // start serial port
  Serial.begin(9600);
  Serial.println("1-Wire DS18B20 example code");
 
  // Start up the library
  sensors.begin();
 
  delay(5000);  //important on linux as serial port can lock up otherwise
  numberOfSensors = discoverOneWireDevices();
  Serial.println();
}
 
void loop(void)
{
  printTemperaturesToSerial();
  delay(10000); //wait 10 sec
}
 
void printTemperaturesToSerial(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.println("DONE");
 
  // Read each of our sensors and print the value
  for(int i=0; i < numberOfSensors; i++) {
   Serial.print("Temperature for Device ");
   Serial.print( i );
   Serial.print(" is: ");
   // Why "byIndex"? You can have more than one IC on the same bus. 
   // 0 refers to the first IC on the wire
   Serial.println( sensors.getTempCByIndex(i) );
  }
 
  Serial.println();
}
 
// Based on http://www.hacktronics.com/Tutorials/arduino-1-wire-address-finder.html
int discoverOneWireDevices(void) {
  byte i;
  byte present = 0;
  byte data[12];
  byte addr[8];
  int count = 0;
 
  Serial.println("Looking for 1-Wire devices...");
  while(oneWire.search(addr)) {
    Serial.print("Found \'1-Wire\' device with address: ");
    for( i = 0; i < 8; i++) {
      Serial.print("0x");
      if (addr[i] < 16) {
        Serial.print('0');
      }
      Serial.print(addr[i], HEX);
      if (i < 7) {
        Serial.print(", ");
      }
    }
    if ( OneWire::crc8( addr, 7) != addr[7]) {
        Serial.println("CRC is not valid!");
        return 0;
    }
    Serial.println();
    count++;
  }
  Serial.println("That's it.");
  oneWire.reset_search();
  return count;
}

I get the following output on the serial connection

1-Wire DS18B20 example code
Looking for 1-Wire devices...
Found '1-Wire' device with address: 0x28, 0xCE, 0x85, 0xBB, 0x02, 0x00, 0x00, 0xC1
Found '1-Wire' device with address: 0x28, 0xEF, 0x7F, 0xBB, 0x02, 0x00, 0x00, 0x5B
That's it.

Requesting temperatures...DONE
Temperature for Device 0 is: 21.31
Temperature for Device 1 is: 21.37

Requesting temperatures...DONE
Temperature for Device 0 is: 21.37
Temperature for Device 1 is: 21.37
...

There you have it – A very quick Arduino temperature sensor, using pretty cheap 1-wire devices. The only problem you have now is how to get the wires everywhere you might want to read the temperature of.

About Anton Piatek

Professional bit herder, amateur photographer. Linux and tech geek
This entry was posted in Arduino, Programming and tagged , , , , . Bookmark the permalink.

11 Responses to Arduino 1-wire temperature sensors

  1. AndyT says:

    I forget which seller precisely I bought mine from, but you can get a pack of 10 on eBay for $20, so around £12:

    http://cgi.ebay.co.uk/10-pcs-DS18S20-DS1820-1-Wire-Digital-Thermometer-Dallas-/250415670959?pt=LH_DefaultDomain_0&hash=item3a4defe6af

    My flat is littered with the things 🙂

  2. Anton Piatek says:

    Thanks for pointing that out – That is a DS18S20, which had some warnings about some things not working as well, but searching on ebay turns up similar prices for a pack of 10 DS18B20 too! http://shop.ebay.co.uk/?_from=R40&_trksid=m570&_nkw=ds18b20

  3. Ken says:

    You can be sneaky and save yourself a bit of cash by making use of the Maxim free samples.

  4. Ken says:

    Ignore my last comment, they appear to have stopped doing them as freebies 🙁

  5. Joel says:

    Thank you for the quick and easy write-up. Was just working with these sensors this weekend, the code you have here is much cleaner and easier to use that what I was using previously.

  6. Joel says:

    The Miles Burton website is down – but there is still a working link to the libraries – at the moment version 3.6 is available: http://download.milesburton.com/Arduino/MaximTemperature/DallasTemperature_360.zip

    Also a link for the latest version, which I imagine will be updated in the future: http://download.milesburton.com/Arduino/MaximTemperature/DallasTemperature_LATEST.zip

  7. James LeFevre says:

    I tried you one wire address finder example. It will not compile. Gives the following errors.

    temp_sensor_address_finder:15: error: ‘OneWire’ does not name a type
    temp_sensor_address_finder:18: error: ‘DallasTemperature’ does not name a type
    temp_sensor_address_finder:18: error: expected constructor, destructor, or type conversion before ‘)’ token
    temp_sensor_address_finder.ino: In function ‘void setup()’:
    temp_sensor_address_finder:29: error: ‘sensors’ was not declared in this scope
    temp_sensor_address_finder.ino: In function ‘void printTemperaturesToSerial()’:
    temp_sensor_address_finder:46: error: ‘sensors’ was not declared in this scope
    temp_sensor_address_finder.ino: In function ‘int discoverOneWireDevices()’:
    temp_sensor_address_finder:71: error: ‘oneWire’ was not declared in this scope
    temp_sensor_address_finder:83: error: ‘OneWire’ has not been declared
    temp_sensor_address_finder:91: error: ‘oneWire’ was not declared in this scope
    Do you have an example that actually works.

  8. Pingback: Styra en 230V-fläkt genom relä med Arduino | blog.m.nu

  9. Pingback: Fix Arduino Error ‘wire’ Was Not Declared In This Scope Windows XP, Vista, 7, 8 [Solved]

  10. Anitha says:

    can we use lm35 temperature sensor instead of ds18b20 for 1wire interfacing if possible please tel me a link that where i can get the code and what are the outputs can be obtained

  11. Anton Piatek says:

    Anitha I’ve no idea bout the lm35

Leave a Reply