Library for reading temperature from DS1820, DS18B20 and DS1822

Dependencies:   LinkedList

Dependents:   heatmap BLE_Temperature BLE_Temperature_Exercise F334andDS18B20 ... more

Fork of DS1820 by David Pairman

HelloWorld: http://mbed.org/users/Sissors/code/DS1820_HelloWorld/

Library should currently work on all mbed targets, let me know if there is an issue. First however make sure you have latest version of mbed library and this library.

Committer:
Sissors
Date:
Sat Mar 11 20:35:59 2017 +0000
Revision:
15:236eb8f8e73a
Parent:
14:c591209285e9
Removed specialized STM code (still uses OpenDrain mode), should work now still.
;
; Added NRF51822 support by adding a software delay function.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
pairmand 3:8f2b7f4940b5 1 #include "DS1820.h"
Sissors 5:2cd4928e8147 2
Sissors 14:c591209285e9 3 #ifdef TARGET_STM
Sissors 15:236eb8f8e73a 4 //STM targets use opendrain mode since their switching between input and output is slow
Sissors 14:c591209285e9 5 #define ONEWIRE_INPUT(pin) pin->write(1)
Sissors 14:c591209285e9 6 #define ONEWIRE_OUTPUT(pin)
Sissors 14:c591209285e9 7 #define ONEWIRE_INIT(pin) pin->output(); pin->mode(OpenDrain)
Sissors 14:c591209285e9 8 #else
Sissors 14:c591209285e9 9 #define ONEWIRE_INPUT(pin) pin->input()
Sissors 14:c591209285e9 10 #define ONEWIRE_OUTPUT(pin) pin->output()
Sissors 14:c591209285e9 11 #define ONEWIRE_INIT(pin)
Sissors 14:c591209285e9 12 #endif
Sissors 14:c591209285e9 13
Sissors 15:236eb8f8e73a 14 #ifdef TARGET_NORDIC
Sissors 15:236eb8f8e73a 15 //NORDIC targets (NRF) use software delays since their ticker uses a 32kHz clock
Sissors 15:236eb8f8e73a 16 static uint32_t loops_per_us = 0;
Sissors 15:236eb8f8e73a 17
Sissors 15:236eb8f8e73a 18 #define INIT_DELAY init_soft_delay()
Sissors 15:236eb8f8e73a 19 #define ONEWIRE_DELAY_US(value) for(int cnt = 0; cnt < (value * loops_per_us) >> 5; cnt++) {__NOP(); __NOP(); __NOP();}
Sissors 15:236eb8f8e73a 20
Sissors 15:236eb8f8e73a 21 void init_soft_delay( void ) {
Sissors 15:236eb8f8e73a 22 if (loops_per_us == 0) {
Sissors 15:236eb8f8e73a 23 loops_per_us = 1;
Sissors 15:236eb8f8e73a 24 Timer timey;
Sissors 15:236eb8f8e73a 25 timey.start();
Sissors 15:236eb8f8e73a 26 ONEWIRE_DELAY_US(320000);
Sissors 15:236eb8f8e73a 27 timey.stop();
Sissors 15:236eb8f8e73a 28 loops_per_us = (320000 + timey.read_us() / 2) / timey.read_us();
Sissors 15:236eb8f8e73a 29 }
Sissors 15:236eb8f8e73a 30 }
Sissors 15:236eb8f8e73a 31 #else
Sissors 15:236eb8f8e73a 32 #define INIT_DELAY
Sissors 15:236eb8f8e73a 33 #define ONEWIRE_DELAY_US(value) wait_us(value)
Sissors 15:236eb8f8e73a 34 #endif
Sissors 15:236eb8f8e73a 35
Sissors 5:2cd4928e8147 36 LinkedList<node> DS1820::probes;
pairmand 3:8f2b7f4940b5 37
pairmand 3:8f2b7f4940b5 38
Sissors 5:2cd4928e8147 39 DS1820::DS1820 (PinName data_pin, PinName power_pin, bool power_polarity) : _datapin(data_pin), _parasitepin(power_pin) {
pairmand 3:8f2b7f4940b5 40 int byte_counter;
Sissors 5:2cd4928e8147 41 _power_polarity = power_polarity;
florian 9:3821ca0b7f14 42
florian 9:3821ca0b7f14 43 _power_mosfet = power_pin != NC;
Sissors 5:2cd4928e8147 44
pairmand 3:8f2b7f4940b5 45 for(byte_counter=0;byte_counter<9;byte_counter++)
pairmand 3:8f2b7f4940b5 46 RAM[byte_counter] = 0x00;
Sissors 5:2cd4928e8147 47
Sissors 14:c591209285e9 48 ONEWIRE_INIT((&_datapin));
Sissors 15:236eb8f8e73a 49 INIT_DELAY;
Sissors 14:c591209285e9 50
Sissors 5:2cd4928e8147 51 if (!unassignedProbe(&_datapin, _ROM))
Sissors 5:2cd4928e8147 52 error("No unassigned DS1820 found!\n");
Sissors 5:2cd4928e8147 53 else {
Sissors 5:2cd4928e8147 54 _datapin.input();
Sissors 5:2cd4928e8147 55 probes.append(this);
Sissors 5:2cd4928e8147 56 _parasite_power = !read_power_supply();
Sissors 5:2cd4928e8147 57 }
pairmand 3:8f2b7f4940b5 58 }
Sissors 5:2cd4928e8147 59
Sissors 5:2cd4928e8147 60 DS1820::~DS1820 (void) {
Sissors 5:2cd4928e8147 61 node *tmp;
Sissors 5:2cd4928e8147 62 for(int i=1; i<=probes.length(); i++)
Sissors 5:2cd4928e8147 63 {
Sissors 5:2cd4928e8147 64 tmp = probes.pop(i);
Sissors 5:2cd4928e8147 65 if (tmp->data == this)
Sissors 5:2cd4928e8147 66 probes.remove(i);
Sissors 5:2cd4928e8147 67 }
pairmand 3:8f2b7f4940b5 68 }
Sissors 5:2cd4928e8147 69
pairmand 3:8f2b7f4940b5 70
Sissors 5:2cd4928e8147 71 bool DS1820::onewire_reset(DigitalInOut *pin) {
pairmand 3:8f2b7f4940b5 72 // This will return false if no devices are present on the data bus
pairmand 3:8f2b7f4940b5 73 bool presence=false;
Sissors 14:c591209285e9 74 ONEWIRE_OUTPUT(pin);
Sissors 5:2cd4928e8147 75 pin->write(0); // bring low for 500 us
Sissors 15:236eb8f8e73a 76 ONEWIRE_DELAY_US(500);
Sissors 14:c591209285e9 77 ONEWIRE_INPUT(pin); // let the data line float high
Sissors 15:236eb8f8e73a 78 ONEWIRE_DELAY_US(90); // wait 90us
Sissors 5:2cd4928e8147 79 if (pin->read()==0) // see if any devices are pulling the data line low
pairmand 3:8f2b7f4940b5 80 presence=true;
Sissors 15:236eb8f8e73a 81 ONEWIRE_DELAY_US(410);
pairmand 3:8f2b7f4940b5 82 return presence;
pairmand 3:8f2b7f4940b5 83 }
pairmand 3:8f2b7f4940b5 84
Sissors 5:2cd4928e8147 85 void DS1820::onewire_bit_out (DigitalInOut *pin, bool bit_data) {
Sissors 14:c591209285e9 86 ONEWIRE_OUTPUT(pin);
Sissors 5:2cd4928e8147 87 pin->write(0);
Sissors 15:236eb8f8e73a 88 ONEWIRE_DELAY_US(3); // DXP modified from 5
pairmand 3:8f2b7f4940b5 89 if (bit_data) {
Sissors 8:d87e11e8d012 90 pin->write(1); // bring data line high
Sissors 15:236eb8f8e73a 91 ONEWIRE_DELAY_US(55);
pairmand 3:8f2b7f4940b5 92 } else {
Sissors 15:236eb8f8e73a 93 ONEWIRE_DELAY_US(55); // keep data line low
Sissors 8:d87e11e8d012 94 pin->write(1);
Sissors 15:236eb8f8e73a 95 ONEWIRE_DELAY_US(10); // DXP added to allow bus to float high before next bit_out
pairmand 3:8f2b7f4940b5 96 }
pairmand 3:8f2b7f4940b5 97 }
pairmand 3:8f2b7f4940b5 98
pairmand 3:8f2b7f4940b5 99 void DS1820::onewire_byte_out(char data) { // output data character (least sig bit first).
pairmand 3:8f2b7f4940b5 100 int n;
pairmand 3:8f2b7f4940b5 101 for (n=0; n<8; n++) {
Sissors 5:2cd4928e8147 102 onewire_bit_out(&this->_datapin, data & 0x01);
pairmand 3:8f2b7f4940b5 103 data = data >> 1; // now the next bit is in the least sig bit position.
pairmand 3:8f2b7f4940b5 104 }
pairmand 3:8f2b7f4940b5 105 }
pairmand 3:8f2b7f4940b5 106
Sissors 5:2cd4928e8147 107 bool DS1820::onewire_bit_in(DigitalInOut *pin) {
pairmand 3:8f2b7f4940b5 108 bool answer;
Sissors 14:c591209285e9 109 ONEWIRE_OUTPUT(pin);
Sissors 5:2cd4928e8147 110 pin->write(0);
Sissors 15:236eb8f8e73a 111 ONEWIRE_DELAY_US(3); // DXP modofied from 5
Sissors 14:c591209285e9 112 ONEWIRE_INPUT(pin);
Sissors 15:236eb8f8e73a 113 ONEWIRE_DELAY_US(10); // DXP modified from 5
Sissors 5:2cd4928e8147 114 answer = pin->read();
Sissors 15:236eb8f8e73a 115 ONEWIRE_DELAY_US(45); // DXP modified from 50
pairmand 3:8f2b7f4940b5 116 return answer;
pairmand 3:8f2b7f4940b5 117 }
pairmand 3:8f2b7f4940b5 118
pairmand 3:8f2b7f4940b5 119 char DS1820::onewire_byte_in() { // read byte, least sig byte first
pairmand 3:8f2b7f4940b5 120 char answer = 0x00;
pairmand 3:8f2b7f4940b5 121 int i;
pairmand 3:8f2b7f4940b5 122 for (i=0; i<8; i++) {
pairmand 3:8f2b7f4940b5 123 answer = answer >> 1; // shift over to make room for the next bit
Sissors 5:2cd4928e8147 124 if (onewire_bit_in(&this->_datapin))
pairmand 3:8f2b7f4940b5 125 answer = answer | 0x80; // if the data port is high, make this bit a 1
pairmand 3:8f2b7f4940b5 126 }
pairmand 3:8f2b7f4940b5 127 return answer;
pairmand 3:8f2b7f4940b5 128 }
Sissors 5:2cd4928e8147 129
Sissors 5:2cd4928e8147 130 bool DS1820::unassignedProbe(PinName pin) {
Sissors 5:2cd4928e8147 131 DigitalInOut _pin(pin);
Sissors 14:c591209285e9 132 ONEWIRE_INIT((&_pin));
Sissors 15:236eb8f8e73a 133 INIT_DELAY;
Sissors 5:2cd4928e8147 134 char ROM_address[8];
Sissors 5:2cd4928e8147 135 return search_ROM_routine(&_pin, 0xF0, ROM_address);
pairmand 3:8f2b7f4940b5 136 }
pairmand 3:8f2b7f4940b5 137
Sissors 5:2cd4928e8147 138 bool DS1820::unassignedProbe(DigitalInOut *pin, char *ROM_address) {
Sissors 5:2cd4928e8147 139 return search_ROM_routine(pin, 0xF0, ROM_address);
pairmand 3:8f2b7f4940b5 140 }
pairmand 3:8f2b7f4940b5 141
Sissors 5:2cd4928e8147 142 bool DS1820::search_ROM_routine(DigitalInOut *pin, char command, char *ROM_address) {
Sissors 5:2cd4928e8147 143 bool DS1820_done_flag = false;
Sissors 5:2cd4928e8147 144 int DS1820_last_descrepancy = 0;
Sissors 5:2cd4928e8147 145 char DS1820_search_ROM[8] = {0, 0, 0, 0, 0, 0, 0, 0};
Sissors 5:2cd4928e8147 146
pairmand 3:8f2b7f4940b5 147 int descrepancy_marker, ROM_bit_index;
pairmand 3:8f2b7f4940b5 148 bool return_value, Bit_A, Bit_B;
pairmand 3:8f2b7f4940b5 149 char byte_counter, bit_mask;
pairmand 3:8f2b7f4940b5 150
pairmand 3:8f2b7f4940b5 151 return_value=false;
Sissors 5:2cd4928e8147 152 while (!DS1820_done_flag) {
Sissors 5:2cd4928e8147 153 if (!onewire_reset(pin)) {
Sissors 5:2cd4928e8147 154 return false;
pairmand 3:8f2b7f4940b5 155 } else {
pairmand 3:8f2b7f4940b5 156 ROM_bit_index=1;
pairmand 3:8f2b7f4940b5 157 descrepancy_marker=0;
Sissors 12:196e9e54b033 158 char command_shift = command;
Sissors 5:2cd4928e8147 159 for (int n=0; n<8; n++) { // Search ROM command or Search Alarm command
Sissors 12:196e9e54b033 160 onewire_bit_out(pin, command_shift & 0x01);
Sissors 12:196e9e54b033 161 command_shift = command_shift >> 1; // now the next bit is in the least sig bit position.
Sissors 5:2cd4928e8147 162 }
pairmand 3:8f2b7f4940b5 163 byte_counter = 0;
pairmand 3:8f2b7f4940b5 164 bit_mask = 0x01;
pairmand 3:8f2b7f4940b5 165 while (ROM_bit_index<=64) {
Sissors 5:2cd4928e8147 166 Bit_A = onewire_bit_in(pin);
Sissors 5:2cd4928e8147 167 Bit_B = onewire_bit_in(pin);
pairmand 3:8f2b7f4940b5 168 if (Bit_A & Bit_B) {
pairmand 3:8f2b7f4940b5 169 descrepancy_marker = 0; // data read error, this should never happen
pairmand 3:8f2b7f4940b5 170 ROM_bit_index = 0xFF;
pairmand 3:8f2b7f4940b5 171 } else {
pairmand 3:8f2b7f4940b5 172 if (Bit_A | Bit_B) {
pairmand 3:8f2b7f4940b5 173 // Set ROM bit to Bit_A
pairmand 3:8f2b7f4940b5 174 if (Bit_A) {
pairmand 3:8f2b7f4940b5 175 DS1820_search_ROM[byte_counter] = DS1820_search_ROM[byte_counter] | bit_mask; // Set ROM bit to one
pairmand 3:8f2b7f4940b5 176 } else {
pairmand 3:8f2b7f4940b5 177 DS1820_search_ROM[byte_counter] = DS1820_search_ROM[byte_counter] & ~bit_mask; // Set ROM bit to zero
pairmand 3:8f2b7f4940b5 178 }
pairmand 3:8f2b7f4940b5 179 } else {
pairmand 3:8f2b7f4940b5 180 // both bits A and B are low, so there are two or more devices present
pairmand 3:8f2b7f4940b5 181 if ( ROM_bit_index == DS1820_last_descrepancy ) {
pairmand 3:8f2b7f4940b5 182 DS1820_search_ROM[byte_counter] = DS1820_search_ROM[byte_counter] | bit_mask; // Set ROM bit to one
pairmand 3:8f2b7f4940b5 183 } else {
pairmand 3:8f2b7f4940b5 184 if ( ROM_bit_index > DS1820_last_descrepancy ) {
pairmand 3:8f2b7f4940b5 185 DS1820_search_ROM[byte_counter] = DS1820_search_ROM[byte_counter] & ~bit_mask; // Set ROM bit to zero
pairmand 3:8f2b7f4940b5 186 descrepancy_marker = ROM_bit_index;
pairmand 3:8f2b7f4940b5 187 } else {
pairmand 3:8f2b7f4940b5 188 if (( DS1820_search_ROM[byte_counter] & bit_mask) == 0x00 )
pairmand 3:8f2b7f4940b5 189 descrepancy_marker = ROM_bit_index;
pairmand 3:8f2b7f4940b5 190 }
pairmand 3:8f2b7f4940b5 191 }
pairmand 3:8f2b7f4940b5 192 }
Sissors 5:2cd4928e8147 193 onewire_bit_out (pin, DS1820_search_ROM[byte_counter] & bit_mask);
pairmand 3:8f2b7f4940b5 194 ROM_bit_index++;
pairmand 3:8f2b7f4940b5 195 if (bit_mask & 0x80) {
pairmand 3:8f2b7f4940b5 196 byte_counter++;
pairmand 3:8f2b7f4940b5 197 bit_mask = 0x01;
pairmand 3:8f2b7f4940b5 198 } else {
pairmand 3:8f2b7f4940b5 199 bit_mask = bit_mask << 1;
pairmand 3:8f2b7f4940b5 200 }
pairmand 3:8f2b7f4940b5 201 }
pairmand 3:8f2b7f4940b5 202 }
pairmand 3:8f2b7f4940b5 203 DS1820_last_descrepancy = descrepancy_marker;
pairmand 3:8f2b7f4940b5 204 if (ROM_bit_index != 0xFF) {
Sissors 5:2cd4928e8147 205 int i = 1;
Sissors 5:2cd4928e8147 206 node *list_container;
Sissors 5:2cd4928e8147 207 while(1) {
Sissors 5:2cd4928e8147 208 list_container = probes.pop(i);
Sissors 5:2cd4928e8147 209 if (list_container == NULL) { //End of list, or empty list
Sissors 5:2cd4928e8147 210 if (ROM_checksum_error(DS1820_search_ROM)) { // Check the CRC
Sissors 5:2cd4928e8147 211 return false;
Sissors 5:2cd4928e8147 212 }
Sissors 5:2cd4928e8147 213 for(byte_counter=0;byte_counter<8;byte_counter++)
Sissors 5:2cd4928e8147 214 ROM_address[byte_counter] = DS1820_search_ROM[byte_counter];
Sissors 5:2cd4928e8147 215 return true;
Sissors 5:2cd4928e8147 216 } else { //Otherwise, check if ROM is already known
Sissors 5:2cd4928e8147 217 bool equal = true;
Sissors 5:2cd4928e8147 218 DS1820 *pointer = (DS1820*) list_container->data;
Sissors 5:2cd4928e8147 219 char *ROM_compare = pointer->_ROM;
Sissors 5:2cd4928e8147 220
Sissors 5:2cd4928e8147 221 for(byte_counter=0;byte_counter<8;byte_counter++) {
Sissors 5:2cd4928e8147 222 if ( ROM_compare[byte_counter] != DS1820_search_ROM[byte_counter])
Sissors 5:2cd4928e8147 223 equal = false;
Sissors 5:2cd4928e8147 224 }
Sissors 5:2cd4928e8147 225 if (equal)
Sissors 5:2cd4928e8147 226 break;
Sissors 5:2cd4928e8147 227 else
Sissors 5:2cd4928e8147 228 i++;
Sissors 5:2cd4928e8147 229 }
Sissors 5:2cd4928e8147 230 }
pairmand 3:8f2b7f4940b5 231 }
pairmand 3:8f2b7f4940b5 232 }
pairmand 3:8f2b7f4940b5 233 if (DS1820_last_descrepancy == 0)
pairmand 3:8f2b7f4940b5 234 DS1820_done_flag = true;
pairmand 3:8f2b7f4940b5 235 }
pairmand 3:8f2b7f4940b5 236 return return_value;
pairmand 3:8f2b7f4940b5 237 }
pairmand 3:8f2b7f4940b5 238
pairmand 3:8f2b7f4940b5 239 void DS1820::match_ROM() {
pairmand 3:8f2b7f4940b5 240 // Used to select a specific device
pairmand 3:8f2b7f4940b5 241 int i;
Sissors 5:2cd4928e8147 242 onewire_reset(&this->_datapin);
pairmand 3:8f2b7f4940b5 243 onewire_byte_out( 0x55); //Match ROM command
Sissors 5:2cd4928e8147 244 for (i=0;i<8;i++) {
Sissors 5:2cd4928e8147 245 onewire_byte_out(_ROM[i]);
Sissors 5:2cd4928e8147 246 }
pairmand 3:8f2b7f4940b5 247 }
pairmand 3:8f2b7f4940b5 248
pairmand 3:8f2b7f4940b5 249 void DS1820::skip_ROM() {
Sissors 5:2cd4928e8147 250 onewire_reset(&this->_datapin);
pairmand 3:8f2b7f4940b5 251 onewire_byte_out(0xCC); // Skip ROM command
pairmand 3:8f2b7f4940b5 252 }
pairmand 3:8f2b7f4940b5 253
Sissors 5:2cd4928e8147 254 bool DS1820::ROM_checksum_error(char *_ROM_address) {
Sissors 11:1a3c3002b50c 255 char _CRC=0x00;
pairmand 3:8f2b7f4940b5 256 int i;
pairmand 3:8f2b7f4940b5 257 for(i=0;i<7;i++) // Only going to shift the lower 7 bytes
Sissors 11:1a3c3002b50c 258 _CRC = CRC_byte(_CRC, _ROM_address[i]);
pairmand 3:8f2b7f4940b5 259 // After 7 bytes CRC should equal the 8th byte (ROM CRC)
Sissors 11:1a3c3002b50c 260 return (_CRC!=_ROM_address[7]); // will return true if there is a CRC checksum mis-match
pairmand 3:8f2b7f4940b5 261 }
pairmand 3:8f2b7f4940b5 262
pairmand 3:8f2b7f4940b5 263 bool DS1820::RAM_checksum_error() {
Sissors 11:1a3c3002b50c 264 char _CRC=0x00;
pairmand 3:8f2b7f4940b5 265 int i;
pairmand 3:8f2b7f4940b5 266 for(i=0;i<8;i++) // Only going to shift the lower 8 bytes
Sissors 11:1a3c3002b50c 267 _CRC = CRC_byte(_CRC, RAM[i]);
pairmand 3:8f2b7f4940b5 268 // After 8 bytes CRC should equal the 9th byte (RAM CRC)
Sissors 11:1a3c3002b50c 269 return (_CRC!=RAM[8]); // will return true if there is a CRC checksum mis-match
pairmand 3:8f2b7f4940b5 270 }
pairmand 3:8f2b7f4940b5 271
Sissors 11:1a3c3002b50c 272 char DS1820::CRC_byte (char _CRC, char byte ) {
pairmand 3:8f2b7f4940b5 273 int j;
pairmand 3:8f2b7f4940b5 274 for(j=0;j<8;j++) {
Sissors 11:1a3c3002b50c 275 if ((byte & 0x01 ) ^ (_CRC & 0x01)) {
pairmand 3:8f2b7f4940b5 276 // DATA ^ LSB CRC = 1
Sissors 11:1a3c3002b50c 277 _CRC = _CRC>>1;
pairmand 3:8f2b7f4940b5 278 // Set the MSB to 1
Sissors 11:1a3c3002b50c 279 _CRC = _CRC | 0x80;
pairmand 3:8f2b7f4940b5 280 // Check bit 3
Sissors 11:1a3c3002b50c 281 if (_CRC & 0x04) {
Sissors 11:1a3c3002b50c 282 _CRC = _CRC & 0xFB; // Bit 3 is set, so clear it
pairmand 3:8f2b7f4940b5 283 } else {
Sissors 11:1a3c3002b50c 284 _CRC = _CRC | 0x04; // Bit 3 is clear, so set it
pairmand 3:8f2b7f4940b5 285 }
pairmand 3:8f2b7f4940b5 286 // Check bit 4
Sissors 11:1a3c3002b50c 287 if (_CRC & 0x08) {
Sissors 11:1a3c3002b50c 288 _CRC = _CRC & 0xF7; // Bit 4 is set, so clear it
pairmand 3:8f2b7f4940b5 289 } else {
Sissors 11:1a3c3002b50c 290 _CRC = _CRC | 0x08; // Bit 4 is clear, so set it
pairmand 3:8f2b7f4940b5 291 }
pairmand 3:8f2b7f4940b5 292 } else {
pairmand 3:8f2b7f4940b5 293 // DATA ^ LSB CRC = 0
Sissors 11:1a3c3002b50c 294 _CRC = _CRC>>1;
pairmand 3:8f2b7f4940b5 295 // clear MSB
Sissors 11:1a3c3002b50c 296 _CRC = _CRC & 0x7F;
pairmand 3:8f2b7f4940b5 297 // No need to check bits, with DATA ^ LSB CRC = 0, they will remain unchanged
pairmand 3:8f2b7f4940b5 298 }
pairmand 3:8f2b7f4940b5 299 byte = byte>>1;
pairmand 3:8f2b7f4940b5 300 }
Sissors 11:1a3c3002b50c 301 return _CRC;
pairmand 3:8f2b7f4940b5 302 }
pairmand 3:8f2b7f4940b5 303
Sissors 5:2cd4928e8147 304 int DS1820::convertTemperature(bool wait, devices device) {
pairmand 3:8f2b7f4940b5 305 // Convert temperature into scratchpad RAM for all devices at once
pairmand 3:8f2b7f4940b5 306 int delay_time = 750; // Default delay time
pairmand 3:8f2b7f4940b5 307 char resolution;
pairmand 3:8f2b7f4940b5 308 if (device==all_devices)
pairmand 3:8f2b7f4940b5 309 skip_ROM(); // Skip ROM command, will convert for ALL devices
pairmand 3:8f2b7f4940b5 310 else {
pairmand 3:8f2b7f4940b5 311 match_ROM();
Sissors 5:2cd4928e8147 312 if ((FAMILY_CODE == FAMILY_CODE_DS18B20 ) || (FAMILY_CODE == FAMILY_CODE_DS1822 )) {
pairmand 3:8f2b7f4940b5 313 resolution = RAM[4] & 0x60;
pairmand 3:8f2b7f4940b5 314 if (resolution == 0x00) // 9 bits
pairmand 3:8f2b7f4940b5 315 delay_time = 94;
pairmand 3:8f2b7f4940b5 316 if (resolution == 0x20) // 10 bits
pairmand 3:8f2b7f4940b5 317 delay_time = 188;
pairmand 3:8f2b7f4940b5 318 if (resolution == 0x40) // 11 bits. Note 12bits uses the 750ms default
pairmand 3:8f2b7f4940b5 319 delay_time = 375;
pairmand 3:8f2b7f4940b5 320 }
pairmand 3:8f2b7f4940b5 321 }
Sissors 5:2cd4928e8147 322
pairmand 3:8f2b7f4940b5 323 onewire_byte_out( 0x44); // perform temperature conversion
pairmand 3:8f2b7f4940b5 324 if (_parasite_power) {
Sissors 5:2cd4928e8147 325 if (_power_mosfet) {
Sissors 5:2cd4928e8147 326 _parasitepin = _power_polarity; // Parasite power strong pullup
Sissors 5:2cd4928e8147 327 wait_ms(delay_time);
Sissors 5:2cd4928e8147 328 _parasitepin = !_power_polarity;
Sissors 5:2cd4928e8147 329 delay_time = 0;
Sissors 5:2cd4928e8147 330 } else {
Sissors 5:2cd4928e8147 331 _datapin.output();
Sissors 5:2cd4928e8147 332 _datapin.write(1);
Sissors 5:2cd4928e8147 333 wait_ms(delay_time);
Sissors 5:2cd4928e8147 334 _datapin.input();
Sissors 5:2cd4928e8147 335 }
pairmand 3:8f2b7f4940b5 336 } else {
pairmand 3:8f2b7f4940b5 337 if (wait) {
pairmand 3:8f2b7f4940b5 338 wait_ms(delay_time);
pairmand 3:8f2b7f4940b5 339 delay_time = 0;
pairmand 3:8f2b7f4940b5 340 }
pairmand 3:8f2b7f4940b5 341 }
pairmand 3:8f2b7f4940b5 342 return delay_time;
pairmand 3:8f2b7f4940b5 343 }
pairmand 3:8f2b7f4940b5 344
pairmand 3:8f2b7f4940b5 345 void DS1820::read_RAM() {
pairmand 3:8f2b7f4940b5 346 // This will copy the DS1820's 9 bytes of RAM data
pairmand 3:8f2b7f4940b5 347 // into the objects RAM array. Functions that use
pairmand 3:8f2b7f4940b5 348 // RAM values will automaticly call this procedure.
pairmand 3:8f2b7f4940b5 349 int i;
pairmand 3:8f2b7f4940b5 350 match_ROM(); // Select this device
pairmand 3:8f2b7f4940b5 351 onewire_byte_out( 0xBE); //Read Scratchpad command
pairmand 3:8f2b7f4940b5 352 for(i=0;i<9;i++) {
pairmand 3:8f2b7f4940b5 353 RAM[i] = onewire_byte_in();
pairmand 3:8f2b7f4940b5 354 }
pairmand 3:8f2b7f4940b5 355 // if (!RAM_checksum_error())
pairmand 3:8f2b7f4940b5 356 // crcerr = 1;
pairmand 3:8f2b7f4940b5 357 }
pairmand 3:8f2b7f4940b5 358
Sissors 5:2cd4928e8147 359 bool DS1820::setResolution(unsigned int resolution) {
pairmand 3:8f2b7f4940b5 360 bool answer = false;
pairmand 3:8f2b7f4940b5 361 resolution = resolution - 9;
pairmand 3:8f2b7f4940b5 362 if (resolution < 4) {
pairmand 3:8f2b7f4940b5 363 resolution = resolution<<5; // align the bits
pairmand 3:8f2b7f4940b5 364 RAM[4] = (RAM[4] & 0x60) | resolution; // mask out old data, insert new
pairmand 3:8f2b7f4940b5 365 write_scratchpad ((RAM[2]<<8) + RAM[3]);
pairmand 3:8f2b7f4940b5 366 // store_scratchpad (DS1820::this_device); // Need to test if this is required
pairmand 3:8f2b7f4940b5 367 answer = true;
pairmand 3:8f2b7f4940b5 368 }
pairmand 3:8f2b7f4940b5 369 return answer;
pairmand 3:8f2b7f4940b5 370 }
pairmand 3:8f2b7f4940b5 371
pairmand 3:8f2b7f4940b5 372 void DS1820::write_scratchpad(int data) {
pairmand 3:8f2b7f4940b5 373 RAM[3] = data;
pairmand 3:8f2b7f4940b5 374 RAM[2] = data>>8;
pairmand 3:8f2b7f4940b5 375 match_ROM();
pairmand 3:8f2b7f4940b5 376 onewire_byte_out(0x4E); // Copy scratchpad into DS1820 ram memory
pairmand 3:8f2b7f4940b5 377 onewire_byte_out(RAM[2]); // T(H)
pairmand 3:8f2b7f4940b5 378 onewire_byte_out(RAM[3]); // T(L)
Sissors 5:2cd4928e8147 379 if ((FAMILY_CODE == FAMILY_CODE_DS18B20 ) || (FAMILY_CODE == FAMILY_CODE_DS1822 )) {
pairmand 3:8f2b7f4940b5 380 onewire_byte_out(RAM[4]); // Configuration register
pairmand 3:8f2b7f4940b5 381 }
pairmand 3:8f2b7f4940b5 382 }
pairmand 3:8f2b7f4940b5 383
pairmand 3:8f2b7f4940b5 384 float DS1820::temperature(char scale) {
pairmand 3:8f2b7f4940b5 385 // The data specs state that count_per_degree should be 0x10 (16), I found my devices
pairmand 3:8f2b7f4940b5 386 // to have a count_per_degree of 0x4B (75). With the standard resolution of 1/2 deg C
pairmand 3:8f2b7f4940b5 387 // this allowed an expanded resolution of 1/150th of a deg C. I wouldn't rely on this
pairmand 3:8f2b7f4940b5 388 // being super acurate, but it does allow for a smooth display in the 1/10ths of a
pairmand 3:8f2b7f4940b5 389 // deg C or F scales.
pairmand 3:8f2b7f4940b5 390 float answer, remaining_count, count_per_degree;
pairmand 3:8f2b7f4940b5 391 int reading;
pairmand 3:8f2b7f4940b5 392 read_RAM();
pairmand 3:8f2b7f4940b5 393 if (RAM_checksum_error())
pairmand 3:8f2b7f4940b5 394 // Indicate we got a CRC error
Sissors 7:58b61681818f 395 answer = invalid_conversion;
pairmand 3:8f2b7f4940b5 396 else {
pairmand 3:8f2b7f4940b5 397 reading = (RAM[1] << 8) + RAM[0];
pairmand 3:8f2b7f4940b5 398 if (reading & 0x8000) { // negative degrees C
pairmand 3:8f2b7f4940b5 399 reading = 0-((reading ^ 0xffff) + 1); // 2's comp then convert to signed int
pairmand 3:8f2b7f4940b5 400 }
pairmand 3:8f2b7f4940b5 401 answer = reading +0.0; // convert to floating point
Sissors 5:2cd4928e8147 402 if ((FAMILY_CODE == FAMILY_CODE_DS18B20 ) || (FAMILY_CODE == FAMILY_CODE_DS1822 )) {
Sissors 11:1a3c3002b50c 403 answer = answer / 16.0f;
pairmand 3:8f2b7f4940b5 404 }
pairmand 3:8f2b7f4940b5 405 else {
pairmand 3:8f2b7f4940b5 406 remaining_count = RAM[6];
pairmand 3:8f2b7f4940b5 407 count_per_degree = RAM[7];
Sissors 11:1a3c3002b50c 408 answer = floor(answer/2.0f) - 0.25f + (count_per_degree - remaining_count) / count_per_degree;
pairmand 3:8f2b7f4940b5 409 }
florian 10:d297ce9ce422 410 if (scale=='F' or scale=='f')
pairmand 3:8f2b7f4940b5 411 // Convert to deg F
Sissors 11:1a3c3002b50c 412 answer = answer * 9.0f / 5.0f + 32.0f;
pairmand 3:8f2b7f4940b5 413 }
pairmand 3:8f2b7f4940b5 414 return answer;
pairmand 3:8f2b7f4940b5 415 }
pairmand 3:8f2b7f4940b5 416
pairmand 3:8f2b7f4940b5 417 bool DS1820::read_power_supply(devices device) {
pairmand 3:8f2b7f4940b5 418 // This will return true if the device (or all devices) are Vcc powered
pairmand 3:8f2b7f4940b5 419 // This will return false if the device (or ANY device) is parasite powered
pairmand 3:8f2b7f4940b5 420 if (device==all_devices)
pairmand 3:8f2b7f4940b5 421 skip_ROM(); // Skip ROM command, will poll for any device using parasite power
pairmand 3:8f2b7f4940b5 422 else
pairmand 3:8f2b7f4940b5 423 match_ROM();
pairmand 3:8f2b7f4940b5 424 onewire_byte_out(0xB4); // Read power supply command
Sissors 5:2cd4928e8147 425 return onewire_bit_in(&this->_datapin);
pairmand 3:8f2b7f4940b5 426 }
pairmand 3:8f2b7f4940b5 427
pairmand 3:8f2b7f4940b5 428