Skip to content

Commit

Permalink
Minimized conversion wait times
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
Arnd authored Dec 3, 2016
1 parent 8e68828 commit 0b69c9b
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 10 deletions.
32 changes: 23 additions & 9 deletions DSFamily.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 //
Expand All @@ -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 //
Expand All @@ -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 //
Expand All @@ -126,17 +130,21 @@ 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 //
write_byte(DS_SKIP_ROM); // Tell all devices to listen //
} 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 //----------------------------------//

/*******************************************************************************************************************
Expand All @@ -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;i<iterations;i++) { // Loop to get a good sampling //
for(uint8_t x=0;x<ThermometersUsed;x++) { // process each thermometer //
stats1[x] += ReadDeviceTemp(x,true); // read raw temperature, no offset //
Expand All @@ -182,6 +191,7 @@ void DSFamily_Class::Calibrate(const uint8_t iterations=30) { //
void DSFamily_Class::SetDeviceCalibration(const uint8_t deviceNumber, // //
const int8_t offset) { // //
uint8_t dsBuffer[9]; // Temporary scratchpad buffer //
_LastCommandWasConvert = false; // Set switch to false //
Read1WireScratchpad(deviceNumber,dsBuffer); // Read from the device scratchpad //
SelectDevice(deviceNumber); // Reset 1-wire, address device //
write_byte(DS_WRITE_SCRATCHPAD); // Write scratchpad, send 3 bytes //
Expand All @@ -199,6 +209,7 @@ void DSFamily_Class::SetDeviceCalibration(const uint8_t deviceNumber, //
int8_t DSFamily_Class::GetDeviceCalibration(const uint8_t deviceNumber) { // //
int8_t offset = INT8_MIN; // Default to an invalid value //
uint8_t dsBuffer[9]; // Temporary scratchpad buffer //
_LastCommandWasConvert = false; // Set switch to false //
Read1WireScratchpad(deviceNumber,dsBuffer); // Read from the device scratchpad //
if (dsBuffer[2]^dsBuffer[3]==0xFF) offset = (int8_t)dsBuffer[2]; // Use the calibration value //
return (offset); // Return the computed offset //
Expand All @@ -221,6 +232,7 @@ void DSFamily_Class::SelectDevice(const uint8_t deviceNumber) { //
*******************************************************************************************************************/
void DSFamily_Class::GetDeviceROM(const uint8_t deviceNumber, // //
uint8_t ROMBuffer[8]) { // Array to hold unique DS ID //
_LastCommandWasConvert = false; // Set switch to false //
for (uint8_t i=0;i<8;i++) // loop for each byte in the buffer //
ROMBuffer[i]=EEPROM.read(i+E2END-((deviceNumber+1)*8)); // Read the EEPROM byte //
} // of method GetDeviceROM() //----------------------------------//
Expand Down Expand Up @@ -287,6 +299,7 @@ int16_t DSFamily_Class::AvgTemperature(const uint8_t skipDeviceNumber=UINT8_MAX)
void DSFamily_Class::SetDeviceResolution(const uint8_t deviceNumber, // Set resolution to 9,10,11 or 12 b//
uint8_t resolution) { // //
uint8_t dsBuffer[9]; // Buffer to hold scratchpad values //
_LastCommandWasConvert = false; // Set switch to false //
if(resolution<9 || resolution>12) resolution = 12; // Default to full resolution //
switch (resolution) { // Now select which action to do //
case 12: // When 12 bits of precision used //
Expand Down Expand Up @@ -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() //----------------------------------//

/*******************************************************************************************************************
Expand Down
5 changes: 4 additions & 1 deletion DSFamily.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
** **
** Vers. Date Developer Comments **
** ====== ========== =================== ======================================================================== **
** 1.0.2 2016-12-03 [email protected] Added optional ReadDeviceTemp "WaitSwitch", minimized conversion delays **
** 1.0.1 2016-12-02 [email protected] Added delays for ReadDeviceTemp() and when a parasitic device is present **
** 1.0.0 2016-12-01 [email protected] Initial release **
** 1.0.b5 2016-11-30 [email protected] Moved 1-Wire calls to private, refactored some of the calls **
Expand Down Expand Up @@ -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 //
Expand All @@ -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 //
Expand Down

0 comments on commit 0b69c9b

Please sign in to comment.