From a2943e393aca8c0d0cbc6f60dbb383b2fa49d9c6 Mon Sep 17 00:00:00 2001 From: Eric Chavet Date: Fri, 26 May 2023 16:18:18 +0200 Subject: [PATCH] Refactor DS18B20 Temperature Conversion Time Handling Currently, the DS18B20 driver uses a fixed delay of 1 millisecond (board.io.sendOneWireDelay(pin, 1);) after requesting each sensor to perform a temperature conversion. However, the DS18B20 datasheet specifies that a conversion actually takes up to 750 milliseconds. This misalignment could potentially lead to inaccuracies when reading from multiple DS18B20 sensors simultaneously, particularly if the requested frequency (options.freq) is shorter than the time required for a temperature conversion. Additionally, it's important to note that the implementation of the delayTask function on the Firmata side is not fully functional and relies on the inclusion of a "FirmataScheduler" module, which merely adds processor cycles and does not provide a true delay mechanism. https://github.com/rwaldron/johnny-five/issues/1823 --- lib/thermometer.js | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/lib/thermometer.js b/lib/thermometer.js index ad15b07e4..63178e40e 100644 --- a/lib/thermometer.js +++ b/lib/thermometer.js @@ -222,22 +222,24 @@ const Drivers = { board.io.sendOneWireReset(pin); board.io.sendOneWireWrite(pin, device, CONSTANTS.CONVERT_TEMPERATURE_COMMAND); }); - - // the delay gives the sensor time to do the calculation - board.io.sendOneWireDelay(pin, 1); + + // board.io.sendOneWireDelay(pin, 1); + + // the DS18B20 datasheet specifies that a conversion actually takes up to 750 milliseconds. + let conversionTime = 750; // Time needed for temperature conversion readOne = () => { let device; if (devicesToRead.length === 0) { - setTimeout(readThermometer, freq); + setTimeout(readThermometer, Math.max(0, freq - conversionTime)); // adjust delay to achieve desired freq return; } device = devicesToRead.pop(); + // read from the scratchpad board.io.sendOneWireReset(pin); - board.io.sendOneWireWriteAndRead(pin, device, CONSTANTS.READ_SCRATCHPAD_COMMAND, CONSTANTS.READ_COUNT, (err, data) => { if (err) { this.emit("error", err); @@ -248,10 +250,10 @@ const Drivers = { this.emit("data", getAddress(device), result); readOne(); - }); - }; - readOne(); + }); + }; + setTimeout(readOne, conversionTime); }; readThermometer();