@@ -22,6 +22,18 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
2222SOFTWARE.
2323*/
2424
25+ #if defined(PLATFORM_ID) // Only defined if a Particle device
26+ inline void yield () {
27+ Particle.process ();
28+ }
29+ #elif ARDUINO >= 100
30+ #include " Arduino.h"
31+ #else
32+ extern " C" {
33+ #include " WConstants.h"
34+ }
35+ #endif
36+
2537#include " DallasTemperature.h"
2638
2739// OneWire commands
@@ -50,6 +62,7 @@ SOFTWARE.
5062#define TEMP_11_BIT 0x5F // 11 bit
5163#define TEMP_12_BIT 0x7F // 12 bit
5264
65+ // Constructors
5366DallasTemperature::DallasTemperature () {
5467#if REQUIRESALARMS
5568 setAlarmHandler (nullptr );
@@ -121,6 +134,50 @@ void DallasTemperature::begin(void) {
121134 }
122135}
123136
137+ // Device Information Methods
138+ bool DallasTemperature::validFamily (const uint8_t * deviceAddress) {
139+ switch (deviceAddress[0 ]) {
140+ case DS18S20MODEL:
141+ case DS18B20MODEL:
142+ case DS1822MODEL:
143+ case DS1825MODEL:
144+ case DS28EA00MODEL:
145+ return true ;
146+ default :
147+ return false ;
148+ }
149+ }
150+
151+ bool DallasTemperature::validAddress (const uint8_t * deviceAddress) {
152+ return (_wire->crc8 (const_cast <uint8_t *>(deviceAddress), 7 ) == deviceAddress[7 ]);
153+ }
154+
155+ bool DallasTemperature::getAddress (uint8_t * deviceAddress, uint8_t index) {
156+ if (index < devices) {
157+ uint8_t depth = 0 ;
158+
159+ _wire->reset_search ();
160+
161+ while (depth <= index && _wire->search (deviceAddress)) {
162+ if (depth == index && validAddress (deviceAddress)) {
163+ return true ;
164+ }
165+ depth++;
166+ }
167+ }
168+
169+ return false ;
170+ }
171+
172+ // Device Count Methods
173+ uint8_t DallasTemperature::getDeviceCount (void ) {
174+ return devices;
175+ }
176+
177+ uint8_t DallasTemperature::getDS18Count (void ) {
178+ return ds18Count;
179+ }
180+
124181// Alternative device count verification method
125182bool DallasTemperature::verifyDeviceCount (void ) {
126183 uint8_t actualCount = 0 ;
@@ -144,34 +201,200 @@ bool DallasTemperature::verifyDeviceCount(void) {
144201 return false ;
145202}
146203
147- // Returns the number of devices found on the bus
148- uint8_t DallasTemperature::getDeviceCount (void ) {
149- return devices;
204+ // Temperature reading with retry functionality
205+ int32_t DallasTemperature::getTemp (const uint8_t * deviceAddress, byte retryCount) {
206+ ScratchPad scratchPad;
207+ byte retries = 0 ;
208+
209+ while (retries++ <= retryCount) {
210+ if (isConnected (deviceAddress, scratchPad)) {
211+ return calculateTemperature (deviceAddress, scratchPad);
212+ }
213+ }
214+
215+ return DEVICE_DISCONNECTED_RAW;
150216}
151217
152- uint8_t DallasTemperature::getDS18Count ( void ) {
153- return ds18Count ;
218+ float DallasTemperature::getTempC ( const uint8_t * deviceAddress, byte retryCount ) {
219+ return rawToCelsius ( getTemp (deviceAddress, retryCount)) ;
154220}
155221
156- bool DallasTemperature::validFamily (const uint8_t * deviceAddress) {
157- switch (deviceAddress[0 ]) {
158- case DS18S20MODEL:
159- case DS18B20MODEL:
160- case DS1822MODEL:
161- case DS1825MODEL:
162- case DS28EA00MODEL:
163- return true ;
164- default :
165- return false ;
222+ float DallasTemperature::getTempF (const uint8_t * deviceAddress) {
223+ return rawToFahrenheit (getTemp (deviceAddress));
224+ }
225+
226+ // Temperature request methods
227+ request_t DallasTemperature::requestTemperatures (void ) {
228+ request_t req = {};
229+ req.result = true ;
230+
231+ _wire->reset ();
232+ _wire->skip ();
233+ _wire->write (STARTCONVO, parasite);
234+
235+ req.timestamp = millis ();
236+ if (!waitForConversion) {
237+ return req;
166238 }
239+
240+ blockTillConversionComplete (bitResolution, req.timestamp );
241+ return req;
167242}
168243
169- bool DallasTemperature::validAddress (const uint8_t * deviceAddress) {
170- return (_wire->crc8 (const_cast <uint8_t *>(deviceAddress), 7 ) == deviceAddress[7 ]);
244+ request_t DallasTemperature::requestTemperaturesByAddress (const uint8_t * deviceAddress) {
245+ request_t req = {};
246+ uint8_t deviceBitResolution = getResolution (deviceAddress);
247+
248+ if (deviceBitResolution == 0 ) {
249+ req.result = false ;
250+ return req;
251+ }
252+
253+ _wire->reset ();
254+ _wire->select (deviceAddress);
255+ _wire->write (STARTCONVO, parasite);
256+
257+ req.timestamp = millis ();
258+ req.result = true ;
259+
260+ if (!waitForConversion) {
261+ return req;
262+ }
263+
264+ blockTillConversionComplete (deviceBitResolution, req.timestamp );
265+ return req;
171266}
172267
173- bool DallasTemperature::getAddress (uint8_t * deviceAddress, uint8_t index) {
174- if (index < devices) {
175- uint8_t depth = 0 ;
268+ // Resolution control methods
269+ void DallasTemperature::setResolution (uint8_t newResolution) {
270+ bitResolution = constrain (newResolution, 9 , 12 );
271+
272+ DeviceAddress deviceAddress;
273+ _wire->reset_search ();
274+
275+ for (uint8_t i = 0 ; i < devices; i++) {
276+ if (_wire->search (deviceAddress) && validAddress (deviceAddress)) {
277+ setResolution (deviceAddress, bitResolution, true );
278+ }
279+ }
280+ }
281+
282+ bool DallasTemperature::setResolution (const uint8_t * deviceAddress, uint8_t newResolution, bool skipGlobalBitResolutionCalculation) {
283+ bool success = false ;
284+
285+ // DS1820 and DS18S20 have no resolution configuration register
286+ if (deviceAddress[0 ] == DS18S20MODEL) {
287+ success = true ;
288+ } else {
289+ newResolution = constrain (newResolution, 9 , 12 );
290+ uint8_t newValue = 0 ;
291+ ScratchPad scratchPad;
292+
293+ if (isConnected (deviceAddress, scratchPad)) {
294+ switch (newResolution) {
295+ case 12 :
296+ newValue = TEMP_12_BIT;
297+ break ;
298+ case 11 :
299+ newValue = TEMP_11_BIT;
300+ break ;
301+ case 10 :
302+ newValue = TEMP_10_BIT;
303+ break ;
304+ case 9 :
305+ default :
306+ newValue = TEMP_9_BIT;
307+ break ;
308+ }
309+
310+ if (scratchPad[CONFIGURATION] != newValue) {
311+ scratchPad[CONFIGURATION] = newValue;
312+ writeScratchPad (deviceAddress, scratchPad);
313+ }
314+ success = true ;
315+ }
316+ }
317+
318+ // Update global resolution if needed
319+ if (!skipGlobalBitResolutionCalculation && success) {
320+ bitResolution = newResolution;
176321
177- _wire->reset_
322+ if (devices > 1 ) {
323+ DeviceAddress deviceAddr;
324+ _wire->reset_search ();
325+
326+ for (uint8_t i = 0 ; i < devices; i++) {
327+ if (bitResolution == 12 ) break ;
328+
329+ if (_wire->search (deviceAddr) && validAddress (deviceAddr)) {
330+ uint8_t b = getResolution (deviceAddr);
331+ if (b > bitResolution) bitResolution = b;
332+ }
333+ }
334+ }
335+ }
336+
337+ return success;
338+ }
339+
340+ // Utility methods
341+ float DallasTemperature::toFahrenheit (float celsius) {
342+ return (celsius * 1 .8f ) + 32 .0f ;
343+ }
344+
345+ float DallasTemperature::toCelsius (float fahrenheit) {
346+ return (fahrenheit - 32 .0f ) * 0 .555555556f ;
347+ }
348+
349+ float DallasTemperature::rawToCelsius (int32_t raw) {
350+ if (raw <= DEVICE_DISCONNECTED_RAW) {
351+ return DEVICE_DISCONNECTED_C;
352+ }
353+ return (float )raw * 0 .0078125f ; // 1/128
354+ }
355+
356+ float DallasTemperature::rawToFahrenheit (int32_t raw) {
357+ if (raw <= DEVICE_DISCONNECTED_RAW) {
358+ return DEVICE_DISCONNECTED_F;
359+ }
360+ return (float )raw * 0 .0140625f + 32 .0f ; // 1/128*1.8 + 32
361+ }
362+
363+ int16_t DallasTemperature::celsiusToRaw (float celsius) {
364+ return static_cast <int16_t >(celsius * 128 .0f );
365+ }
366+
367+ // Internal helper methods
368+ bool DallasTemperature::isAllZeros (const uint8_t * const scratchPad, const size_t length) {
369+ for (size_t i = 0 ; i < length; i++) {
370+ if (scratchPad[i] != 0 ) {
371+ return false ;
372+ }
373+ }
374+ return true ;
375+ }
376+
377+ void DallasTemperature::activateExternalPullup () {
378+ if (useExternalPullup) {
379+ digitalWrite (pullupPin, LOW);
380+ }
381+ }
382+
383+ void DallasTemperature::deactivateExternalPullup () {
384+ if (useExternalPullup) {
385+ digitalWrite (pullupPin, HIGH);
386+ }
387+ }
388+
389+ // Memory management if required
390+ #if REQUIRESNEW
391+ void * DallasTemperature::operator new (unsigned int size) {
392+ void * p = malloc (size);
393+ memset (p, 0 , size);
394+ return p;
395+ }
396+
397+ void DallasTemperature::operator delete (void * p) {
398+ free (p);
399+ }
400+ #endif
0 commit comments