comparison service/arduinoNode/arduino-libraries/DallasTemperature/DallasTemperature.cpp @ 970:4f5825a9fc47

some external arduino libs, minus examples and docs Ignore-this: 444126f11a1755109b3b29cbeaa6b9bd darcs-hash:20150411084314-312f9-165a2a8d6ee806950c8a7ae2145364d286fd50b4
author drewp <drewp@bigasterisk.com>
date Sat, 11 Apr 2015 01:43:14 -0700
parents
children
comparison
equal deleted inserted replaced
969:70a5392b24d3 970:4f5825a9fc47
1 // This library is free software; you can redistribute it and/or
2 // modify it under the terms of the GNU Lesser General Public
3 // License as published by the Free Software Foundation; either
4 // version 2.1 of the License, or (at your option) any later version.
5
6 // Version 3.7.2 modified on Dec 6, 2011 to support Arduino 1.0
7 // See Includes...
8 // Modified by Jordan Hochenbaum
9
10 #include "DallasTemperature.h"
11
12 #if ARDUINO >= 100
13 #include "Arduino.h"
14 #else
15 extern "C" {
16 #include "WConstants.h"
17 }
18 #endif
19
20 DallasTemperature::DallasTemperature(OneWire* _oneWire)
21 #if REQUIRESALARMS
22 : _AlarmHandler(&defaultAlarmHandler)
23 #endif
24 {
25 _wire = _oneWire;
26 devices = 0;
27 parasite = false;
28 bitResolution = 9;
29 waitForConversion = true;
30 checkForConversion = true;
31 }
32
33 // initialise the bus
34 void DallasTemperature::begin(void)
35 {
36 DeviceAddress deviceAddress;
37
38 _wire->reset_search();
39 devices = 0; // Reset the number of devices when we enumerate wire devices
40
41 while (_wire->search(deviceAddress))
42 {
43 if (validAddress(deviceAddress))
44 {
45 if (!parasite && readPowerSupply(deviceAddress)) parasite = true;
46
47 ScratchPad scratchPad;
48
49 readScratchPad(deviceAddress, scratchPad);
50
51 bitResolution = max(bitResolution, getResolution(deviceAddress));
52
53 devices++;
54 }
55 }
56 }
57
58 // returns the number of devices found on the bus
59 uint8_t DallasTemperature::getDeviceCount(void)
60 {
61 return devices;
62 }
63
64 // returns true if address is valid
65 bool DallasTemperature::validAddress(const uint8_t* deviceAddress)
66 {
67 return (_wire->crc8(deviceAddress, 7) == deviceAddress[7]);
68 }
69
70 // finds an address at a given index on the bus
71 // returns true if the device was found
72 bool DallasTemperature::getAddress(uint8_t* deviceAddress, uint8_t index)
73 {
74 uint8_t depth = 0;
75
76 _wire->reset_search();
77
78 while (depth <= index && _wire->search(deviceAddress))
79 {
80 if (depth == index && validAddress(deviceAddress)) return true;
81 depth++;
82 }
83
84 return false;
85 }
86
87 // attempt to determine if the device at the given address is connected to the bus
88 bool DallasTemperature::isConnected(const uint8_t* deviceAddress)
89 {
90 ScratchPad scratchPad;
91 return isConnected(deviceAddress, scratchPad);
92 }
93
94 // attempt to determine if the device at the given address is connected to the bus
95 // also allows for updating the read scratchpad
96 bool DallasTemperature::isConnected(const uint8_t* deviceAddress, uint8_t* scratchPad)
97 {
98 readScratchPad(deviceAddress, scratchPad);
99 return (_wire->crc8(scratchPad, 8) == scratchPad[SCRATCHPAD_CRC]);
100 }
101
102 // read device's scratch pad
103 void DallasTemperature::readScratchPad(const uint8_t* deviceAddress, uint8_t* scratchPad)
104 {
105 // send the command
106 _wire->reset();
107 _wire->select(deviceAddress);
108 _wire->write(READSCRATCH);
109
110 // TODO => collect all comments & use simple loop
111 // byte 0: temperature LSB
112 // byte 1: temperature MSB
113 // byte 2: high alarm temp
114 // byte 3: low alarm temp
115 // byte 4: DS18S20: store for crc
116 // DS18B20 & DS1822: configuration register
117 // byte 5: internal use & crc
118 // byte 6: DS18S20: COUNT_REMAIN
119 // DS18B20 & DS1822: store for crc
120 // byte 7: DS18S20: COUNT_PER_C
121 // DS18B20 & DS1822: store for crc
122 // byte 8: SCRATCHPAD_CRC
123 //
124 // for(int i=0; i<9; i++)
125 // {
126 // scratchPad[i] = _wire->read();
127 // }
128
129
130 // read the response
131
132 // byte 0: temperature LSB
133 scratchPad[TEMP_LSB] = _wire->read();
134
135 // byte 1: temperature MSB
136 scratchPad[TEMP_MSB] = _wire->read();
137
138 // byte 2: high alarm temp
139 scratchPad[HIGH_ALARM_TEMP] = _wire->read();
140
141 // byte 3: low alarm temp
142 scratchPad[LOW_ALARM_TEMP] = _wire->read();
143
144 // byte 4:
145 // DS18S20: store for crc
146 // DS18B20 & DS1822: configuration register
147 scratchPad[CONFIGURATION] = _wire->read();
148
149 // byte 5:
150 // internal use & crc
151 scratchPad[INTERNAL_BYTE] = _wire->read();
152
153 // byte 6:
154 // DS18S20: COUNT_REMAIN
155 // DS18B20 & DS1822: store for crc
156 scratchPad[COUNT_REMAIN] = _wire->read();
157
158 // byte 7:
159 // DS18S20: COUNT_PER_C
160 // DS18B20 & DS1822: store for crc
161 scratchPad[COUNT_PER_C] = _wire->read();
162
163 // byte 8:
164 // SCTRACHPAD_CRC
165 scratchPad[SCRATCHPAD_CRC] = _wire->read();
166
167 _wire->reset();
168 }
169
170 // writes device's scratch pad
171 void DallasTemperature::writeScratchPad(const uint8_t* deviceAddress, const uint8_t* scratchPad)
172 {
173 _wire->reset();
174 _wire->select(deviceAddress);
175 _wire->write(WRITESCRATCH);
176 _wire->write(scratchPad[HIGH_ALARM_TEMP]); // high alarm temp
177 _wire->write(scratchPad[LOW_ALARM_TEMP]); // low alarm temp
178 // DS1820 and DS18S20 have no configuration register
179 if (deviceAddress[0] != DS18S20MODEL) _wire->write(scratchPad[CONFIGURATION]); // configuration
180 _wire->reset();
181 _wire->select(deviceAddress); //<--this line was missing
182 // save the newly written values to eeprom
183 _wire->write(COPYSCRATCH, parasite);
184 delay(20); // <--- added 20ms delay to allow 10ms long EEPROM write operation (as specified by datasheet)
185 if (parasite) delay(10); // 10ms delay
186 _wire->reset();
187 }
188
189 // reads the device's power requirements
190 bool DallasTemperature::readPowerSupply(const uint8_t* deviceAddress)
191 {
192 bool ret = false;
193 _wire->reset();
194 _wire->select(deviceAddress);
195 _wire->write(READPOWERSUPPLY);
196 if (_wire->read_bit() == 0) ret = true;
197 _wire->reset();
198 return ret;
199 }
200
201
202 // set resolution of all devices to 9, 10, 11, or 12 bits
203 // if new resolution is out of range, it is constrained.
204 void DallasTemperature::setResolution(uint8_t newResolution)
205 {
206 bitResolution = constrain(newResolution, 9, 12);
207 DeviceAddress deviceAddress;
208 for (int i=0; i<devices; i++)
209 {
210 getAddress(deviceAddress, i);
211 setResolution(deviceAddress, bitResolution);
212 }
213 }
214
215 // set resolution of a device to 9, 10, 11, or 12 bits
216 // if new resolution is out of range, 9 bits is used.
217 bool DallasTemperature::setResolution(const uint8_t* deviceAddress, uint8_t newResolution)
218 {
219 ScratchPad scratchPad;
220 if (isConnected(deviceAddress, scratchPad))
221 {
222 // DS1820 and DS18S20 have no resolution configuration register
223 if (deviceAddress[0] != DS18S20MODEL)
224 {
225 switch (newResolution)
226 {
227 case 12:
228 scratchPad[CONFIGURATION] = TEMP_12_BIT;
229 break;
230 case 11:
231 scratchPad[CONFIGURATION] = TEMP_11_BIT;
232 break;
233 case 10:
234 scratchPad[CONFIGURATION] = TEMP_10_BIT;
235 break;
236 case 9:
237 default:
238 scratchPad[CONFIGURATION] = TEMP_9_BIT;
239 break;
240 }
241 writeScratchPad(deviceAddress, scratchPad);
242 }
243 return true; // new value set
244 }
245 return false;
246 }
247
248 // returns the global resolution
249 uint8_t DallasTemperature::getResolution()
250 {
251 return bitResolution;
252 }
253
254 // returns the current resolution of the device, 9-12
255 // returns 0 if device not found
256 uint8_t DallasTemperature::getResolution(const uint8_t* deviceAddress)
257 {
258 // DS1820 and DS18S20 have no resolution configuration register
259 if (deviceAddress[0] == DS18S20MODEL) return 12;
260
261 ScratchPad scratchPad;
262 if (isConnected(deviceAddress, scratchPad))
263 {
264 switch (scratchPad[CONFIGURATION])
265 {
266 case TEMP_12_BIT:
267 return 12;
268
269 case TEMP_11_BIT:
270 return 11;
271
272 case TEMP_10_BIT:
273 return 10;
274
275 case TEMP_9_BIT:
276 return 9;
277 }
278 }
279 return 0;
280 }
281
282
283 // sets the value of the waitForConversion flag
284 // TRUE : function requestTemperature() etc returns when conversion is ready
285 // FALSE: function requestTemperature() etc returns immediately (USE WITH CARE!!)
286 // (1) programmer has to check if the needed delay has passed
287 // (2) but the application can do meaningful things in that time
288 void DallasTemperature::setWaitForConversion(bool flag)
289 {
290 waitForConversion = flag;
291 }
292
293 // gets the value of the waitForConversion flag
294 bool DallasTemperature::getWaitForConversion()
295 {
296 return waitForConversion;
297 }
298
299
300 // sets the value of the checkForConversion flag
301 // TRUE : function requestTemperature() etc will 'listen' to an IC to determine whether a conversion is complete
302 // FALSE: function requestTemperature() etc will wait a set time (worst case scenario) for a conversion to complete
303 void DallasTemperature::setCheckForConversion(bool flag)
304 {
305 checkForConversion = flag;
306 }
307
308 // gets the value of the waitForConversion flag
309 bool DallasTemperature::getCheckForConversion()
310 {
311 return checkForConversion;
312 }
313
314 bool DallasTemperature::isConversionAvailable(const uint8_t* deviceAddress)
315 {
316 // Check if the clock has been raised indicating the conversion is complete
317 ScratchPad scratchPad;
318 readScratchPad(deviceAddress, scratchPad);
319 return scratchPad[0];
320 }
321
322
323 // sends command for all devices on the bus to perform a temperature conversion
324 void DallasTemperature::requestTemperatures()
325 {
326 _wire->reset();
327 _wire->skip();
328 _wire->write(STARTCONVO, parasite);
329
330 // ASYNC mode?
331 if (!waitForConversion) return;
332 blockTillConversionComplete(bitResolution, NULL);
333 }
334
335 // sends command for one device to perform a temperature by address
336 // returns FALSE if device is disconnected
337 // returns TRUE otherwise
338 bool DallasTemperature::requestTemperaturesByAddress(const uint8_t* deviceAddress)
339 {
340 _wire->reset();
341 _wire->select(deviceAddress);
342 _wire->write(STARTCONVO, parasite);
343
344 // check device
345 ScratchPad scratchPad;
346 if (!isConnected(deviceAddress, scratchPad)) return false;
347
348 // ASYNC mode?
349 if (!waitForConversion) return true;
350 blockTillConversionComplete(getResolution(deviceAddress), deviceAddress);
351
352 return true;
353 }
354
355 // returns number of milliseconds to wait till conversion is complete (based on IC datasheet)
356 int16_t DallasTemperature::millisToWaitForConversion(uint8_t bitResolution)
357 {
358 switch (bitResolution)
359 {
360 case 9:
361 return 94;
362 case 10:
363 return 188;
364 case 11:
365 return 375;
366 default:
367 return 750;
368 }
369 }
370
371 // Continue to check if the IC has responded with a temperature
372 void DallasTemperature::blockTillConversionComplete(uint8_t bitResolution, const uint8_t* deviceAddress)
373 {
374 int delms = millisToWaitForConversion(bitResolution);
375 if (deviceAddress != NULL && checkForConversion && !parasite)
376 {
377 unsigned long timend = millis() + delms;
378 while(!isConversionAvailable(deviceAddress) && (millis() < timend));
379 }
380 else
381 {
382 delay(delms);
383 }
384 }
385
386 // sends command for one device to perform a temp conversion by index
387 bool DallasTemperature::requestTemperaturesByIndex(uint8_t deviceIndex)
388 {
389 DeviceAddress deviceAddress;
390 getAddress(deviceAddress, deviceIndex);
391 return requestTemperaturesByAddress(deviceAddress);
392 }
393
394 // Fetch temperature for device index
395 float DallasTemperature::getTempCByIndex(uint8_t deviceIndex)
396 {
397 DeviceAddress deviceAddress;
398 if (!getAddress(deviceAddress, deviceIndex))
399 return DEVICE_DISCONNECTED_C;
400 return getTempC((uint8_t*)deviceAddress);
401 }
402
403 // Fetch temperature for device index
404 float DallasTemperature::getTempFByIndex(uint8_t deviceIndex)
405 {
406 DeviceAddress deviceAddress;
407 if (!getAddress(deviceAddress, deviceIndex))
408 return DEVICE_DISCONNECTED_F;
409 return getTempF((uint8_t*)deviceAddress);
410 }
411
412 // reads scratchpad and returns fixed-point temperature, scaling factor 2^-7
413 int16_t DallasTemperature::calculateTemperature(const uint8_t* deviceAddress, uint8_t* scratchPad)
414 {
415 int16_t fpTemperature =
416 (((int16_t) scratchPad[TEMP_MSB]) << 11) |
417 (((int16_t) scratchPad[TEMP_LSB]) << 3);
418
419 /*
420 DS1820 and DS18S20 have a 9-bit temperature register.
421
422 Resolutions greater than 9-bit can be calculated using the data from
423 the temperature, and COUNT REMAIN and COUNT PER °C registers in the
424 scratchpad. The resolution of the calculation depends on the model.
425
426 While the COUNT PER °C register is hard-wired to 16 (10h) in a
427 DS18S20, it changes with temperature in DS1820.
428
429 After reading the scratchpad, the TEMP_READ value is obtained by
430 truncating the 0.5°C bit (bit 0) from the temperature data. The
431 extended resolution temperature can then be calculated using the
432 following equation:
433
434 COUNT_PER_C - COUNT_REMAIN
435 TEMPERATURE = TEMP_READ - 0.25 + --------------------------
436 COUNT_PER_C
437
438 Hagai Shatz simplified this to integer arithmetic for a 12 bits
439 value for a DS18S20, and James Cameron added legacy DS1820 support.
440
441 See - http://myarduinotoy.blogspot.co.uk/2013/02/12bit-result-from-ds18s20.html
442 */
443
444 if (deviceAddress[0] == DS18S20MODEL)
445 fpTemperature = ((fpTemperature & 0xfff0) << 3) - 16 +
446 (
447 ((scratchPad[COUNT_PER_C] - scratchPad[COUNT_REMAIN]) << 7) /
448 scratchPad[COUNT_PER_C]
449 );
450
451 return fpTemperature;
452 }
453
454
455 // returns temperature in 1/128 degrees C or DEVICE_DISCONNECTED_RAW if the
456 // device's scratch pad cannot be read successfully.
457 // the numeric value of DEVICE_DISCONNECTED_RAW is defined in
458 // DallasTemperature.h. It is a large negative number outside the
459 // operating range of the device
460 int16_t DallasTemperature::getTemp(const uint8_t* deviceAddress)
461 {
462 ScratchPad scratchPad;
463 if (isConnected(deviceAddress, scratchPad)) return calculateTemperature(deviceAddress, scratchPad);
464 return DEVICE_DISCONNECTED_RAW;
465 }
466
467 // returns temperature in degrees C or DEVICE_DISCONNECTED_C if the
468 // device's scratch pad cannot be read successfully.
469 // the numeric value of DEVICE_DISCONNECTED_C is defined in
470 // DallasTemperature.h. It is a large negative number outside the
471 // operating range of the device
472 float DallasTemperature::getTempC(const uint8_t* deviceAddress)
473 {
474 return rawToCelsius(getTemp(deviceAddress));
475 }
476
477 // returns temperature in degrees F or DEVICE_DISCONNECTED_F if the
478 // device's scratch pad cannot be read successfully.
479 // the numeric value of DEVICE_DISCONNECTED_F is defined in
480 // DallasTemperature.h. It is a large negative number outside the
481 // operating range of the device
482 float DallasTemperature::getTempF(const uint8_t* deviceAddress)
483 {
484 return rawToFahrenheit(getTemp(deviceAddress));
485 }
486
487 // returns true if the bus requires parasite power
488 bool DallasTemperature::isParasitePowerMode(void)
489 {
490 return parasite;
491 }
492
493 #if REQUIRESALARMS
494
495 /*
496
497 ALARMS:
498
499 TH and TL Register Format
500
501 BIT 7 BIT 6 BIT 5 BIT 4 BIT 3 BIT 2 BIT 1 BIT 0
502 S 2^6 2^5 2^4 2^3 2^2 2^1 2^0
503
504 Only bits 11 through 4 of the temperature register are used
505 in the TH and TL comparison since TH and TL are 8-bit
506 registers. If the measured temperature is lower than or equal
507 to TL or higher than or equal to TH, an alarm condition exists
508 and an alarm flag is set inside the DS18B20. This flag is
509 updated after every temperature measurement; therefore, if the
510 alarm condition goes away, the flag will be turned off after
511 the next temperature conversion.
512
513 */
514
515 // sets the high alarm temperature for a device in degrees Celsius
516 // accepts a float, but the alarm resolution will ignore anything
517 // after a decimal point. valid range is -55C - 125C
518 void DallasTemperature::setHighAlarmTemp(const uint8_t* deviceAddress, char celsius)
519 {
520 // make sure the alarm temperature is within the device's range
521 if (celsius > 125) celsius = 125;
522 else if (celsius < -55) celsius = -55;
523
524 ScratchPad scratchPad;
525 if (isConnected(deviceAddress, scratchPad))
526 {
527 scratchPad[HIGH_ALARM_TEMP] = (uint8_t)celsius;
528 writeScratchPad(deviceAddress, scratchPad);
529 }
530 }
531
532 // sets the low alarm temperature for a device in degrees Celsius
533 // accepts a float, but the alarm resolution will ignore anything
534 // after a decimal point. valid range is -55C - 125C
535 void DallasTemperature::setLowAlarmTemp(const uint8_t* deviceAddress, char celsius)
536 {
537 // make sure the alarm temperature is within the device's range
538 if (celsius > 125) celsius = 125;
539 else if (celsius < -55) celsius = -55;
540
541 ScratchPad scratchPad;
542 if (isConnected(deviceAddress, scratchPad))
543 {
544 scratchPad[LOW_ALARM_TEMP] = (uint8_t)celsius;
545 writeScratchPad(deviceAddress, scratchPad);
546 }
547 }
548
549 // returns a char with the current high alarm temperature or
550 // DEVICE_DISCONNECTED for an address
551 char DallasTemperature::getHighAlarmTemp(const uint8_t* deviceAddress)
552 {
553 ScratchPad scratchPad;
554 if (isConnected(deviceAddress, scratchPad)) return (char)scratchPad[HIGH_ALARM_TEMP];
555 return DEVICE_DISCONNECTED_C;
556 }
557
558 // returns a char with the current low alarm temperature or
559 // DEVICE_DISCONNECTED for an address
560 char DallasTemperature::getLowAlarmTemp(const uint8_t* deviceAddress)
561 {
562 ScratchPad scratchPad;
563 if (isConnected(deviceAddress, scratchPad)) return (char)scratchPad[LOW_ALARM_TEMP];
564 return DEVICE_DISCONNECTED_C;
565 }
566
567 // resets internal variables used for the alarm search
568 void DallasTemperature::resetAlarmSearch()
569 {
570 alarmSearchJunction = -1;
571 alarmSearchExhausted = 0;
572 for(uint8_t i = 0; i < 7; i++)
573 alarmSearchAddress[i] = 0;
574 }
575
576 // This is a modified version of the OneWire::search method.
577 //
578 // Also added the OneWire search fix documented here:
579 // http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1238032295
580 //
581 // Perform an alarm search. If this function returns a '1' then it has
582 // enumerated the next device and you may retrieve the ROM from the
583 // OneWire::address variable. If there are no devices, no further
584 // devices, or something horrible happens in the middle of the
585 // enumeration then a 0 is returned. If a new device is found then
586 // its address is copied to newAddr. Use
587 // DallasTemperature::resetAlarmSearch() to start over.
588 bool DallasTemperature::alarmSearch(uint8_t* newAddr)
589 {
590 uint8_t i;
591 char lastJunction = -1;
592 uint8_t done = 1;
593
594 if (alarmSearchExhausted) return false;
595 if (!_wire->reset()) return false;
596
597 // send the alarm search command
598 _wire->write(0xEC, 0);
599
600 for(i = 0; i < 64; i++)
601 {
602 uint8_t a = _wire->read_bit( );
603 uint8_t nota = _wire->read_bit( );
604 uint8_t ibyte = i / 8;
605 uint8_t ibit = 1 << (i & 7);
606
607 // I don't think this should happen, this means nothing responded, but maybe if
608 // something vanishes during the search it will come up.
609 if (a && nota) return false;
610
611 if (!a && !nota)
612 {
613 if (i == alarmSearchJunction)
614 {
615 // this is our time to decide differently, we went zero last time, go one.
616 a = 1;
617 alarmSearchJunction = lastJunction;
618 }
619 else if (i < alarmSearchJunction)
620 {
621 // take whatever we took last time, look in address
622 if (alarmSearchAddress[ibyte] & ibit) a = 1;
623 else
624 {
625 // Only 0s count as pending junctions, we've already exhausted the 0 side of 1s
626 a = 0;
627 done = 0;
628 lastJunction = i;
629 }
630 }
631 else
632 {
633 // we are blazing new tree, take the 0
634 a = 0;
635 alarmSearchJunction = i;
636 done = 0;
637 }
638 // OneWire search fix
639 // See: http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1238032295
640 }
641
642 if (a) alarmSearchAddress[ibyte] |= ibit;
643 else alarmSearchAddress[ibyte] &= ~ibit;
644
645 _wire->write_bit(a);
646 }
647
648 if (done) alarmSearchExhausted = 1;
649 for (i = 0; i < 8; i++) newAddr[i] = alarmSearchAddress[i];
650 return true;
651 }
652
653 // returns true if device address might have an alarm condition
654 // (only an alarm search can verify this)
655 bool DallasTemperature::hasAlarm(const uint8_t* deviceAddress)
656 {
657 ScratchPad scratchPad;
658 if (isConnected(deviceAddress, scratchPad))
659 {
660 char temp = calculateTemperature(deviceAddress, scratchPad) >> 7;
661
662 // check low alarm
663 if (temp <= (char)scratchPad[LOW_ALARM_TEMP]) return true;
664
665 // check high alarm
666 if (temp >= (char)scratchPad[HIGH_ALARM_TEMP]) return true;
667 }
668
669 // no alarm
670 return false;
671 }
672
673 // returns true if any device is reporting an alarm condition on the bus
674 bool DallasTemperature::hasAlarm(void)
675 {
676 DeviceAddress deviceAddress;
677 resetAlarmSearch();
678 return alarmSearch(deviceAddress);
679 }
680
681 // runs the alarm handler for all devices returned by alarmSearch()
682 void DallasTemperature::processAlarms(void)
683 {
684 resetAlarmSearch();
685 DeviceAddress alarmAddr;
686
687 while (alarmSearch(alarmAddr))
688 {
689 if (validAddress(alarmAddr))
690 _AlarmHandler(alarmAddr);
691 }
692 }
693
694 // sets the alarm handler
695 void DallasTemperature::setAlarmHandler(AlarmHandler *handler)
696 {
697 _AlarmHandler = handler;
698 }
699
700 // The default alarm handler
701 void DallasTemperature::defaultAlarmHandler(const uint8_t* deviceAddress)
702 {
703 }
704
705 #endif
706
707 // Convert float Celsius to Fahrenheit
708 float DallasTemperature::toFahrenheit(float celsius)
709 {
710 return (celsius * 1.8) + 32;
711 }
712
713 // Convert float Fahrenheit to Celsius
714 float DallasTemperature::toCelsius(float fahrenheit)
715 {
716 return (fahrenheit - 32) * 0.555555556;
717 }
718
719 // convert from raw to Celsius
720 float DallasTemperature::rawToCelsius(int16_t raw)
721 {
722 if (raw <= DEVICE_DISCONNECTED_RAW)
723 return DEVICE_DISCONNECTED_C;
724 // C = RAW/128
725 return (float)raw * 0.0078125;
726 }
727
728 // convert from raw to Fahrenheit
729 float DallasTemperature::rawToFahrenheit(int16_t raw)
730 {
731 if (raw <= DEVICE_DISCONNECTED_RAW)
732 return DEVICE_DISCONNECTED_F;
733 // C = RAW/128
734 // F = (C*1.8)+32 = (RAW/128*1.8)+32 = (RAW*0.0140625)+32
735 return ((float)raw * 0.0140625) + 32;
736 }
737
738 #if REQUIRESNEW
739
740 // MnetCS - Allocates memory for DallasTemperature. Allows us to instance a new object
741 void* DallasTemperature::operator new(unsigned int size) // Implicit NSS obj size
742 {
743 void * p; // void pointer
744 p = malloc(size); // Allocate memory
745 memset((DallasTemperature*)p,0,size); // Initialise memory
746
747 //!!! CANT EXPLICITLY CALL CONSTRUCTOR - workaround by using an init() methodR - workaround by using an init() method
748 return (DallasTemperature*) p; // Cast blank region to NSS pointer
749 }
750
751 // MnetCS 2009 - Free the memory used by this instance
752 void DallasTemperature::operator delete(void* p)
753 {
754 DallasTemperature* pNss = (DallasTemperature*) p; // Cast to NSS pointer
755 pNss->~DallasTemperature(); // Destruct the object
756
757 free(p); // Free the memory
758 }
759
760 #endif