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:
Sun Jan 08 17:26:21 2017 +0000
Revision:
14:c591209285e9
Parent:
12:196e9e54b033
Child:
15:236eb8f8e73a
Switched for STM devices to OpenDrain mode. Since also OpenDrain mode is bugged for STM devices it has a workaround to properly enable it. Should be removed once STM fixes it in the mbed lib.

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