Created
June 1, 2011 16:48
-
-
Save kjordahl/1002726 to your computer and use it in GitHub Desktop.
Arduino sketch to read data from DS18x20 digital temperature sensors
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* 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 | |
[email protected] | |
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