Looking at the OneWire code, the following functions take at least (due to delayMicros()):
- OneWire::reset() - 1000 - 1250 micros = ~1.5 millis()
- OneWire::write() - ~70 micros / bit == 0.6 millis per byte
- OneWire::readBit() ~65 micros / bit == 0.6 millis per byte
with this knowledge we can calc the minimum time of getTempC(), it calls isConnected, which calls readScratchPad, which is the communication workhorse..
float DallasTemperature::getTempC(uint8_t* deviceAddress)
{
ScratchPad scratchPad;
if (isConnected(deviceAddress, scratchPad)) return calculateTemperature(deviceAddress, scratchPad);
return DEVICE_DISCONNECTED;
}
bool DallasTemperature::isConnected(uint8_t* deviceAddress, uint8_t* scratchPad)
{
readScratchPad(deviceAddress, scratchPad);
return (_wire->crc8(scratchPad, 8) == scratchPad[SCRATCHPAD_CRC]);
}
readScratchPad()
{
// send the command
_wire->reset(); // 1.5 millis
_wire->select(deviceAddress); // command + 8 bytes == 9 * 0.6 = 5.4 millis.
_wire->write(READSCRATCH); // command == 0.6 millis
for(int i=0; i<9; i++) // 9 bytes *0.6 = 5.4 millis
{
scratchPad[i] = _wire->read();
}
_wire->reset(); // 1.5 millis
}
So only the delayMIcroseconds in the handshake needed for getTempC take at least 14.4 ms. That is allready 70% of the 20 ms you wait. So only 30% of the time it is executing code. During all this IO it continuously clears and sets the interrupt bit, so it won't miss a bit.
Some possible tweaks to increase speed
(all disclaimers apply I have not tested this!)1) remove the
last _wire->reset(); from readScratchpad(), ==> win 1.5 millis
think this is quite save as all functions reset the wire at their start
2) replace return (_wire->crc8(scratchPad,

== scratchPad[SCRATCHPAD_CRC]); with return true;
just don't check if data is valid ==> gain ?? 1 millis?
3) fetch only the first two bytes when reading scratchpad ==> screws the protocol - dangerous!!
gain 7 *0.6 = 4.2 millis
Mixing these latter 2 could make create something like:
void readScratchPadFast()
{
// send the command
_wire->reset(); // 1.5 millis
_wire->select(deviceAddress); // command + 8 bytes == 9 * 0.6 = 5.4 millis. **
_wire->write(READSCRATCH); // command == 0.6 millis
scratchPad[0] = _wire->read(); // read only the temperature bytes
scratchPad[1] = _wire->read(); // 2 * 0.6 = 1.2 millis
}
If all these tweaks work and don't harm the protocoll too much you can win approx 6 ms;
This could bring the time for getTempC from 20 ms down to ~14 ms. ?? (still 8 millis active waiting ..)
AFAIK sending the _wire->select(deviceAddress); is needed even with one sensor, otherwise another 5.4 millis might be won. (** in code above)As said before not tested, no guarantees.