Skip to content

Instantly share code, notes, and snippets.

@kjordahl
Created June 1, 2011 16:48
Show Gist options
  • Save kjordahl/1002726 to your computer and use it in GitHub Desktop.
Save kjordahl/1002726 to your computer and use it in GitHub Desktop.
Arduino sketch to read data from DS18x20 digital temperature sensors
/* Name: onewire.pde
Read data from multiple DS18x20 digital temperature sensors
DS18B20 <http://www.maxim-ic.com/datasheet/index.mvp/id/2812>
DS18S20 <http://www.maxim-ic.com/datasheet/index.mvp/id/2815>
* Detect number and type of sensors, and whether each is using parasitic power
* Gracefully handles plugging/unplugging of sensors (but will not
detect new sensors after initialization)
Based on sample.pde from OneWire library (v2.0),
copyright Jim Studt, Paul Stoffregen, Robin James and others
Requires OneWire <http://www.pjrc.com/teensy/td_libs_OneWire.html>
Kelsey Jordahl
kjordahl@alum.mit.edu
http://kjordahl.net
Time-stamp: <Wed Jun 1 12:46:28 EDT 2011>
*/
#include <OneWire.h>
#define ONEWIREPIN 7 /* OneWire bus on digital pin 7 */
#define MAXSENSORS 5 /* Maximum number of sensors on OneWire bus */
// Model IDs
#define DS18S20 0x10
#define DS18B20 0x28
#define DS1822 0x22
// OneWire commands
#define CONVERT_T 0x44 // Tells device to take a temperature reading and put it on the scratchpad
#define COPYSCRATCH 0x48 // Copy EEPROM
#define READSCRATCH 0xBE // Read EEPROM
#define WRITESCRATCH 0x4E // Write to EEPROM
#define RECALLSCRATCH 0xB8 // Reload from last known
#define READPOWERSUPPLY 0xB4 // Determine if device needs parasite power
#define ALARMSEARCH 0xEC // Query bus for devices with an alarm condition
class Sensor /* hold info for a DS18 class digital temperature sensor */
{
public:
byte addr[8];
boolean parasite;
float temp;
};
int HighByte, LowByte, TReading, SignBit, Tc_100;
byte i, j, sensors;
byte present = 0;
boolean ready;
int dt;
byte data[12];
byte addr[8];
OneWire ds(ONEWIREPIN); // DS18S20 Temperature chip i/o
Sensor DS[MAXSENSORS]; /* array of digital sensors */
void setup(void) {
// initialize inputs/outputs
// start serial port
Serial.begin(9600);
sensors = 0;
Serial.println("Searching for sensors...");
while ( ds.search(addr)) {
if ( OneWire::crc8( addr, 7) != addr[7]) {
Serial.print("CRC is not valid!\n");
break;
}
delay(1000);
ds.write(READPOWERSUPPLY);
boolean parasite = !ds.read_bit();
present = ds.reset();
Serial.print("temp");
Serial.print(sensors,DEC);
Serial.print(": ");
DS[sensors].parasite = parasite;
for( i = 0; i < 8; i++) {
DS[sensors].addr[i] = addr[i];
Serial.print(addr[i], HEX);
Serial.print(" ");
}
//Serial.print(addr,HEX);
if ( addr[0] == DS18S20) {
Serial.print(" DS18S20");
}
else if ( addr[0] == DS18B20) {
Serial.print(" DS18B20");
}
else {
Serial.print(" unknown");
}
if (DS[sensors].parasite) {Serial.print(" parasite");} else {Serial.print(" powered");}
Serial.println();
sensors++;
}
Serial.print(sensors,DEC);
Serial.print(" sensors found");
Serial.println();
for (i=0; i<sensors; i++) {
Serial.print("temp");
Serial.print(i,DEC);
if (i<sensors-1) {
Serial.print(",");
}
}
Serial.println();
}
void get_ds(int sensors) { /* read sensor data */
for (i=0; i<sensors; i++) {
ds.reset();
ds.select(DS[i].addr);
ds.write(CONVERT_T,DS[i].parasite); // start conversion, with parasite power off at the end
if (DS[i].parasite) {
dt = 75;
delay(750); /* no way to test if ready, so wait max time */
} else {
ready = false;
dt = 0;
delay(10);
while (!ready && dt<75) { /* wait for ready signal */
delay(10);
ready = ds.read_bit();
dt++;
}
}
present = ds.reset();
ds.select(DS[i].addr);
ds.write(READSCRATCH); // Read Scratchpad
for ( j = 0; j < 9; j++) { // we need 9 bytes
data[j] = ds.read();
}
/* check for valid data */
if ( (data[7] == 0x10) || (OneWire::crc8( addr, 8) != addr[8]) ) {
LowByte = data[0];
HighByte = data[1];
TReading = (HighByte << 8) + LowByte;
SignBit = TReading & 0x8000; // test most sig bit
if (SignBit) // negative
{
TReading = (TReading ^ 0xffff) + 1; // 2's comp
}
if (DS[i].addr[0] == DS18B20) { /* DS18B20 0.0625 deg resolution */
Tc_100 = (6 * TReading) + TReading / 4; // multiply by (100 * 0.0625) or 6.25
}
else if ( DS[i].addr[0] == DS18S20) { /* DS18S20 0.5 deg resolution */
Tc_100 = (TReading*100/2);
}
if (SignBit) {
DS[i].temp = - (float) Tc_100 / 100;
} else {
DS[i].temp = (float) Tc_100 / 100;
}
} else { /* invalid data (e.g. disconnected sensor) */
DS[i].temp = NAN;
}
}
}
void loop(void) {
get_ds(sensors);
for (i=0; i<sensors; i++) {
if (isnan(DS[i].temp)) {
Serial.print("NaN");
} else {
Serial.print(DS[i].temp,2);
}
if (i<sensors-1) {
Serial.print(",");
}
}
Serial.println();
delay(5000);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment