|
@ -16,6 +16,7 @@ |
|
|
#include "BaseSensor.h" |
|
|
#include "BaseSensor.h" |
|
|
|
|
|
|
|
|
#define DS_CHIP_DS18S20 0x10 |
|
|
#define DS_CHIP_DS18S20 0x10 |
|
|
|
|
|
#define DS_CHIP_DS2406 0x12 |
|
|
#define DS_CHIP_DS1822 0x22 |
|
|
#define DS_CHIP_DS1822 0x22 |
|
|
#define DS_CHIP_DS18B20 0x28 |
|
|
#define DS_CHIP_DS18B20 0x28 |
|
|
#define DS_CHIP_DS1825 0x3B |
|
|
#define DS_CHIP_DS1825 0x3B |
|
@ -27,6 +28,40 @@ |
|
|
#define DS_CMD_START_CONVERSION 0x44 |
|
|
#define DS_CMD_START_CONVERSION 0x44 |
|
|
#define DS_CMD_READ_SCRATCHPAD 0xBE |
|
|
#define DS_CMD_READ_SCRATCHPAD 0xBE |
|
|
|
|
|
|
|
|
|
|
|
// ====== DS2406 specific constants ======= |
|
|
|
|
|
|
|
|
|
|
|
#define DS2406_CHANNEL_ACCESS 0xF5; |
|
|
|
|
|
|
|
|
|
|
|
// CHANNEL CONTROL BYTE |
|
|
|
|
|
// 7 6 5 4 3 2 1 0 |
|
|
|
|
|
// ALR IM TOG IC CHS1 CHS0 CRC1 CRC0 |
|
|
|
|
|
// 0 1 0 0 0 1 0 1 0x45 |
|
|
|
|
|
|
|
|
|
|
|
// CHS1 CHS0 Description |
|
|
|
|
|
// 0 0 (not allowed) |
|
|
|
|
|
// 0 1 channel A only |
|
|
|
|
|
// 1 0 channel B only |
|
|
|
|
|
// 1 1 both channels interleaved |
|
|
|
|
|
|
|
|
|
|
|
// TOG IM CHANNELS EFFECT |
|
|
|
|
|
// 0 0 one channel Write all bits to the selected channel |
|
|
|
|
|
// 0 1 one channel Read all bits from the selected channel |
|
|
|
|
|
// 1 0 one channel Write 8 bits, read 8 bits, write, read, etc. to/from the selected channel |
|
|
|
|
|
// 1 1 one channel Read 8 bits, write 8 bits, read, write, etc. from/to the selected channel |
|
|
|
|
|
// 0 0 two channels Repeat: four times (write A, write B) |
|
|
|
|
|
// 0 1 two channels Repeat: four times (read A, read B) |
|
|
|
|
|
// 1 0 two channels Four times: (write A, write B), four times: (readA, read B), write, read, etc. |
|
|
|
|
|
// 1 1 two channels Four times: (read A, read B), four times: (write A, write B), read, write, etc. |
|
|
|
|
|
|
|
|
|
|
|
// CRC1 CRC0 Description |
|
|
|
|
|
// 0 0 CRC disabled (no CRC at all) |
|
|
|
|
|
// 0 1 CRC after every byte |
|
|
|
|
|
// 1 0 CRC after 8 bytes |
|
|
|
|
|
// 1 1 CRC after 32 bytes |
|
|
|
|
|
#define DS2406_CHANNEL_CONTROL_BYTE 0x45; |
|
|
|
|
|
|
|
|
|
|
|
#define DS2406_STATE_BUF_LEN 7 |
|
|
|
|
|
|
|
|
class DallasSensor : public BaseSensor { |
|
|
class DallasSensor : public BaseSensor { |
|
|
|
|
|
|
|
|
public: |
|
|
public: |
|
@ -120,37 +155,68 @@ class DallasSensor : public BaseSensor { |
|
|
// Read scratchpads |
|
|
// Read scratchpads |
|
|
for (unsigned char index=0; index<_devices.size(); index++) { |
|
|
for (unsigned char index=0; index<_devices.size(); index++) { |
|
|
|
|
|
|
|
|
// Read scratchpad |
|
|
|
|
|
if (_wire->reset() == 0) { |
|
|
|
|
|
// Force a CRC check error |
|
|
|
|
|
_devices[index].data[0] = _devices[index].data[0] + 1; |
|
|
|
|
|
return; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
if (_devices[index].address[0] == DS_CHIP_DS2406) { |
|
|
|
|
|
|
|
|
_wire->select(_devices[index].address); |
|
|
|
|
|
_wire->write(DS_CMD_READ_SCRATCHPAD); |
|
|
|
|
|
|
|
|
uint8_t data[DS2406_STATE_BUF_LEN]; |
|
|
|
|
|
|
|
|
uint8_t data[DS_DATA_SIZE]; |
|
|
|
|
|
for (unsigned char i = 0; i < DS_DATA_SIZE; i++) { |
|
|
|
|
|
data[i] = _wire->read(); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
// Read scratchpad |
|
|
|
|
|
if (_wire->reset() == 0) { |
|
|
|
|
|
// Force a CRC check error |
|
|
|
|
|
_devices[index].data[0] = _devices[index].data[0] + 1; |
|
|
|
|
|
return; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
_wire->select(_devices[index].address); |
|
|
|
|
|
|
|
|
if (_wire->reset() != 1) { |
|
|
|
|
|
// Force a CRC check error |
|
|
|
|
|
_devices[index].data[0] = _devices[index].data[0] + 1; |
|
|
|
|
|
return; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
data[0] = DS2406_CHANNEL_ACCESS; |
|
|
|
|
|
data[1] = DS2406_CHANNEL_CONTROL_BYTE; |
|
|
|
|
|
data[2] = 0xFF; |
|
|
|
|
|
|
|
|
memcpy(_devices[index].data, data, DS_DATA_SIZE); |
|
|
|
|
|
|
|
|
_wire->write_bytes(data,3); |
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
// 3 cmd bytes, 1 channel info byte, 1 0x00, 2 CRC16 |
|
|
|
|
|
for(int i = 3; i<DS2406_STATE_BUF_LEN; i++) { |
|
|
|
|
|
data[i] = _wire->read(); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
// Read scratchpad |
|
|
|
|
|
if (_wire->reset() == 0) { |
|
|
|
|
|
// Force a CRC check error |
|
|
|
|
|
_devices[index].data[0] = _devices[index].data[0] + 1; |
|
|
|
|
|
return; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
conversion = !conversion; |
|
|
|
|
|
|
|
|
memcpy(_devices[index].data, data, DS2406_STATE_BUF_LEN); |
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
|
|
|
|
// Read scratchpad |
|
|
|
|
|
if (_wire->reset() == 0) { |
|
|
|
|
|
// Force a CRC check error |
|
|
|
|
|
_devices[index].data[0] = _devices[index].data[0] + 1; |
|
|
|
|
|
return; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
_wire->select(_devices[index].address); |
|
|
|
|
|
_wire->write(DS_CMD_READ_SCRATCHPAD); |
|
|
|
|
|
|
|
|
|
|
|
uint8_t data[DS_DATA_SIZE]; |
|
|
|
|
|
for (unsigned char i = 0; i < DS_DATA_SIZE; i++) { |
|
|
|
|
|
data[i] = _wire->read(); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (_wire->reset() != 1) { |
|
|
|
|
|
// Force a CRC check error |
|
|
|
|
|
_devices[index].data[0] = _devices[index].data[0] + 1; |
|
|
|
|
|
return; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
memcpy(_devices[index].data, data, DS_DATA_SIZE); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
conversion = !conversion; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
// Descriptive name of the sensor |
|
|
// Descriptive name of the sensor |
|
|
String description() { |
|
|
String description() { |
|
@ -190,14 +256,20 @@ class DallasSensor : public BaseSensor { |
|
|
|
|
|
|
|
|
// Type for slot # index |
|
|
// Type for slot # index |
|
|
unsigned char type(unsigned char index) { |
|
|
unsigned char type(unsigned char index) { |
|
|
if (index < _count) return MAGNITUDE_TEMPERATURE; |
|
|
|
|
|
|
|
|
if (index < _count) { |
|
|
|
|
|
if (chip(index) == DS_CHIP_DS2406) { |
|
|
|
|
|
return MAGNITUDE_DIGITAL; |
|
|
|
|
|
} else { |
|
|
|
|
|
return MAGNITUDE_TEMPERATURE; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
return MAGNITUDE_NONE; |
|
|
return MAGNITUDE_NONE; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// Number of decimals for a magnitude (or -1 for default) |
|
|
|
|
|
signed char decimals(unsigned char type) { |
|
|
|
|
|
return 2; // smallest increment is 0.0625 C, so 2 decimals |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
// Number of decimals for a magnitude (or -1 for default) |
|
|
|
|
|
signed char decimals(unsigned char type) { |
|
|
|
|
|
return 2; // smallest increment is 0.0625 C, so 2 decimals |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
// Pre-read hook (usually to populate registers with up-to-date data) |
|
|
// Pre-read hook (usually to populate registers with up-to-date data) |
|
|
void pre() { |
|
|
void pre() { |
|
@ -211,6 +283,26 @@ class DallasSensor : public BaseSensor { |
|
|
|
|
|
|
|
|
uint8_t * data = _devices[index].data; |
|
|
uint8_t * data = _devices[index].data; |
|
|
|
|
|
|
|
|
|
|
|
if (chip(index) == DS_CHIP_DS2406) { |
|
|
|
|
|
|
|
|
|
|
|
if (!OneWire::check_crc16(data, 5, &data[5])) { |
|
|
|
|
|
_error = SENSOR_ERROR_CRC; |
|
|
|
|
|
return 0; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// 3 cmd bytes, 1 channel info byte, 1 0x00, 2 CRC16 |
|
|
|
|
|
// CHANNEL INFO BYTE |
|
|
|
|
|
// Bit 7 : Supply Indication 0 = no supply |
|
|
|
|
|
// Bit 6 : Number of Channels 0 = channel A only |
|
|
|
|
|
// Bit 5 : PIO-B Activity Latch |
|
|
|
|
|
// Bit 4 : PIO-A Activity Latch |
|
|
|
|
|
// Bit 3 : PIO B Sensed Level |
|
|
|
|
|
// Bit 2 : PIO A Sensed Level |
|
|
|
|
|
// Bit 1 : PIO-B Channel Flip-Flop Q |
|
|
|
|
|
// Bit 0 : PIO-A Channel Flip-Flop Q |
|
|
|
|
|
return (data[3] & 0x04) != 0; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
if (OneWire::crc8(data, DS_DATA_SIZE-1) != data[DS_DATA_SIZE-1]) { |
|
|
if (OneWire::crc8(data, DS_DATA_SIZE-1) != data[DS_DATA_SIZE-1]) { |
|
|
_error = SENSOR_ERROR_CRC; |
|
|
_error = SENSOR_ERROR_CRC; |
|
|
return 0; |
|
|
return 0; |
|
@ -261,7 +353,7 @@ class DallasSensor : public BaseSensor { |
|
|
// --------------------------------------------------------------------- |
|
|
// --------------------------------------------------------------------- |
|
|
|
|
|
|
|
|
bool validateID(unsigned char id) { |
|
|
bool validateID(unsigned char id) { |
|
|
return (id == DS_CHIP_DS18S20) || (id == DS_CHIP_DS18B20) || (id == DS_CHIP_DS1822) || (id == DS_CHIP_DS1825); |
|
|
|
|
|
|
|
|
return (id == DS_CHIP_DS18S20) || (id == DS_CHIP_DS18B20) || (id == DS_CHIP_DS1822) || (id == DS_CHIP_DS1825) || (id == DS_CHIP_DS2406) ; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
unsigned char chip(unsigned char index) { |
|
|
unsigned char chip(unsigned char index) { |
|
@ -275,6 +367,7 @@ class DallasSensor : public BaseSensor { |
|
|
if (chip_id == DS_CHIP_DS18B20) return String("DS18B20"); |
|
|
if (chip_id == DS_CHIP_DS18B20) return String("DS18B20"); |
|
|
if (chip_id == DS_CHIP_DS1822) return String("DS1822"); |
|
|
if (chip_id == DS_CHIP_DS1822) return String("DS1822"); |
|
|
if (chip_id == DS_CHIP_DS1825) return String("DS1825"); |
|
|
if (chip_id == DS_CHIP_DS1825) return String("DS1825"); |
|
|
|
|
|
if (chip_id == DS_CHIP_DS2406) return String("DS2406"); |
|
|
return String("Unknown"); |
|
|
return String("Unknown"); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|