Measuring temperatures with TMP03/04 (Part 8)

Part 12345, 6, 7, 8

While I was struggling for improving a combination of a bunch of PlainXXX libraries for building a state of the art temperature controller + its human interface, I revisited the code of PlainTMP with the objective of getting rid of the the standard timing functions, and then getting rid of any timer at all.The reason behind this strange specification was to avoid any interrupt conflicts with other codes. And well, in fact, the job is easy. Apart from their ease of use, lack of need for additional components, TMP03/04 sensors are ratiometric. Which means that as long as you can accurately count the high and low states duration from the generated pulse you can read a temperature. I applied a brute, rudimentary but pretty efficient timing mechanism which is reproduced below:

for (uint8_t i = 0; i < _averages; i++) {
	while(true) { 
		neg = (~(*address) & _pinMask);
		if (neg) break;/* Break when signal goes low state */
		pos = (*address & _pinMask);
		highTicks += 1;
		_delay_us(4);
	}
	while(true) { 
		pos = (*address & _pinMask);
		if (pos) break; /* Break when signal goes high state */
		neg = (~(*address) & _pinMask);
		lowTicks += 1;
		_delay_us(4);
	}
}

As you can read, both high state and low state reading sequence are strictly equal, to the exception of the compared term. Both highTicks and lowTicks are unsigned 32 bits integers. Blah, 32 bits counters are sllllllow. Right, and so what ! We have “plenty” time to perform this type of operation. The use of such a trivial timer results in sampling frequency better than 1 MHz which we will see next is amply sufficient for what we have to do. The TMP03/04 data sheet reads:

Optimizing Counter Characteristics Counter resolution, clock rate, and the resultant temperature decode error that occurs using a counter scheme may be determined from the following calculations: 1. T1 is nominally 10 ms, and compared to T2 is relatively insensitive to temperature changes. A useful worst-case assumption is that T1 will never exceed 12 ms over the specified temperature range.

 

T1 max = 12 ms

 

Substituting this value for T1 in the formula, temperature (°C) = 235 – ([T1/T2] × 400), yields a maximum value of T2 of 44 ms at 125°C. Rearranging the formula allows the maximum value of T2 to be calculated at any maximum operating temperature:

 

T2 (Temp) = (T1max × 400)/(235 – Temp) in seconds 

 

2. We now need to calculate the maximum clock frequency we can apply to the gated counter so it will not overflow during T2 time measurement. The maximum frequency is calculated using: Frequency (max) = Counter Size/ (T2 at maximum temperature) 

 

Substituting in the equation using a 12-bit counter gives,

 

Fmax = 4096/44 ms  94 kHz.

 

3. Now we can calculate the temperature resolution, or quantization error, provided by the counter at the chosen clock frequency and  temperature of interest. Again, using a 12-bit counter being clocked at 90 kHz (to allow for ~5% temperature over-range), the temperature resolution at 25°C is calculated from:

 

Quantization Error ( °C) = 400 × ([Count1/Count2] –[Count1 – 1]/[Count2 + 1]) Quantization Error ( °F) = 720 × ([Count1/Count2] –[Count1 – 1]/[Count2 + 1])

 

where, Count1 = T1max × Frequency, and Count2 =T2 (Temp) × Frequency. At 25°C this gives a resolution of better than 0.3°C. Note that the temperature resolution calculated from these equations improves as temperature increases. Higher temperature resolution will be obtained by employing larger counters as shown in Table I. The internal quantization error of the TMP03 sets a theoretical minimum resolution of approximately 0.1°C at 25°C.

 

The counting process from the reworked PlainTMP allows a time resolution better than 1 µS, thus a sampling frequency in excess of 1 MHz. This translates in an ultimate quantization error of less than 0.025 °C. This resolution can be improved by oversampling the signal resulting in extended counts and thus lowered quantization errors. A rule of the thumb states that one bit of resolution is gained for each x4 oversampling.

 

The new PlainTMP library has a slightly different acquisition mechanism compared to the previous one. Only one synchronizing sequence precedes the real counting sequence. The risk is low that the sensor will suddenly fail to send pulses just after synchronization, and the gain in time is really interesting (we now halve the sampling time). Here is the synchronization part of the code, plain easy:

volatile uint8_t *address = &(*(_port - 2));
while(true) {
	neg = (~(*address) & _pinMask);
	if (neg) break; /* Break when signal goes low state */
	pos = (*address & _pinMask);
	ticks += 1;
	if (ticks > _timeOutTicks) return(TMP_ERR_TIMEOUT);
}
while(true) { 
	pos = (*address & _pinMask);
	if (pos) break; /* Break when signal goes high state */
	neg = (~(*address) & _pinMask);
	ticks += 1;
	if (ticks > _timeOutTicks) return(TMP_ERR_TIMEOUT);
}

Also, I decided to harmonize the behavior of most PlainXXX libraries, including their initialization part. Thus the new InitializeTMP command and the simplified Temperature() function. Here is an overview of the PlainTMP public functions, as per the header file content:

void InitializeTMP(uint8_t sensorModel, volatile uint8_t *port, uint8_t pin, uint8_t unit);
void InitializeTMP(uint8_t sensorModel, volatile uint8_t *port, uint8_t pin, uint8_t unit, uint8_t averages);
void InitializeTMP(uint8_t sensorModel, volatile uint8_t *port, uint8_t pin, uint8_t unit, uint8_t averages, float gain, float offset);
void InitializeTMP(uint8_t sensorModel, volatile uint8_t *port, uint8_t pin, uint8_t unit, uint8_t averages, float gain, float offset, uint32_t timeout);
float Temperature();

 

The library comes with easy examples of use for each of the TMP0x family sensors.

Enjoy !

2 Comments

  1. LeandroM says:

    All the improvements seem really exciting!! although the syncro part isn’t quite understandable for me because my ports and bit operation knowledge is very little if at all existing… 😀
    I wish I had something to apply these to… maybe some sound producing with temperature for a latter project!…

    hey, a misspell:
    “A rule of the thumb sates (STATES) that one bit of resolution is gained for each x4 oversampling.”

    And so, are the libraries up for sharing now?
    You have seen my mails with my info and etc, haven’t you?
    nice post, good day!

    • Didier says:

      Hi Leandro,

      Thanks for the careful review. Typo corrected. I plan to release the libraries to those who ask in the next days, after making sure that the combination of all libraries involved in the next posts (MicroHEATER, PlainPID) are all fully compatible (You are on my list of recipients !)

Leave a Reply

You must be logged in to post a comment.