OneWire + DS18X20 Library
Basic functions for OneWire operations + specific DS18x20 operations
 All Functions Groups Pages
OneWire + DS18X20 Library Documentation
ds18x20.h - ds18x20 library
onewire.h - onewire library
Author
Falk Brunner
Version
1.00
License:
Beerware License
Files:
ds18x20.h
ds18x20.c
onewire.h
onewire.c
Description:
Developed on AVR plattform, but can be used with any other
AVR-Studio 4.18, WinAVR20100110 (avr-gcc 4.3.3)

Atomic access and IO access must be adapted to other plattforms!
Onewire operation is interrupt proof. During one single bit transmission
and onewire reset, interrupts are disabled for 100us. Between single bits
interrupts are enabled to allow servicing of interrupts.
Example:
Arduino plattform example
#include <util/delay.h>
#include "onewire.h"
#include "ds18x20.h"
#define MAX_ROMS 10
typedef uint8_t rom_t[MAX_ROMS][8];
uint8_t buffer[9] = {0x10, 0x1D, 0x9E, 0x09, 0x02, 0x08, 0x00, 0x55, 0x00}; // init values just for test & debugging
rom_t roms;
rom_t alarm_roms;
void print_header(void);
void print_rom(uint8_t *data, uint8_t index);
int scan_bus(rom_t rom_list, uint8_t cmd);
int scan_bus(rom_t rom_list, uint8_t cmd) {
uint8_t i, j, rc;
if (cmd == ONEWIRE_SEARCH_ROM) {
Serial.println(F("\r\nScaning OneWire bus for ROM codes.\r\n"));
} else if (cmd == ONEWIRE_ALARM_SEARCH) {
Serial.println(F("\r\nScaning OneWire bus for devices with active alarm flag.\r\n"));
} else {
return -2; // error, unknown command
}
print_header();
rc=ONEWIRE_OK;
for (i = 0; (i < MAX_ROMS) && (rc == ONEWIRE_OK); i++) {
rc = onewire_search(buffer, cmd);
if (rc == ONEWIRE_OK || rc == ONEWIRE_LAST_CODE ) {
print_rom(buffer, i);
memcpy(rom_list[i], buffer, 8);
} else {
// error
switch (rc) {
case ONEWIRE_NO_PRESENCE: Serial.println(F("No response on bus!")); break;
case ONEWIRE_GND_SHORT: Serial.println(F("Bus shorted to GND!")); break;
case ONEWIRE_SCAN_ERROR:
if (cmd == ONEWIRE_SEARCH_ROM) {
Serial.println(F("Scan error!"));
} else {
return 0; // no alarm device found
}
break;
}
break; // finish scan loop
}
}
if (!(rc == ONEWIRE_OK || rc == ONEWIRE_LAST_CODE)) {
return -1; // error
} else {
return i; // number of found ROMs
}
}
void print_header(void) {
int8_t i, j;
Serial.print(F(" Index: "));
for (i = 7; i >= 0; i--) {
Serial.print(F(" "));
Serial.print(i);
Serial.print(F(" "));
}
Serial.println("");
}
void print_rom(uint8_t *data, uint8_t index) {
int8_t i, j;
Serial.print(F(" ROM#"));
if (index < 10) {
Serial.print('0');
}
Serial.print(index);
Serial.print(' ');
for (i = 7; i >= 0; i--) {
Serial.print(F(" 0x"));
if (data[i] < 16) {
Serial.print(F("0"));
}
Serial.print(data[i], HEX);
Serial.print(F(" "));
}
Serial.println("");
}
void print_scratchpad(uint8_t *data) {
uint8_t i;
Serial.println(F("\r\nPrinting scratchpad data"));
Serial.println(F("Index Value"));
for (i = 0; i < 9; i++) {
Serial.print(F(" "));
Serial.print(i);
Serial.print(F(" 0x"));
Serial.println(data[i], HEX);
}
}
void setup() {
int16_t x;
uint8_t i, j, crc;
volatile int rc; // volatile is used for timing measurement in simulation, not required for normal application
uint8_t i_ds18B20, i_ds18S20;
Serial.begin(9600);
Serial.println(F("\r\nOneWire (tm) demo"));
// speed test in simulator, set breakpoints on next two lines
rc = onewire_crc(buffer, 8);
rc;
if (rc) {
Serial.println(F("\r\nCRC error in buffer data!"));
}
/******************************************************************************************
single device on bus, simple access without ROM code
******************************************************************************************/
Serial.println(F("\r\nReading ROM code of single device on bus."));
rc = onewire_read_rom(buffer);
for (i = 0, j = 0; i < 8; i++) j |= buffer[i]; // or all data
crc = buffer[7];
buffer[7] = 0;
if (rc == ONEWIRE_NO_PRESENCE) {
Serial.println(F("No response on bus!"));
while (1); // stop here
} else if (rc == ONEWIRE_CRC_ERROR) {
Serial.println(F("CRC error! "));
Serial.print(F("Received CRC : 0x"));
Serial.println(crc, HEX);
Serial.print(F("Calculated CRC: 0x"));
Serial.println(onewire_crc(buffer, 8), HEX);
Serial.println(F("There is probably more than one device on the bus.\r\n"));
} else if (j == 0) {
Serial.println(F("All rom data zero."));
Serial.println(F("There is probably more than one device on the bus.\r\n"));
}
buffer[7] = crc;
print_header();
print_rom(buffer, 0);
if ((rc == 0) && (j >0)) {
// check if DS18S20 or DS18B20 are found on bus
if (buffer[0] == DS18S20_ID) i_ds18S20 = 1; else i_ds18S20 = 0; // family code for DS18S20
if (buffer[0] == DS18B20_ID) i_ds18B20 = 1; else i_ds18B20 = 0; // family code for DS18B20
// read complete scratchpad (9 bytes)
if (i_ds18S20 || i_ds18B20) {
if (onewire_crc(buffer, 9)) {
Serial.println(F("CRC error in scratchpad data!"));
}
print_scratchpad(buffer);
}
// temperature reading using normal power
if (!i_ds18S20) {
Serial.println(F("\r\nNo DS18S20 found on bus."));
} else {
Serial.println(F("\r\nReading temperature of DS18S20 (9 Bit + extended resolution, effective resolution 0.0625 C)"));
Serial.println(F("DS18S20 must be normal powered!"));
Serial.println(F("Press any key to stop"));
while (!Serial.available()) {
ds18S20_convert_t(0); // normal power
_delay_ms(750);
if (rc) {
Serial.println(F("CRC error!"));
} else {
Serial.print(F("T: "));
Serial.print(x / 10);
Serial.print('.');
Serial.print(abs(x) % 10);
Serial.println(F(" C"));
}
}
}
// clear input buffer
while (Serial.available()) Serial.read();
// temperature reading using parasitic power
if (!i_ds18B20) {
Serial.println(F("\r\nNo DS18B20 found on bus."));
} else {
Serial.println(F("\r\nReading temperature of DS18B20 (12 Bit, 0.0625 C resolution)"));
Serial.println(F("DS18B20 must be parasitc powered!"));
Serial.println(F("Press any key to stop"));
while (!Serial.available()) {
ds18x20_convert_t(1); // parasitic power
_delay_ms(750);
ONEWIRE_STRONG_PU_OFF // user must disable strong pull up after conversion
// when using parasitic power
if (rc) {
Serial.println(F("CRC error!"));
} else {
Serial.print(F("T: "));
Serial.print(x / 10);
Serial.print('.');
Serial.print(abs(x) % 10);
Serial.println(F(" C"));
}
}
}
// clear input buffer
while (Serial.available()) Serial.read();
}
Serial.println(F("\r\nSingle device demo finished."));
/******************************************************************************************
multiple devices demo, access only with ROM code
******************************************************************************************/
rc = scan_bus(roms, ONEWIRE_SEARCH_ROM);
if (rc == -1) {
Serial.println(F("\r\nError, no device found!"));
while (1);
} else {
Serial.print(F("\r\nScan finished, "));
Serial.print(rc);
Serial.println(F(" devices found."));
}
// find rom index for DS18S20 and DS18B20
i_ds18B20 = MAX_ROMS;
i_ds18S20 = MAX_ROMS;
for (i = 0; i < MAX_ROMS; i++) {
if (i_ds18B20 == MAX_ROMS && roms[i][0] == DS18B20_ID) {
i_ds18B20 = i; // first rom index for DS18B20
}
if (i_ds18B20 == MAX_ROMS && roms[i][0] == DS18S20_ID) {
i_ds18S20 = i; // first rom index for DS18S20
}
}
// temperature reading using normal power
if (i_ds18S20 == MAX_ROMS) {
Serial.println(F("\r\nNo DS18S20 found on bus!"));
} else {
Serial.println(F("\r\nReading temperature of DS18S20 (9 Bit + extended resolution, effective resolution 0.0625 C )"));
Serial.println(F("DS18S20 must be normal powered"));
Serial.println(F("Press any key to stop"));
while (!Serial.available()) {
onewire_match_rom(roms[i_ds18S20]);
ds18S20_convert_t(0);
_delay_ms(750);
onewire_match_rom(roms[i_ds18S20]);
if (rc) {
Serial.println(F("CRC error!"));
} else {
Serial.print(F("T: "));
Serial.print(x / 10);
Serial.print('.');
Serial.print(abs(x) % 10);
Serial.println(F(" C"));
}
}
// clear input buffer
while (Serial.available()) Serial.read();
// write th, tl to DS18S20
Serial.println(F("\r\nWriting th(28) & tl(15) to DS18S20."));
onewire_match_rom(roms[i_ds18S20]);
// read complete scratchpad (9 bytes)
onewire_match_rom(roms[i_ds18S20]);
ds18S20_read_scratchpad(buffer);
if (onewire_crc(buffer, 9)) {
Serial.print(F("\r\nCRC error in scratchpad data!"));
}
print_scratchpad(buffer);
// copy scratchpad to EEPROM, normal power
onewire_match_rom(roms[i_ds18S20]);
ds18S20_copy_scratchpad(0);
// copy EEPROM to scratchpad
onewire_match_rom(roms[i_ds18S20]);
ds18S20_recall_E2();
// read complete scratchpad (9 bytes)
onewire_match_rom(roms[i_ds18S20]);
ds18S20_read_scratchpad(buffer);
if (onewire_crc(buffer, 9)) {
Serial.print(F("\r\nCRC error in scratchpad data!"));
}
print_scratchpad(buffer);
// read power supply
Serial.print(F("DS18S20 runs on "));
onewire_match_rom(roms[i_ds18S20]);
if (ds18S20_read_power_supply()) {
Serial.println(F("parasitic power."));
} else {
Serial.println(F("normal power."));
}
}
// temperature reading using parasitic power
if (i_ds18B20 == MAX_ROMS) {
Serial.println(F("\r\nNo DS18B20 found on bus!"));
} else {
Serial.println(F("\r\nReading temperature of DS18B20 (12 Bit, 0.0625 C resolution)"));
Serial.println(F("DS18B20 must be parasitic powered"));
Serial.println(F("Press any key to stop"));
while (!Serial.available()) {
onewire_match_rom(roms[i_ds18B20]);
ds18B20_convert_t(1); // parasitic power
_delay_ms(750);
ONEWIRE_STRONG_PU_OFF // user must disable strong pull up after conversion
// when using parasitic power
onewire_match_rom(roms[i_ds18B20]);
if (rc) {
Serial.println(F("CRC error!")); break;
} else {
Serial.print(F("T: "));
Serial.print(x / 10);
Serial.print('.');
Serial.print(abs(x) % 10);
Serial.println(F(" C"));
}
}
// clear input buffer
while (Serial.available()) Serial.read();
// write th, tl and config to DS18B20
// write th, tl and config to DS18B20
Serial.println(F("\r\nWriting th(28) & tl(10) and adc resolution (12 bits) to DS18B20."));
onewire_match_rom(roms[i_ds18B20]);
// read complete scratchpad (9 bytes)
onewire_match_rom(roms[i_ds18B20]);
ds18B20_read_scratchpad(buffer);
if (onewire_crc(buffer, 9)) {
Serial.print(F("\r\nCRC error in scratchpad data!"));
}
print_scratchpad(buffer);
// copy scratchpad to EEPROM, parasitic power
onewire_match_rom(roms[i_ds18B20]);
ds18B20_copy_scratchpad(1); // parasitic power
// copy EEPROM to scratchpad
onewire_match_rom(roms[i_ds18B20]);
ds18B20_recall_E2();
// read complete scratchpad (9 bytes)
onewire_match_rom(roms[i_ds18B20]);
ds18B20_read_scratchpad(buffer);
if (onewire_crc(buffer, 9)) {
Serial.print(F("\r\nCRC error in scratchpad data!"));
}
print_scratchpad(buffer);
// read power supply
Serial.print(F("\r\nDS18B20 runs on "));
onewire_match_rom(roms[i_ds18B20]);
if (ds18B20_read_power_supply()) {
Serial.println(F("parasitic power."));
} else {
Serial.println(F("normal power."));
}
}
// scan for alarm
Serial.println(F("Scaning for alarm devices."));
Serial.println(F("Press any key to stop"));
while (!Serial.available()) {
// in this demo, DS18S20 and DS18B20 run on different power modes (normal/parasitic)
// so we must send the convert_t command seperately
// the alarm flag inside the DS18x20 is updated ONLY after a convert_t command, not continuously!
if (i_ds18S20 != MAX_ROMS) {
onewire_match_rom(roms[i_ds18S20]);
ds18S20_convert_t(0);
_delay_ms(1000);
}
if (i_ds18B20 != MAX_ROMS) {
onewire_match_rom(roms[i_ds18B20]);
ds18B20_convert_t(1);
_delay_ms(1000);
ONEWIRE_STRONG_PU_OFF
}
// if all DS18x20 run on the same power mode, a broadcast convert_t could be sent
/*
onewire_skip_rom();
ds18S20_convert_t(0); // is identical to ds18B20_convert_t(0)
_delay_ms(1000);
*/
rc = scan_bus(alarm_roms, ONEWIRE_ALARM_SEARCH);
if (rc <= 0) {
Serial.println(F("\r\nNo alarm device found!"));
} else {
Serial.print(F("\r\nScan finished, "));
Serial.print(rc);
Serial.println(F(" devices found."));
}
}
// clear input buffer
while (Serial.available()) Serial.read();
Serial.println(F("\r\nMultiple device demo finished."));
Serial.println(F("Press Reset to restart."));
}
void loop() {
// put your main code here, to run repeatedly:
}