Updated versions of DallasTemperature and OneWire libraries
This commit is contained in:
@@ -4,6 +4,24 @@ Copyright (c) 2007, Jim Studt (original old version - many contributors since)
|
||||
The latest version of this library may be found at:
|
||||
http://www.pjrc.com/teensy/td_libs_OneWire.html
|
||||
|
||||
OneWire has been maintained by Paul Stoffregen (paul@pjrc.com) since
|
||||
January 2010. At the time, it was in need of many bug fixes, but had
|
||||
been abandoned the original author (Jim Studt). None of the known
|
||||
contributors were interested in maintaining OneWire. Paul typically
|
||||
works on OneWire every 6 to 12 months. Patches usually wait that
|
||||
long. If anyone is interested in more actively maintaining OneWire,
|
||||
please contact Paul.
|
||||
|
||||
Version 2.2:
|
||||
Teensy 3.0 compatibility, Paul Stoffregen, paul@pjrc.com
|
||||
Arduino Due compatibility, http://arduino.cc/forum/index.php?topic=141030
|
||||
Fix DS18B20 example negative temperature
|
||||
Fix DS18B20 example's low res modes, Ken Butcher
|
||||
Improve reset timing, Mark Tillotson
|
||||
Add const qualifiers, Bertrik Sikken
|
||||
Add initial value input to crc16, Bertrik Sikken
|
||||
Add target_search() function, Scott Roberts
|
||||
|
||||
Version 2.1:
|
||||
Arduino 1.0 compatibility, Paul Stoffregen
|
||||
Improve temperature example, Paul Stoffregen
|
||||
@@ -136,13 +154,13 @@ uint8_t OneWire::reset(void)
|
||||
DIRECT_WRITE_LOW(reg, mask);
|
||||
DIRECT_MODE_OUTPUT(reg, mask); // drive output low
|
||||
interrupts();
|
||||
delayMicroseconds(500);
|
||||
delayMicroseconds(480);
|
||||
noInterrupts();
|
||||
DIRECT_MODE_INPUT(reg, mask); // allow it to float
|
||||
delayMicroseconds(80);
|
||||
delayMicroseconds(70);
|
||||
r = !DIRECT_READ(reg, mask);
|
||||
interrupts();
|
||||
delayMicroseconds(420);
|
||||
delayMicroseconds(410);
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -249,13 +267,13 @@ void OneWire::read_bytes(uint8_t *buf, uint16_t count) {
|
||||
//
|
||||
// Do a ROM select
|
||||
//
|
||||
void OneWire::select( uint8_t rom[8])
|
||||
void OneWire::select(const uint8_t rom[8])
|
||||
{
|
||||
int i;
|
||||
uint8_t i;
|
||||
|
||||
write(0x55); // Choose ROM
|
||||
|
||||
for( i = 0; i < 8; i++) write(rom[i]);
|
||||
for (i = 0; i < 8; i++) write(rom[i]);
|
||||
}
|
||||
|
||||
//
|
||||
@@ -280,17 +298,30 @@ void OneWire::depower()
|
||||
// You do not need to do it for the first search, though you could.
|
||||
//
|
||||
void OneWire::reset_search()
|
||||
{
|
||||
{
|
||||
// reset the search state
|
||||
LastDiscrepancy = 0;
|
||||
LastDeviceFlag = FALSE;
|
||||
LastFamilyDiscrepancy = 0;
|
||||
for(int i = 7; ; i--)
|
||||
{
|
||||
for(int i = 7; ; i--) {
|
||||
ROM_NO[i] = 0;
|
||||
if ( i == 0) break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Setup the search to find the device type 'family_code' on the next call
|
||||
// to search(*newAddr) if it is present.
|
||||
//
|
||||
void OneWire::target_search(uint8_t family_code)
|
||||
{
|
||||
// set the search state to find SearchFamily type devices
|
||||
ROM_NO[0] = family_code;
|
||||
for (uint8_t i = 1; i < 8; i++)
|
||||
ROM_NO[i] = 0;
|
||||
LastDiscrepancy = 64;
|
||||
LastFamilyDiscrepancy = 0;
|
||||
LastDeviceFlag = FALSE;
|
||||
}
|
||||
|
||||
//
|
||||
// Perform a search. If this function returns a '1' then it has
|
||||
@@ -461,7 +492,7 @@ static const uint8_t PROGMEM dscrc_table[] = {
|
||||
// compared to all those delayMicrosecond() calls. But I got
|
||||
// confused, so I use this table from the examples.)
|
||||
//
|
||||
uint8_t OneWire::crc8( uint8_t *addr, uint8_t len)
|
||||
uint8_t OneWire::crc8(const uint8_t *addr, uint8_t len)
|
||||
{
|
||||
uint8_t crc = 0;
|
||||
|
||||
@@ -475,7 +506,7 @@ uint8_t OneWire::crc8( uint8_t *addr, uint8_t len)
|
||||
// Compute a Dallas Semiconductor 8 bit CRC directly.
|
||||
// this is much slower, but much smaller, than the lookup table.
|
||||
//
|
||||
uint8_t OneWire::crc8( uint8_t *addr, uint8_t len)
|
||||
uint8_t OneWire::crc8(const uint8_t *addr, uint8_t len)
|
||||
{
|
||||
uint8_t crc = 0;
|
||||
|
||||
@@ -493,23 +524,22 @@ uint8_t OneWire::crc8( uint8_t *addr, uint8_t len)
|
||||
#endif
|
||||
|
||||
#if ONEWIRE_CRC16
|
||||
bool OneWire::check_crc16(uint8_t* input, uint16_t len, uint8_t* inverted_crc)
|
||||
bool OneWire::check_crc16(const uint8_t* input, uint16_t len, const uint8_t* inverted_crc, uint16_t crc)
|
||||
{
|
||||
uint16_t crc = ~crc16(input, len);
|
||||
crc = ~crc16(input, len, crc);
|
||||
return (crc & 0xFF) == inverted_crc[0] && (crc >> 8) == inverted_crc[1];
|
||||
}
|
||||
|
||||
uint16_t OneWire::crc16(uint8_t* input, uint16_t len)
|
||||
uint16_t OneWire::crc16(const uint8_t* input, uint16_t len, uint16_t crc)
|
||||
{
|
||||
static const uint8_t oddparity[16] =
|
||||
{ 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0 };
|
||||
uint16_t crc = 0; // Starting seed is zero.
|
||||
|
||||
for (uint16_t i = 0 ; i < len ; i++) {
|
||||
// Even though we're just copying a byte from the input,
|
||||
// we'll be doing 16-bit computation with it.
|
||||
uint16_t cdata = input[i];
|
||||
cdata = (cdata ^ (crc & 0xff)) & 0xff;
|
||||
cdata = (cdata ^ crc) & 0xff;
|
||||
crc >>= 8;
|
||||
|
||||
if (oddparity[cdata & 0x0F] ^ oddparity[cdata >> 4])
|
||||
|
||||
@@ -56,13 +56,44 @@
|
||||
#define IO_REG_TYPE uint8_t
|
||||
#define IO_REG_ASM asm("r30")
|
||||
#define DIRECT_READ(base, mask) (((*(base)) & (mask)) ? 1 : 0)
|
||||
#define DIRECT_MODE_INPUT(base, mask) ((*(base+1)) &= ~(mask))
|
||||
#define DIRECT_MODE_OUTPUT(base, mask) ((*(base+1)) |= (mask))
|
||||
#define DIRECT_WRITE_LOW(base, mask) ((*(base+2)) &= ~(mask))
|
||||
#define DIRECT_WRITE_HIGH(base, mask) ((*(base+2)) |= (mask))
|
||||
#define DIRECT_MODE_INPUT(base, mask) ((*((base)+1)) &= ~(mask))
|
||||
#define DIRECT_MODE_OUTPUT(base, mask) ((*((base)+1)) |= (mask))
|
||||
#define DIRECT_WRITE_LOW(base, mask) ((*((base)+2)) &= ~(mask))
|
||||
#define DIRECT_WRITE_HIGH(base, mask) ((*((base)+2)) |= (mask))
|
||||
|
||||
#elif defined(__MK20DX128__)
|
||||
#define PIN_TO_BASEREG(pin) (portOutputRegister(pin))
|
||||
#define PIN_TO_BITMASK(pin) (1)
|
||||
#define IO_REG_TYPE uint8_t
|
||||
#define IO_REG_ASM
|
||||
#define DIRECT_READ(base, mask) (*((base)+512))
|
||||
#define DIRECT_MODE_INPUT(base, mask) (*((base)+640) = 0)
|
||||
#define DIRECT_MODE_OUTPUT(base, mask) (*((base)+640) = 1)
|
||||
#define DIRECT_WRITE_LOW(base, mask) (*((base)+256) = 1)
|
||||
#define DIRECT_WRITE_HIGH(base, mask) (*((base)+128) = 1)
|
||||
|
||||
#elif defined(__SAM3X8E__)
|
||||
// Arduino 1.5.1 may have a bug in delayMicroseconds() on Arduino Due.
|
||||
// http://arduino.cc/forum/index.php/topic,141030.msg1076268.html#msg1076268
|
||||
// If you have trouble with OneWire on Arduino Due, please check the
|
||||
// status of delayMicroseconds() before reporting a bug in OneWire!
|
||||
#define PIN_TO_BASEREG(pin) (&(digitalPinToPort(pin)->PIO_PER))
|
||||
#define PIN_TO_BITMASK(pin) (digitalPinToBitMask(pin))
|
||||
#define IO_REG_TYPE uint32_t
|
||||
#define IO_REG_ASM
|
||||
#define DIRECT_READ(base, mask) (((*((base)+15)) & (mask)) ? 1 : 0)
|
||||
#define DIRECT_MODE_INPUT(base, mask) ((*((base)+5)) = (mask))
|
||||
#define DIRECT_MODE_OUTPUT(base, mask) ((*((base)+4)) = (mask))
|
||||
#define DIRECT_WRITE_LOW(base, mask) ((*((base)+13)) = (mask))
|
||||
#define DIRECT_WRITE_HIGH(base, mask) ((*((base)+12)) = (mask))
|
||||
#ifndef PROGMEM
|
||||
#define PROGMEM
|
||||
#endif
|
||||
#ifndef pgm_read_byte
|
||||
#define pgm_read_byte(addr) (*(const uint8_t *)(addr))
|
||||
#endif
|
||||
|
||||
#elif defined(__PIC32MX__)
|
||||
#include <plib.h> // is this necessary?
|
||||
#define PIN_TO_BASEREG(pin) (portModeRegister(digitalPinToPort(pin)))
|
||||
#define PIN_TO_BITMASK(pin) (digitalPinToBitMask(pin))
|
||||
#define IO_REG_TYPE uint32_t
|
||||
@@ -101,7 +132,7 @@ class OneWire
|
||||
uint8_t reset(void);
|
||||
|
||||
// Issue a 1-Wire rom select command, you do the reset first.
|
||||
void select( uint8_t rom[8]);
|
||||
void select(const uint8_t rom[8]);
|
||||
|
||||
// Issue a 1-Wire rom skip command, to address all on bus.
|
||||
void skip(void);
|
||||
@@ -137,6 +168,10 @@ class OneWire
|
||||
// Clear the search state so that if will start from the beginning again.
|
||||
void reset_search();
|
||||
|
||||
// Setup the search to find the device type 'family_code' on the next call
|
||||
// to search(*newAddr) if it is present.
|
||||
void target_search(uint8_t family_code);
|
||||
|
||||
// Look for the next device. Returns 1 if a new address has been
|
||||
// returned. A zero might mean that the bus is shorted, there are
|
||||
// no devices, or you have already retrieved all of them. It
|
||||
@@ -149,7 +184,7 @@ class OneWire
|
||||
#if ONEWIRE_CRC
|
||||
// Compute a Dallas Semiconductor 8 bit CRC, these are used in the
|
||||
// ROM and scratchpad registers.
|
||||
static uint8_t crc8( uint8_t *addr, uint8_t len);
|
||||
static uint8_t crc8(const uint8_t *addr, uint8_t len);
|
||||
|
||||
#if ONEWIRE_CRC16
|
||||
// Compute the 1-Wire CRC16 and compare it against the received CRC.
|
||||
@@ -170,8 +205,9 @@ class OneWire
|
||||
// @param inverted_crc - The two CRC16 bytes in the received data.
|
||||
// This should just point into the received data,
|
||||
// *not* at a 16-bit integer.
|
||||
// @param crc - The crc starting value (optional)
|
||||
// @return True, iff the CRC matches.
|
||||
static bool check_crc16(uint8_t* input, uint16_t len, uint8_t* inverted_crc);
|
||||
static bool check_crc16(const uint8_t* input, uint16_t len, const uint8_t* inverted_crc, uint16_t crc = 0);
|
||||
|
||||
// Compute a Dallas Semiconductor 16 bit CRC. This is required to check
|
||||
// the integrity of data received from many 1-Wire devices. Note that the
|
||||
@@ -183,8 +219,9 @@ class OneWire
|
||||
// byte order than the two bytes you get from 1-Wire.
|
||||
// @param input - Array of bytes to checksum.
|
||||
// @param len - How many bytes to use.
|
||||
// @param crc - The crc starting value (optional)
|
||||
// @return The CRC16, as defined by Dallas Semiconductor.
|
||||
static uint16_t crc16(uint8_t* input, uint16_t len);
|
||||
static uint16_t crc16(const uint8_t* input, uint16_t len, uint16_t crc = 0);
|
||||
#endif
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
// The DallasTemperature library can do all this work for you!
|
||||
// http://milesburton.com/Dallas_Temperature_Control_Library
|
||||
|
||||
OneWire ds(10); // on pin 10
|
||||
OneWire ds(10); // on pin 10 (a 4.7K resistor is necessary)
|
||||
|
||||
void setup(void) {
|
||||
Serial.begin(9600);
|
||||
@@ -62,7 +62,7 @@ void loop(void) {
|
||||
|
||||
ds.reset();
|
||||
ds.select(addr);
|
||||
ds.write(0x44,1); // start conversion, with parasite power on at the end
|
||||
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.
|
||||
@@ -72,7 +72,7 @@ void loop(void) {
|
||||
ds.write(0xBE); // Read Scratchpad
|
||||
|
||||
Serial.print(" Data = ");
|
||||
Serial.print(present,HEX);
|
||||
Serial.print(present, HEX);
|
||||
Serial.print(" ");
|
||||
for ( i = 0; i < 9; i++) { // we need 9 bytes
|
||||
data[i] = ds.read();
|
||||
@@ -83,21 +83,24 @@ void loop(void) {
|
||||
Serial.print(OneWire::crc8(data, 8), HEX);
|
||||
Serial.println();
|
||||
|
||||
// convert the data to actual temperature
|
||||
|
||||
unsigned int raw = (data[1] << 8) | data[0];
|
||||
// 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
|
||||
// "count remain" gives full 12 bit resolution
|
||||
raw = (raw & 0xFFF0) + 12 - data[6];
|
||||
}
|
||||
} else {
|
||||
byte cfg = (data[4] & 0x60);
|
||||
if (cfg == 0x00) raw = raw << 3; // 9 bit resolution, 93.75 ms
|
||||
else if (cfg == 0x20) raw = raw << 2; // 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
|
||||
// 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;
|
||||
|
||||
Reference in New Issue
Block a user