From 0b69c9bc8fc7e20ba2986bb98baa8fb1eb39da92 Mon Sep 17 00:00:00 2001 From: Arnd Date: Sat, 3 Dec 2016 13:38:40 +0000 Subject: [PATCH] Minimized conversion wait times If the last command issued on the 1-Wire is a "convert temperature", then reads can be done until the value returned is 1, which means that the conversion is finished. The conversion times in the manuals are maximum values, actual conversion times are much faster and the only reason to delay the maximum times are when one or more devices are parasitically powered. --- DSFamily.cpp | 32 +++++++++++++++++++++++--------- DSFamily.h | 5 ++++- 2 files changed, 27 insertions(+), 10 deletions(-) diff --git a/DSFamily.cpp b/DSFamily.cpp index ca597ec..57a90b5 100644 --- a/DSFamily.cpp +++ b/DSFamily.cpp @@ -67,6 +67,7 @@ DSFamily_Class::~DSFamily_Class() { } // *******************************************************************************************************************/ uint8_t DSFamily_Class::ScanForDevices() { // // uint8_t tempTherm[8]; // Temporary DS address array // + _LastCommandWasConvert = false; // Set switch to false // reset_search(); // Reset the search status // ThermometersFound = 0; // Reset the number of thermometers // while (search(tempTherm)) { // Use the 1-Wire "search" method // @@ -92,6 +93,7 @@ uint8_t DSFamily_Class::ScanForDevices() { // *******************************************************************************************************************/ boolean DSFamily_Class::Read1WireScratchpad(const uint8_t deviceNumber, // // uint8_t buffer[9]) { // // + _LastCommandWasConvert = false; // Set switch to false // SelectDevice(deviceNumber); // Reset the 1-wire, address device // write_byte(DS_READ_SCRATCHPAD); // Request device send Scratchpad // for (uint8_t i=0;i<9;i++) buffer[i] = read_byte(); // read all 9 bytes sent by DS // @@ -110,8 +112,10 @@ int16_t DSFamily_Class::ReadDeviceTemp(const uint8_t deviceNumber, // const bool raw=false) { // // uint8_t dsBuffer[9]; // Buffer to hold scratchpad return // int16_t temperature = DS_BAD_TEMPERATURE; // Holds return value // - if ((_ConvStartTime+ConversionMillis)>millis()) // If a conversion is still running // + if (Parasitic || !_LastCommandWasConvert) { // Wait a fixed time in parasite or // + if ((_ConvStartTime+ConversionMillis)>millis()) // If a conversion is still running // delay(millis()-(_ConvStartTime+ConversionMillis)); // then wait until it is finished // + } else if (_LastCommandWasConvert) while(read_bit()==0); // bit high when conversion finished// if ( deviceNumber < ThermometersFound && // on a successful read from the // Read1WireScratchpad(deviceNumber,dsBuffer)) { // device scratchpad // if (dsBuffer[0]==DS1822_FAMILY) { // The results returned by DS18S20 // @@ -126,10 +130,12 @@ int16_t DSFamily_Class::ReadDeviceTemp(const uint8_t deviceNumber, // /******************************************************************************************************************* ** method DeviceStartConvert() to start the sampling and conversion on a device. At maximum resolution this ** -** conversion can take 750ms. If the optional parameter is not specified then all device conversions are started ** -** at the same time ** +** conversion can take 750ms. If the optional deviceNumber is not specified then all device conversions are ** +** started at the same time. If the optional WaitSwitch parameter is set to "true" then call doesn't return until ** +** the conversion has completed ** *******************************************************************************************************************/ -void DSFamily_Class::DeviceStartConvert(const uint8_t deviceNumber=UINT8_MAX){// // +void DSFamily_Class::DeviceStartConvert(const uint8_t deviceNumber=UINT8_MAX, // // + const bool WaitSwitch = false) { // // ParasiticWait(); // Wait for conversion if necessary // if (deviceNumber==UINT8_MAX) { // If no parameter specified, use // reset(); // Reset 1-wire network // @@ -137,6 +143,8 @@ void DSFamily_Class::DeviceStartConvert(const uint8_t deviceNumber=UINT8_MAX){// } else SelectDevice(deviceNumber); // of if-then all devices or just one // // write_byte(DS_START_CONVERT); // Initiate temperature conversion // _ConvStartTime = millis(); // Store start time of conversion // + _LastCommandWasConvert = true; // Set switch to true // + if (!Parasitic && WaitSwitch) while(read_bit()==0); // Read bit goes high when finished // } // of method DeviceStartConvert //----------------------------------// /******************************************************************************************************************* @@ -161,6 +169,7 @@ void DSFamily_Class::Calibrate(const uint8_t iterations=30) { // int64_t tempSum = 0; // Stores interim values // int8_t offset = 0; // Stores the computed offset value // uint8_t ThermometersUsed = min(DS_MAX_THERMOMETERS,ThermometersFound); // Use the lower of the 2 values // + _LastCommandWasConvert = false; // Set switch to false // for (uint8_t i=0;i12) resolution = 12; // Default to full resolution // switch (resolution) { // Now select which action to do // case 12: // When 12 bits of precision used // @@ -319,11 +332,12 @@ void DSFamily_Class::SetDeviceResolution(const uint8_t deviceNumber, // ** Method SetUserBytes to set the user bytes 1 and 2 to the calibration computed ** *******************************************************************************************************************/ uint8_t DSFamily_Class::GetDeviceResolution(const uint8_t deviceNumber) { // // - uint8_t resolution; // Store the return value // - uint8_t dsBuffer[9]; // Hold scratchpad return values // - Read1WireScratchpad(deviceNumber,dsBuffer); // Read from the device scratchpad // - resolution = (dsBuffer[DS_CONFIG_BYTE]>>5)+9; // get bits 6&7 from the config byte// - return(resolution); // // + uint8_t resolution; // Store the return value // + uint8_t dsBuffer[9]; // Hold scratchpad return values // + _LastCommandWasConvert = false; // Set switch to false // + Read1WireScratchpad(deviceNumber,dsBuffer); // Read from the device scratchpad // + resolution = (dsBuffer[DS_CONFIG_BYTE]>>5)+9; // get bits 6&7 from the config byte// + return(resolution); // // } // of method GetDeviceResolution() //----------------------------------// /******************************************************************************************************************* diff --git a/DSFamily.h b/DSFamily.h index 1582ae7..010d0ba 100644 --- a/DSFamily.h +++ b/DSFamily.h @@ -51,6 +51,7 @@ ** ** ** Vers. Date Developer Comments ** ** ====== ========== =================== ======================================================================== ** +** 1.0.2 2016-12-03 Arnd@SV-Zanshin.Com Added optional ReadDeviceTemp "WaitSwitch", minimized conversion delays ** ** 1.0.1 2016-12-02 Arnd@SV-Zanshin.Com Added delays for ReadDeviceTemp() and when a parasitic device is present ** ** 1.0.0 2016-12-01 Arnd@SV-Zanshin.Com Initial release ** ** 1.0.b5 2016-11-30 Arnd@SV-Zanshin.Com Moved 1-Wire calls to private, refactored some of the calls ** @@ -136,7 +137,8 @@ uint8_t ScanForDevices (); // Scan/rescan the 1-Wire microLAN // int16_t ReadDeviceTemp (const uint8_t deviceNumber, // Return the temperature // const bool raw=false); // optionally using the raw value // - void DeviceStartConvert (const uint8_t deviceNumber=UINT8_MAX); // Start conversion on device // + void DeviceStartConvert (const uint8_t deviceNumber=UINT8_MAX, // Start conversion on device // + const bool WaitSwitch=false); // optionally wait for it to finish // void Calibrate (const uint8_t iterations=30); // Calibrate to read identically // int8_t GetDeviceCalibration(const uint8_t deviceNumber); // Get the device's calibration // void SetDeviceCalibration(const uint8_t deviceNumber, // Set calibration bytes 1 & 2 // @@ -156,6 +158,7 @@ void ParasiticWait(); // Wait for conversion if parasitic // uint8_t _MaxThermometers; // Devices fit (EEPROM-ReserveRom) // uint32_t _ConvStartTime; // Conversion start time // + bool _LastCommandWasConvert=false; // Unset when other commands issued // IO_REG_TYPE bitmask; // // volatile IO_REG_TYPE *baseReg; // // unsigned char ROM_NO[8]; // global search state //