Reading Temperature from TMP03

The TMP03 is a temperature sensor with an open-collector output. I need to make a free running count when the output is high, continue with a new count when the input is low and then calculate temperature with this function:

Tf = 455.0 - (720.0 * t_hi / t_lo);

I have used many of these with PIC micros and the Arduino and I get very stable temperatures. I am trying to measure the temps in the IMP using the following but I get ± 10 degrees on my reading. t_hi and t_lo are fairly large numbers since they are read using the micros() counter. I do see variations in the t_hi and t_lo variables if I monitor those.
`
function readTemp(ch) {
// read the TMP03 by waiting for high then low then reading high and counting up then read low counting up and calculate F.
local t_hi = 0;
local t_lo = 0;
local t_beg = 0;
local t_beg2 = 0;
local tout = 0;
local tflt = 0.0;
if (ch == 1){
while(hardware.pin2.read()){//in case no sensor is connected
tout++;
//delay_ms(1);
if (tout > 200) {
server.log(tout);
return 1;
}

}
tout = 0;
while(!hardware.pin2.read()){//wait for fresh pulse high
}    
t_beg = hardware.micros();
while(hardware.pin2.read()){
}
t_hi = hardware.micros();
while(!hardware.pin2.read()){
}
t_lo = hardware.micros();
t_lo = t_lo - t_hi;
t_hi = t_hi - t_beg;
return 455.0 - (720.0 * t_hi / t_lo);
}

}
`

I am not sure why the underline is not showing up for the t_lo = and t_hi = lines…

Is polling a pin too inaccurate due to interrupts or other things happening skewing the result?

Since Squirrel is an interpreted language, accessing hardware takes a bit more time than in a compiled language (like c).

Is there a reason you’re polling the pin, rather than the digital_in callback?

Take a look at this snippet of code, and see if it can be of use:

`/***********************************************

  • Reads a pulse (either HIGH or LOW) on a pin.

  • If the pulseValue is HIGH, the object will start

  • timing when the pin goes HIGH, then waits for

  • the pin to go LOW, and executes the callback

  • (callback expects a function with one parameter,

  • the length of the pulse in microseconds).

  • The accuracy of this function has not been tested,

  • and will have some variance because of how callbacks

  • work.
    ***********************************************/
    class Pulse {
    pulsePin = null; // Pin to look for pulses on
    pulseValue = null; // 1 for HIGH -> LOW, 0 for LOW -> HIGH
    timer = null; // Time since start of pulse
    callback = null; // callback function when pulse finished

    constructor(_pulsePin, _inputType, _pulseValue, _callback) {
    this.pulsePin = _pulsePin;
    this.pulseValue = _pulseValue;
    this.timer = 0.0;
    this.callback = _callback;

     this.pulsePin.configure(_inputType, pinChanged.bindenv(this));
    

    }

    function pinChanged() {
    local p = pulsePin.read();
    if (p == pulseValue) {
    this.timer = hardware.micros();
    }
    else {
    this.timer = hardware.micros() - timer;
    this.callback(timer);
    }
    }
    }

function pulsed(microseconds)
{
server.log(“pulsed for " + microseconds + " microseconds”);
}

pulsePin1 <- Pulse(hardware.pin1, DIGITAL_IN_PULLDOWN, 1, pulsed);
imp.configure(“Pulse Example”, [], []);
server.log(“ready”);`

Here is a snippet of the output of that code.

