Yet another DS1820 lib, but this one is make in sweat of struggling with other ones. It's a fork really of <insert original as mbed doesn't track idk why> with *added capability* of not blocking.

Dependents:   Nucleo_praktyki

Committer:
amateusz
Date:
Sat Sep 02 20:13:38 2017 +0000
Revision:
1:1020ba9ab5d2
Parent:
0:3968e3a2e047
Non blocking convert. Updates internal variable, which can be read by temperature() method.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
amateusz 0:3968e3a2e047 1 #include "DS1820.h"
amateusz 0:3968e3a2e047 2 #include "mbed.h"
amateusz 0:3968e3a2e047 3
amateusz 0:3968e3a2e047 4 // Global variables shared between all DS1820 objects
amateusz 0:3968e3a2e047 5 bool DS1820_done_flag;
amateusz 0:3968e3a2e047 6 int DS1820_last_descrepancy;
amateusz 0:3968e3a2e047 7 char DS1820_search_ROM[8];
amateusz 0:3968e3a2e047 8
amateusz 0:3968e3a2e047 9
amateusz 0:3968e3a2e047 10 DS1820::DS1820 (PinName data_pin, PinName power_pin) : _datapin(data_pin), _parasitepin(power_pin)
amateusz 0:3968e3a2e047 11 {
amateusz 0:3968e3a2e047 12 int byte_counter;
amateusz 0:3968e3a2e047 13
amateusz 0:3968e3a2e047 14 _last_temperature = NULL;
amateusz 0:3968e3a2e047 15 _parasite_power = true;
amateusz 0:3968e3a2e047 16 for(byte_counter=0; byte_counter<8; byte_counter++)
amateusz 0:3968e3a2e047 17 ROM[byte_counter] = 0xFF;
amateusz 0:3968e3a2e047 18 for(byte_counter=0; byte_counter<9; byte_counter++)
amateusz 0:3968e3a2e047 19 RAM[byte_counter] = 0x00;
amateusz 0:3968e3a2e047 20 }
amateusz 0:3968e3a2e047 21 DS1820::DS1820 (PinName data_pin) : _datapin(data_pin), _parasitepin(NC)
amateusz 0:3968e3a2e047 22 {
amateusz 0:3968e3a2e047 23 int byte_counter;
amateusz 0:3968e3a2e047 24
amateusz 0:3968e3a2e047 25 _last_temperature = NULL;
amateusz 0:3968e3a2e047 26 _parasite_power = false;
amateusz 0:3968e3a2e047 27 for(byte_counter=0; byte_counter<8; byte_counter++)
amateusz 0:3968e3a2e047 28 ROM[byte_counter] = 0xFF;
amateusz 0:3968e3a2e047 29 for(byte_counter=0; byte_counter<9; byte_counter++)
amateusz 0:3968e3a2e047 30 RAM[byte_counter] = 0x00;
amateusz 0:3968e3a2e047 31 }
amateusz 0:3968e3a2e047 32
amateusz 0:3968e3a2e047 33 void DS1820::_auto_convert_temperature()
amateusz 0:3968e3a2e047 34 {
amateusz 1:1020ba9ab5d2 35 convert_temperature(false, DS1820::this_device);
amateusz 0:3968e3a2e047 36 }
amateusz 0:3968e3a2e047 37
amateusz 0:3968e3a2e047 38 void DS1820::enable_auto_convert(float interval)
amateusz 0:3968e3a2e047 39 {
amateusz 0:3968e3a2e047 40 _autoConvert.attach(this, &DS1820::_auto_convert_temperature, interval);
amateusz 0:3968e3a2e047 41 }
amateusz 0:3968e3a2e047 42
amateusz 0:3968e3a2e047 43 bool DS1820::onewire_reset()
amateusz 0:3968e3a2e047 44 {
amateusz 0:3968e3a2e047 45 // This will return false if no devices are present on the data bus
amateusz 0:3968e3a2e047 46 bool presence=false;
amateusz 0:3968e3a2e047 47 _datapin.output();
amateusz 0:3968e3a2e047 48 _datapin.mode(PullUp);
amateusz 0:3968e3a2e047 49 _datapin = 0; // bring low for 500 us
amateusz 0:3968e3a2e047 50 wait_us(500);
amateusz 0:3968e3a2e047 51 _datapin.input(); // let the data line float high
amateusz 0:3968e3a2e047 52 _datapin.mode(PullUp);
amateusz 0:3968e3a2e047 53 wait_us(90); // wait 90us
amateusz 0:3968e3a2e047 54 if (_datapin.read()==0) // see if any devices are pulling the data line low
amateusz 0:3968e3a2e047 55 presence=true;
amateusz 0:3968e3a2e047 56 wait_us(410);
amateusz 0:3968e3a2e047 57 return presence;
amateusz 0:3968e3a2e047 58 }
amateusz 0:3968e3a2e047 59
amateusz 0:3968e3a2e047 60 void DS1820::onewire_bit_out (bool bit_data)
amateusz 0:3968e3a2e047 61 {
amateusz 0:3968e3a2e047 62 _datapin.output();
amateusz 0:3968e3a2e047 63 _datapin = 0;
amateusz 0:3968e3a2e047 64 wait_us(5);
amateusz 0:3968e3a2e047 65 if (bit_data) {
amateusz 0:3968e3a2e047 66 _datapin.input(); // bring data line high
amateusz 0:3968e3a2e047 67 _datapin.mode(PullUp);
amateusz 0:3968e3a2e047 68 wait_us(55);
amateusz 0:3968e3a2e047 69 } else {
amateusz 0:3968e3a2e047 70 wait_us(55); // keep data line low
amateusz 0:3968e3a2e047 71 _datapin.input();
amateusz 0:3968e3a2e047 72 _datapin.mode(PullUp);
amateusz 0:3968e3a2e047 73 }
amateusz 0:3968e3a2e047 74 }
amateusz 0:3968e3a2e047 75
amateusz 0:3968e3a2e047 76 void DS1820::onewire_byte_out(char data) // output data character (least sig bit first).
amateusz 0:3968e3a2e047 77 {
amateusz 0:3968e3a2e047 78 int n;
amateusz 0:3968e3a2e047 79 for (n=0; n<8; n++) {
amateusz 0:3968e3a2e047 80 onewire_bit_out(data & 0x01);
amateusz 0:3968e3a2e047 81 data = data >> 1; // now the next bit is in the least sig bit position.
amateusz 0:3968e3a2e047 82 }
amateusz 0:3968e3a2e047 83 }
amateusz 0:3968e3a2e047 84
amateusz 0:3968e3a2e047 85 bool DS1820::onewire_bit_in()
amateusz 0:3968e3a2e047 86 {
amateusz 0:3968e3a2e047 87 bool answer;
amateusz 0:3968e3a2e047 88 _datapin.output();
amateusz 0:3968e3a2e047 89 _datapin = 0;
amateusz 0:3968e3a2e047 90 wait_us(5);
amateusz 0:3968e3a2e047 91 _datapin.input();
amateusz 0:3968e3a2e047 92 _datapin.mode(PullUp);
amateusz 0:3968e3a2e047 93 wait_us(5);
amateusz 0:3968e3a2e047 94 answer = _datapin.read();
amateusz 0:3968e3a2e047 95 wait_us(50);
amateusz 0:3968e3a2e047 96 return answer;
amateusz 0:3968e3a2e047 97 }
amateusz 0:3968e3a2e047 98
amateusz 0:3968e3a2e047 99 char DS1820::onewire_byte_in() // read byte, least sig byte first
amateusz 0:3968e3a2e047 100 {
amateusz 0:3968e3a2e047 101 char answer = 0x00;
amateusz 0:3968e3a2e047 102 int i;
amateusz 0:3968e3a2e047 103 for (i=0; i<8; i++) {
amateusz 0:3968e3a2e047 104 answer = answer >> 1; // shift over to make room for the next bit
amateusz 0:3968e3a2e047 105 if (onewire_bit_in())
amateusz 0:3968e3a2e047 106 answer = answer | 0x80; // if the data port is high, make this bit a 1
amateusz 0:3968e3a2e047 107 }
amateusz 0:3968e3a2e047 108 return answer;
amateusz 0:3968e3a2e047 109 }
amateusz 0:3968e3a2e047 110
amateusz 0:3968e3a2e047 111 bool DS1820::search_ROM()
amateusz 0:3968e3a2e047 112 {
amateusz 0:3968e3a2e047 113 return search_ROM_routine(0xF0); // Search ROM command
amateusz 0:3968e3a2e047 114 }
amateusz 0:3968e3a2e047 115
amateusz 0:3968e3a2e047 116 bool DS1820::search_alarm()
amateusz 0:3968e3a2e047 117 {
amateusz 0:3968e3a2e047 118 return search_ROM_routine(0xEC); // Search Alarm command
amateusz 0:3968e3a2e047 119 }
amateusz 0:3968e3a2e047 120
amateusz 0:3968e3a2e047 121 bool DS1820::search_ROM_routine(char command)
amateusz 0:3968e3a2e047 122 {
amateusz 0:3968e3a2e047 123 extern bool DS1820_done_flag;
amateusz 0:3968e3a2e047 124 extern int DS1820_last_descrepancy;
amateusz 0:3968e3a2e047 125 extern char DS1820_search_ROM[8];
amateusz 0:3968e3a2e047 126 int descrepancy_marker, ROM_bit_index;
amateusz 0:3968e3a2e047 127 bool return_value, Bit_A, Bit_B;
amateusz 0:3968e3a2e047 128 char byte_counter, bit_mask;
amateusz 0:3968e3a2e047 129
amateusz 0:3968e3a2e047 130 return_value=false;
amateusz 0:3968e3a2e047 131 if (!DS1820_done_flag) {
amateusz 0:3968e3a2e047 132 if (!onewire_reset()) {
amateusz 0:3968e3a2e047 133 DS1820_last_descrepancy = 0; // no devices present
amateusz 0:3968e3a2e047 134 } else {
amateusz 0:3968e3a2e047 135 ROM_bit_index=1;
amateusz 0:3968e3a2e047 136 descrepancy_marker=0;
amateusz 0:3968e3a2e047 137 onewire_byte_out(command); // Search ROM command or Search Alarm command
amateusz 0:3968e3a2e047 138 byte_counter = 0;
amateusz 0:3968e3a2e047 139 bit_mask = 0x01;
amateusz 0:3968e3a2e047 140 while (ROM_bit_index<=64) {
amateusz 0:3968e3a2e047 141 Bit_A = onewire_bit_in();
amateusz 0:3968e3a2e047 142 Bit_B = onewire_bit_in();
amateusz 0:3968e3a2e047 143 if (Bit_A & Bit_B) {
amateusz 0:3968e3a2e047 144 descrepancy_marker = 0; // data read error, this should never happen
amateusz 0:3968e3a2e047 145 ROM_bit_index = 0xFF;
amateusz 0:3968e3a2e047 146 } else {
amateusz 0:3968e3a2e047 147 if (Bit_A | Bit_B) {
amateusz 0:3968e3a2e047 148 // Set ROM bit to Bit_A
amateusz 0:3968e3a2e047 149 if (Bit_A) {
amateusz 0:3968e3a2e047 150 DS1820_search_ROM[byte_counter] = DS1820_search_ROM[byte_counter] | bit_mask; // Set ROM bit to one
amateusz 0:3968e3a2e047 151 } else {
amateusz 0:3968e3a2e047 152 DS1820_search_ROM[byte_counter] = DS1820_search_ROM[byte_counter] & ~bit_mask; // Set ROM bit to zero
amateusz 0:3968e3a2e047 153 }
amateusz 0:3968e3a2e047 154 } else {
amateusz 0:3968e3a2e047 155 // both bits A and B are low, so there are two or more devices present
amateusz 0:3968e3a2e047 156 if ( ROM_bit_index == DS1820_last_descrepancy ) {
amateusz 0:3968e3a2e047 157 DS1820_search_ROM[byte_counter] = DS1820_search_ROM[byte_counter] | bit_mask; // Set ROM bit to one
amateusz 0:3968e3a2e047 158 } else {
amateusz 0:3968e3a2e047 159 if ( ROM_bit_index > DS1820_last_descrepancy ) {
amateusz 0:3968e3a2e047 160 DS1820_search_ROM[byte_counter] = DS1820_search_ROM[byte_counter] & ~bit_mask; // Set ROM bit to zero
amateusz 0:3968e3a2e047 161 descrepancy_marker = ROM_bit_index;
amateusz 0:3968e3a2e047 162 } else {
amateusz 0:3968e3a2e047 163 if (( DS1820_search_ROM[byte_counter] & bit_mask) == 0x00 )
amateusz 0:3968e3a2e047 164 descrepancy_marker = ROM_bit_index;
amateusz 0:3968e3a2e047 165 }
amateusz 0:3968e3a2e047 166 }
amateusz 0:3968e3a2e047 167 }
amateusz 0:3968e3a2e047 168 onewire_bit_out (DS1820_search_ROM[byte_counter] & bit_mask);
amateusz 0:3968e3a2e047 169 ROM_bit_index++;
amateusz 0:3968e3a2e047 170 if (bit_mask & 0x80) {
amateusz 0:3968e3a2e047 171 byte_counter++;
amateusz 0:3968e3a2e047 172 bit_mask = 0x01;
amateusz 0:3968e3a2e047 173 } else {
amateusz 0:3968e3a2e047 174 bit_mask = bit_mask << 1;
amateusz 0:3968e3a2e047 175 }
amateusz 0:3968e3a2e047 176 }
amateusz 0:3968e3a2e047 177 }
amateusz 0:3968e3a2e047 178 DS1820_last_descrepancy = descrepancy_marker;
amateusz 0:3968e3a2e047 179 if (ROM_bit_index != 0xFF) {
amateusz 0:3968e3a2e047 180 for(byte_counter=0; byte_counter<8; byte_counter++)
amateusz 0:3968e3a2e047 181 ROM[byte_counter] = DS1820_search_ROM[byte_counter];
amateusz 0:3968e3a2e047 182 return_value = true;
amateusz 0:3968e3a2e047 183 }
amateusz 0:3968e3a2e047 184 }
amateusz 0:3968e3a2e047 185 if (DS1820_last_descrepancy == 0)
amateusz 0:3968e3a2e047 186 DS1820_done_flag = true;
amateusz 0:3968e3a2e047 187 }
amateusz 0:3968e3a2e047 188 return return_value;
amateusz 0:3968e3a2e047 189 }
amateusz 0:3968e3a2e047 190
amateusz 0:3968e3a2e047 191 void DS1820::search_ROM_setup()
amateusz 0:3968e3a2e047 192 {
amateusz 0:3968e3a2e047 193 extern bool DS1820_done_flag;
amateusz 0:3968e3a2e047 194 extern int DS1820_last_descrepancy;
amateusz 0:3968e3a2e047 195 extern char DS1820_search_ROM[8];
amateusz 0:3968e3a2e047 196 DS1820_done_flag = false;
amateusz 0:3968e3a2e047 197 DS1820_last_descrepancy = 0;
amateusz 0:3968e3a2e047 198 int i;
amateusz 0:3968e3a2e047 199 for (i=0; i<8; i++)
amateusz 0:3968e3a2e047 200 DS1820_search_ROM[i]=0x00;
amateusz 0:3968e3a2e047 201 }
amateusz 0:3968e3a2e047 202
amateusz 0:3968e3a2e047 203 void DS1820::read_ROM()
amateusz 0:3968e3a2e047 204 {
amateusz 0:3968e3a2e047 205 // NOTE: This command can only be used when there is one DS1820 on the bus. If this command
amateusz 0:3968e3a2e047 206 // is used when there is more than one slave present on the bus, a data collision will occur
amateusz 0:3968e3a2e047 207 // when all the DS1820s attempt to respond at the same time.
amateusz 0:3968e3a2e047 208 int i;
amateusz 0:3968e3a2e047 209 onewire_reset();
amateusz 0:3968e3a2e047 210 onewire_byte_out(0x33); // Read ROM id
amateusz 0:3968e3a2e047 211 for (i=0; i<8; i++)
amateusz 0:3968e3a2e047 212 ROM[i]=onewire_byte_in();
amateusz 0:3968e3a2e047 213 }
amateusz 0:3968e3a2e047 214
amateusz 0:3968e3a2e047 215 void DS1820::match_ROM()
amateusz 0:3968e3a2e047 216 {
amateusz 0:3968e3a2e047 217 // Used to select a specific device
amateusz 0:3968e3a2e047 218 int i;
amateusz 0:3968e3a2e047 219 onewire_reset();
amateusz 0:3968e3a2e047 220 onewire_byte_out( 0x55); //Match ROM command
amateusz 0:3968e3a2e047 221 for (i=0; i<8; i++)
amateusz 0:3968e3a2e047 222 onewire_byte_out(ROM[i]);
amateusz 0:3968e3a2e047 223 }
amateusz 0:3968e3a2e047 224
amateusz 0:3968e3a2e047 225 void DS1820::skip_ROM()
amateusz 0:3968e3a2e047 226 {
amateusz 0:3968e3a2e047 227 onewire_reset();
amateusz 0:3968e3a2e047 228 onewire_byte_out(0xCC); // Skip ROM command
amateusz 0:3968e3a2e047 229 }
amateusz 0:3968e3a2e047 230
amateusz 0:3968e3a2e047 231 bool DS1820::ROM_checksum_error()
amateusz 0:3968e3a2e047 232 {
amateusz 0:3968e3a2e047 233 char xCRC=0x00;
amateusz 0:3968e3a2e047 234 int i;
amateusz 0:3968e3a2e047 235 for(i=0; i<7; i++) // Only going to shift the lower 7 bytes
amateusz 0:3968e3a2e047 236 xCRC = CRC_byte(xCRC, ROM[i]);
amateusz 0:3968e3a2e047 237 // After 7 bytes CRC should equal the 8th byte (ROM CRC)
amateusz 0:3968e3a2e047 238 return (xCRC!=ROM[7]); // will return true if there is a CRC checksum error
amateusz 0:3968e3a2e047 239 }
amateusz 0:3968e3a2e047 240
amateusz 0:3968e3a2e047 241 bool DS1820::RAM_checksum_error()
amateusz 0:3968e3a2e047 242 {
amateusz 0:3968e3a2e047 243 char xCRC=0x00;
amateusz 0:3968e3a2e047 244 int i;
amateusz 0:3968e3a2e047 245 read_RAM();
amateusz 0:3968e3a2e047 246 for(i=0; i<8; i++) // Only going to shift the lower 8 bytes
amateusz 0:3968e3a2e047 247 xCRC = CRC_byte(xCRC, RAM[i]);
amateusz 0:3968e3a2e047 248 // After 8 bytes CRC should equal the 9th byte (RAM CRC)
amateusz 0:3968e3a2e047 249 return (xCRC!=RAM[8]); // will return true if there is a CRC checksum error
amateusz 0:3968e3a2e047 250 }
amateusz 0:3968e3a2e047 251
amateusz 0:3968e3a2e047 252 char DS1820::CRC_byte (char xCRC, char byte )
amateusz 0:3968e3a2e047 253 {
amateusz 0:3968e3a2e047 254 int j;
amateusz 0:3968e3a2e047 255 for(j=0; j<8; j++) {
amateusz 0:3968e3a2e047 256 if ((byte & 0x01 ) ^ (xCRC & 0x01)) {
amateusz 0:3968e3a2e047 257 // DATA ^ LSB CRC = 1
amateusz 0:3968e3a2e047 258 xCRC = xCRC>>1;
amateusz 0:3968e3a2e047 259 // Set the MSB to 1
amateusz 0:3968e3a2e047 260 xCRC = xCRC | 0x80;
amateusz 0:3968e3a2e047 261 // Check bit 3
amateusz 0:3968e3a2e047 262 if (xCRC & 0x04) {
amateusz 0:3968e3a2e047 263 xCRC = xCRC & 0xFB; // Bit 3 is set, so clear it
amateusz 0:3968e3a2e047 264 } else {
amateusz 0:3968e3a2e047 265 xCRC = xCRC | 0x04; // Bit 3 is clear, so set it
amateusz 0:3968e3a2e047 266 }
amateusz 0:3968e3a2e047 267 // Check bit 4
amateusz 0:3968e3a2e047 268 if (xCRC & 0x08) {
amateusz 0:3968e3a2e047 269 xCRC = xCRC & 0xF7; // Bit 4 is set, so clear it
amateusz 0:3968e3a2e047 270 } else {
amateusz 0:3968e3a2e047 271 xCRC = xCRC | 0x08; // Bit 4 is clear, so set it
amateusz 0:3968e3a2e047 272 }
amateusz 0:3968e3a2e047 273 } else {
amateusz 0:3968e3a2e047 274 // DATA ^ LSB xCRC = 0
amateusz 0:3968e3a2e047 275 xCRC = xCRC>>1;
amateusz 0:3968e3a2e047 276 // clear MSB
amateusz 0:3968e3a2e047 277 xCRC = xCRC & 0x7F;
amateusz 0:3968e3a2e047 278 // No need to check bits, with DATA ^ LSB xCRC = 0, they will remain unchanged
amateusz 0:3968e3a2e047 279 }
amateusz 0:3968e3a2e047 280 byte = byte>>1;
amateusz 0:3968e3a2e047 281 }
amateusz 0:3968e3a2e047 282 return xCRC;
amateusz 0:3968e3a2e047 283 }
amateusz 0:3968e3a2e047 284
amateusz 1:1020ba9ab5d2 285 void DS1820::convert_temperature(bool blocking, devices device)
amateusz 0:3968e3a2e047 286 {
amateusz 0:3968e3a2e047 287 // Convert temperature into scratchpad RAM for all devices at once
amateusz 1:1020ba9ab5d2 288 int delay_time = 750; // Default delay time (for 12 bits)
amateusz 0:3968e3a2e047 289 char resolution;
amateusz 0:3968e3a2e047 290 if (device==all_devices)
amateusz 0:3968e3a2e047 291 skip_ROM(); // Skip ROM command, will convert for ALL devices
amateusz 0:3968e3a2e047 292 else {
amateusz 0:3968e3a2e047 293 match_ROM();
amateusz 0:3968e3a2e047 294 if (FAMILY_CODE == FAMILY_CODE_DS18B20 ) {
amateusz 0:3968e3a2e047 295 resolution = RAM[4] & 0x60;
amateusz 0:3968e3a2e047 296 if (resolution == 0x00) // 9 bits
amateusz 0:3968e3a2e047 297 delay_time = 94;
amateusz 0:3968e3a2e047 298 if (resolution == 0x20) // 10 bits
amateusz 0:3968e3a2e047 299 delay_time = 188;
amateusz 0:3968e3a2e047 300 if (resolution == 0x40) // 11 bits. Note 12bits uses the 750ms default
amateusz 0:3968e3a2e047 301 delay_time = 375;
amateusz 0:3968e3a2e047 302 }
amateusz 0:3968e3a2e047 303 }
amateusz 0:3968e3a2e047 304 onewire_byte_out( 0x44); // perform temperature conversion
amateusz 0:3968e3a2e047 305 if (_parasite_power)
amateusz 0:3968e3a2e047 306 _parasitepin = 1; // Parasite power strong pullup
amateusz 1:1020ba9ab5d2 307 if (blocking) { // blocking
amateusz 1:1020ba9ab5d2 308 wait_ms(delay_time);
amateusz 1:1020ba9ab5d2 309 _temperature_raw();
amateusz 1:1020ba9ab5d2 310 } else { // non-blocking
amateusz 1:1020ba9ab5d2 311 float timeout_time = ((float)delay_time)/1000.0;
amateusz 1:1020ba9ab5d2 312 auto_get_new_temperature.attach(callback(this, &DS1820::_temperature_raw), timeout_time); // update _last_temperture automagically
amateusz 1:1020ba9ab5d2 313 }
amateusz 0:3968e3a2e047 314 if (_parasite_power)
amateusz 0:3968e3a2e047 315 _parasitepin = 0;
amateusz 0:3968e3a2e047 316 }
amateusz 0:3968e3a2e047 317
amateusz 0:3968e3a2e047 318 void DS1820::read_RAM()
amateusz 0:3968e3a2e047 319 {
amateusz 0:3968e3a2e047 320 // This will copy the DS1820's 9 bytes of RAM data
amateusz 0:3968e3a2e047 321 // into the objects RAM array. Functions that use
amateusz 0:3968e3a2e047 322 // RAM values will automaticly call this procedure.
amateusz 0:3968e3a2e047 323 int i;
amateusz 0:3968e3a2e047 324 match_ROM(); // Select this device
amateusz 0:3968e3a2e047 325 onewire_byte_out( 0xBE); //Read Scratchpad command
amateusz 0:3968e3a2e047 326 for(i=0; i<9; i++) {
amateusz 0:3968e3a2e047 327 RAM[i] = onewire_byte_in();
amateusz 0:3968e3a2e047 328 }
amateusz 0:3968e3a2e047 329 }
amateusz 0:3968e3a2e047 330
amateusz 0:3968e3a2e047 331 bool DS1820::set_configuration_bits(unsigned int resolution, devices device)
amateusz 0:3968e3a2e047 332 {
amateusz 0:3968e3a2e047 333 bool answer = false;
amateusz 0:3968e3a2e047 334 resolution = resolution - 9;
amateusz 0:3968e3a2e047 335 if (resolution < 4) {
amateusz 0:3968e3a2e047 336 if (device==all_devices)
amateusz 0:3968e3a2e047 337 skip_ROM();
amateusz 0:3968e3a2e047 338 else
amateusz 0:3968e3a2e047 339 match_ROM();
amateusz 0:3968e3a2e047 340 resolution = resolution<<5; // align the bits
amateusz 0:3968e3a2e047 341 RAM[4] = (RAM[4] & 0b00011111) | resolution; // mask out old data, insert new
amateusz 0:3968e3a2e047 342 write_scratchpad ((RAM[2]<<8) + RAM[3]);
amateusz 0:3968e3a2e047 343 // store_scratchpad (DS1820::this_device); // Need to test if this is required
amateusz 0:3968e3a2e047 344 answer = true;
amateusz 0:3968e3a2e047 345 }
amateusz 0:3968e3a2e047 346 return answer;
amateusz 0:3968e3a2e047 347 }
amateusz 0:3968e3a2e047 348
amateusz 0:3968e3a2e047 349 int DS1820::read_scratchpad()
amateusz 0:3968e3a2e047 350 {
amateusz 0:3968e3a2e047 351 int answer;
amateusz 0:3968e3a2e047 352 read_RAM();
amateusz 0:3968e3a2e047 353 answer = (RAM[2]<<8) + RAM[3];
amateusz 0:3968e3a2e047 354 return answer;
amateusz 0:3968e3a2e047 355 }
amateusz 0:3968e3a2e047 356
amateusz 0:3968e3a2e047 357 void DS1820::write_scratchpad(int data)
amateusz 0:3968e3a2e047 358 {
amateusz 0:3968e3a2e047 359 RAM[3] = data;
amateusz 0:3968e3a2e047 360 RAM[2] = data>>8;
amateusz 0:3968e3a2e047 361 match_ROM();
amateusz 0:3968e3a2e047 362 onewire_byte_out(0x4E); // Copy scratchpad into DS1820 ram memory
amateusz 0:3968e3a2e047 363 onewire_byte_out(RAM[2]); // T(H)
amateusz 0:3968e3a2e047 364 onewire_byte_out(RAM[3]); // T(L)
amateusz 0:3968e3a2e047 365 if ( FAMILY_CODE == FAMILY_CODE_DS18B20 ) {
amateusz 0:3968e3a2e047 366 onewire_byte_out(RAM[4]); // Configuration register
amateusz 0:3968e3a2e047 367 }
amateusz 0:3968e3a2e047 368 }
amateusz 0:3968e3a2e047 369
amateusz 0:3968e3a2e047 370 void DS1820::store_scratchpad(devices device)
amateusz 0:3968e3a2e047 371 {
amateusz 0:3968e3a2e047 372 if (device==all_devices)
amateusz 0:3968e3a2e047 373 skip_ROM(); // Skip ROM command, will store for ALL devices
amateusz 0:3968e3a2e047 374 else
amateusz 0:3968e3a2e047 375 match_ROM();
amateusz 0:3968e3a2e047 376 onewire_byte_out(0x48); // Write scratchpad into E2 command
amateusz 0:3968e3a2e047 377 if (_parasite_power)
amateusz 0:3968e3a2e047 378 _parasitepin=1;
amateusz 0:3968e3a2e047 379 wait_ms(10); // Parasite power strong pullup for 10ms
amateusz 0:3968e3a2e047 380 if (_parasite_power)
amateusz 0:3968e3a2e047 381 _parasitepin=0;
amateusz 0:3968e3a2e047 382 }
amateusz 0:3968e3a2e047 383
amateusz 0:3968e3a2e047 384 int DS1820::recall_scratchpad(devices device)
amateusz 0:3968e3a2e047 385 {
amateusz 0:3968e3a2e047 386 // This copies the E2 values into the DS1820's memory.
amateusz 0:3968e3a2e047 387 // If you specify all_devices this will return zero, otherwise
amateusz 0:3968e3a2e047 388 // it will return the value of the scratchpad memory.
amateusz 0:3968e3a2e047 389 int answer=0;
amateusz 0:3968e3a2e047 390 if (device==all_devices)
amateusz 0:3968e3a2e047 391 skip_ROM(); // Skip ROM command, will recall for ALL devices
amateusz 0:3968e3a2e047 392 else
amateusz 0:3968e3a2e047 393 match_ROM();
amateusz 0:3968e3a2e047 394 onewire_byte_out(0xB8); // Recall E2 data to scratchpad command
amateusz 0:3968e3a2e047 395 wait_ms(10); // not sure I like polling for completion
amateusz 0:3968e3a2e047 396 // it could cause an infinite loop
amateusz 0:3968e3a2e047 397 if (device==DS1820::this_device) {
amateusz 0:3968e3a2e047 398 read_RAM();
amateusz 0:3968e3a2e047 399 answer = read_scratchpad();
amateusz 0:3968e3a2e047 400 }
amateusz 0:3968e3a2e047 401 return answer;
amateusz 0:3968e3a2e047 402 }
amateusz 1:1020ba9ab5d2 403 void DS1820::_temperature_raw()
amateusz 0:3968e3a2e047 404 {
amateusz 0:3968e3a2e047 405 float answer, remaining_count, count_per_degree;
amateusz 0:3968e3a2e047 406 int reading;
amateusz 0:3968e3a2e047 407 read_RAM();
amateusz 0:3968e3a2e047 408 reading = (RAM[1] << 8) + RAM[0];
amateusz 0:3968e3a2e047 409 if (reading & 0x8000) { // negative degrees C
amateusz 0:3968e3a2e047 410 reading = 0-((reading ^ 0xffff) + 1); // 2's comp then convert to signed int
amateusz 0:3968e3a2e047 411 }
amateusz 0:3968e3a2e047 412 answer = reading +0.0; // convert to floating point
amateusz 0:3968e3a2e047 413 if ( FAMILY_CODE == FAMILY_CODE_DS18B20 ) {
amateusz 0:3968e3a2e047 414 answer = answer / 8.0;
amateusz 0:3968e3a2e047 415 } else {
amateusz 0:3968e3a2e047 416 remaining_count = RAM[6];
amateusz 0:3968e3a2e047 417 count_per_degree = RAM[7];
amateusz 0:3968e3a2e047 418 answer = answer - 0.25 + (count_per_degree - remaining_count) / count_per_degree;
amateusz 0:3968e3a2e047 419 }
amateusz 0:3968e3a2e047 420 _last_temperature = answer;
amateusz 0:3968e3a2e047 421 }
amateusz 0:3968e3a2e047 422
amateusz 0:3968e3a2e047 423 float DS1820::temperature(char scale)
amateusz 0:3968e3a2e047 424 {
amateusz 0:3968e3a2e047 425 // The data specs state that count_per_degree should be 0x10 (16), I found my devices
amateusz 0:3968e3a2e047 426 // to have a count_per_degree of 0x4B (75). With the standard resolution of 1/2 deg C
amateusz 0:3968e3a2e047 427 // this allowed an expanded resolution of 1/150th of a deg C. I wouldn't rely on this
amateusz 0:3968e3a2e047 428 // being super acurate, but it does allow for a smooth display in the 1/10ths of a
amateusz 0:3968e3a2e047 429 // deg C or F scales.
amateusz 0:3968e3a2e047 430 if (_last_temperature == NULL) {
amateusz 1:1020ba9ab5d2 431 convert_temperature(true);
amateusz 0:3968e3a2e047 432 }
amateusz 1:1020ba9ab5d2 433 float answer = _last_temperature;
amateusz 1:1020ba9ab5d2 434 if (scale=='C' or scale=='c')
amateusz 1:1020ba9ab5d2 435 answer = answer / 2.0;
amateusz 1:1020ba9ab5d2 436 else
amateusz 1:1020ba9ab5d2 437 // Convert to deg F
amateusz 1:1020ba9ab5d2 438 answer = answer * 9.0 / 10.0 + 32.0;
amateusz 1:1020ba9ab5d2 439 return answer;
amateusz 0:3968e3a2e047 440 }
amateusz 0:3968e3a2e047 441
amateusz 0:3968e3a2e047 442 bool DS1820::read_power_supply(devices device)
amateusz 0:3968e3a2e047 443 {
amateusz 0:3968e3a2e047 444 // This will return true if the device (or all devices) are Vcc powered
amateusz 0:3968e3a2e047 445 // This will return false if the device (or ANY device) is parasite powered
amateusz 0:3968e3a2e047 446 if (device==all_devices)
amateusz 0:3968e3a2e047 447 skip_ROM(); // Skip ROM command, will poll for any device using parasite power
amateusz 0:3968e3a2e047 448 else
amateusz 0:3968e3a2e047 449 match_ROM();
amateusz 0:3968e3a2e047 450 onewire_byte_out(0xB4); // Read power supply command
amateusz 0:3968e3a2e047 451 return onewire_bit_in();
amateusz 0:3968e3a2e047 452 }