Tue Jul 09 2013 22:08:56 GMT-0500 (Central Daylight Time): pulsed for 8008 microseconds
Tue Jul 09 2013 22:08:56 GMT-0500 (Central Daylight Time): pulsed for 11126 microseconds
Tue Jul 09 2013 22:08:56 GMT-0500 (Central Daylight Time): pulsed for 11185 microseconds
Tue Jul 09 2013 22:08:56 GMT-0500 (Central Daylight Time): pulsed for 11803 microseconds
Tue Jul 09 2013 22:08:56 GMT-0500 (Central Daylight Time): pulsed for 12592 microseconds
Tue Jul 09 2013 22:08:56 GMT-0500 (Central Daylight Time): pulsed for 8196 microseconds
Tue Jul 09 2013 22:08:56 GMT-0500 (Central Daylight Time): pulsed for 8210 microseconds
Tue Jul 09 2013 22:08:56 GMT-0500 (Central Daylight Time): pulsed for 8211 microseconds
Tue Jul 09 2013 22:08:56 GMT-0500 (Central Daylight Time): pulsed for 8210 microseconds
Tue Jul 09 2013 22:08:56 GMT-0500 (Central Daylight Time): pulsed for 12713 microseconds
Tue Jul 09 2013 22:08:56 GMT-0500 (Central Daylight Time): pulsed for 13422 microseconds
Tue Jul 09 2013 22:08:56 GMT-0500 (Central Daylight Time): pulsed for 8196 microseconds
Tue Jul 09 2013 22:08:56 GMT-0500 (Central Daylight Time): pulsed for 3032 microseconds
Tue Jul 09 2013 22:08:56 GMT-0500 (Central Daylight Time): pulsed for 8211 microseconds
Tue Jul 09 2013 22:08:56 GMT-0500 (Central Daylight Time): pulsed for 8202 microseconds
Tue Jul 09 2013 22:08:56 GMT-0500 (Central Daylight Time): pulsed for 8209 microseconds
Tue Jul 09 2013 22:08:56 GMT-0500 (Central Daylight Time): pulsed for 354927192 microseconds
Tue Jul 09 2013 22:08:57 GMT-0500 (Central Daylight Time): pulsed for 8210 microseconds
Tue Jul 09 2013 22:08:57 GMT-0500 (Central Daylight Time): pulsed for 13111 microseconds
Tue Jul 09 2013 22:08:57 GMT-0500 (Central Daylight Time): pulsed for 10273 microseconds
Tue Jul 09 2013 22:08:57 GMT-0500 (Central Daylight Time): pulsed for 8227 microseconds
Tue Jul 09 2013 22:08:57 GMT-0500 (Central Daylight Time): pulsed for 12493 microseconds
Tue Jul 09 2013 22:08:57 GMT-0500 (Central Daylight Time): pulsed for 8195 microseconds
Tue Jul 09 2013 22:08:57 GMT-0500 (Central Daylight Time): pulsed for 8211 microseconds
Tue Jul 09 2013 22:08:57 GMT-0500 (Central Daylight Time): pulsed for 11986 microseconds
Tue Jul 09 2013 22:08:57 GMT-0500 (Central Daylight Time): pulsed for 8206 microseconds
Tue Jul 09 2013 22:08:57 GMT-0500 (Central Daylight Time): pulsed for 10965 microseconds
Tue Jul 09 2013 22:08:57 GMT-0500 (Central Daylight Time): pulsed for 10884 microseconds
Tue Jul 09 2013 22:08:57 GMT-0500 (Central Daylight Time): pulsed for 8209 microseconds
Tue Jul 09 2013 22:08:57 GMT-0500 (Central Daylight Time): pulsed for 8695 microseconds
Tue Jul 09 2013 22:08:57 GMT-0500 (Central Daylight Time): pulsed for 8209 microseconds
Tue Jul 09 2013 22:08:57 GMT-0500 (Central Daylight Time): pulsed for 8229 microseconds
Tue Jul 09 2013 22:08:57 GMT-0500 (Central Daylight Time): pulsed for 11639 microseconds
Tue Jul 09 2013 22:08:57 GMT-0500 (Central Daylight Time): pulsed for 8210 microseconds
Tue Jul 09 2013 22:08:57 GMT-0500 (Central Daylight Time): pulsed for 8211 microseconds
Tue Jul 09 2013 22:08:57 GMT-0500 (Central Daylight Time): pulsed for 8204 microseconds
Tue Jul 09 2013 22:08:57 GMT-0500 (Central Daylight Time): pulsed for 8204 microseconds
Tue Jul 09 2013 22:08:57 GMT-0500 (Central Daylight Time): pulsed for 11124 microseconds
Tue Jul 09 2013 22:08:57 GMT-0500 (Central Daylight Time): pulsed for 8210 microseconds
Tue Jul 09 2013 22:08:57 GMT-0500 (Central Daylight Time): pulsed for 8576 microseconds
Tue Jul 09 2013 22:08:57 GMT-0500 (Central Daylight Time): pulsed for 12613 microseconds

The TMP03 outputs around 35hz and the proportion of high to low is how you calculate temperature.

Here is a snippet of output of my code but I still see enough variation in the pulse timing that I don’t get stable temperature readings.

Tue Jul 09 2013 22:12:04 GMT-0500 (Central Daylight Time): 541959462
Tue Jul 09 2013 22:12:04 GMT-0500 (Central Daylight Time): 541943797
Tue Jul 09 2013 22:12:04 GMT-0500 (Central Daylight Time): 15665
Tue Jul 09 2013 22:12:04 GMT-0500 (Central Daylight Time): 8145
Tue Jul 09 2013 22:12:04 GMT-0500 (Central Daylight Time): 80.6368
Tue Jul 09 2013 22:12:07 GMT-0500 (Central Daylight Time): 544978402
Tue Jul 09 2013 22:12:07 GMT-0500 (Central Daylight Time): 544962736
Tue Jul 09 2013 22:12:07 GMT-0500 (Central Daylight Time): 15666
Tue Jul 09 2013 22:12:07 GMT-0500 (Central Daylight Time): 8154
Tue Jul 09 2013 22:12:07 GMT-0500 (Central Daylight Time): 80.247
Tue Jul 09 2013 22:12:10 GMT-0500 (Central Daylight Time): 548021162
Tue Jul 09 2013 22:12:10 GMT-0500 (Central Daylight Time): 548005693
Tue Jul 09 2013 22:12:10 GMT-0500 (Central Daylight Time): 15469…t_hi
Tue Jul 09 2013 22:12:10 GMT-0500 (Central Daylight Time): 8348…t_lo
Tue Jul 09 2013 22:12:10 GMT-0500 (Central Daylight Time): 66.4448…Temp

I log micros, t_hi, t_lo and calculated temp

You might be better off using SPI to read this peripheral: at the imp’s minimum SPI data rate of 117.1875KHz, one TMP03 output waveform is about 8,000 bits or 1,000 bytes. Ignore the SPI MOSI and clock lines, read a 1,000-byte blob from the SPI MISO line, and see how long the runs of 1 bits and 0 bits in it are. That will give the T_hi and T_lo timings to the nearest 8.53us, which is a lot closer than you’ll get with a pin callback.

Depending on how much imp memory your application has available, you can increase the SPI frequency, and thus input blob size, and thus input resolution (in powers of 2). If you can spare an 8,000-byte blob, you could run SPI at 937.5KHz and be accurate to the nearest 1.07us.

Peter