Measuring temperatures with TMP03/04 (Part 2)

Part 12345, 6, 7, 8

Now that we know how the TMP03/04 sensor works, let’s try to run it with Arduino. My first intuition drove me to write some code which would use interrupts (attachInterrupt() function). The first tests were alright, but I very quiclky tried to add some protections e.g. broken data link to the sensor. Arduino may wait and wait and wait for ages a rising (or falling) edge from the sensor. So that I inserted a time out… which did not work! Probably because of the note that I skipped in the reference material:

Note

Inside the attached function, delay() won’t work and the value returned by millis() will not increment. Serial data received while in the function may be lost.

In addition, using the attachInterrupt() function the basic way prevents from using more than two inputs, which is poor. In spite of its rough look and feel, the second idea is to use a routine in which level changes are monitored by while() instructions.

// Get actual temperature; temperature is expressed in milli Kelvins (unsigned integer value)
long temperature(int selectedChannel){
  statusLed(on);
  long timeOut = (micros()+50000); // 50 ms
  byte signalPinMask = (1< timeOut) break;
  }
  while (~PINB & signalPinMask) { // Wait for high state on signal pin
   if (micros() > timeOut) break;
  }
  long T1Start = micros();  // T1 starts now
  while (PINB & signalPinMask) { // While T1 is on
    if (micros() > timeOut) break;
  }
  long T2Start = micros();
  long T1Duration = (T2Start - T1Start);
  while (~PINB & signalPinMask) { // While T2 is on
    if (micros() > timeOut) break;
  }
  long result;
  if (micros() > timeOut) {
    errorCode = ERR_MIS_SIGNAL; // Set global variable error code
    result = 0;
  }
  else {
    long T2Duration = micros() - T2Start;
    errorCode = ERR_NONE; // Set global variable error code
    result = 508150 - long((400000.00F * T1Duration) / T2Duration);
  }
  statusLed(off);
  return (result);
}

In this example, PORTB0:4 can be used. errorCode is a global variable which can be interpreted in order to prevent false readings. statusLed() is a simple routine which turns a status led on and off in order to monitor the activity of the interface.

For those we are not familiar with bits masking, please read this

Using the “while level has not changed check elapsed time” takes 4 µs, which results in a 200 kHz fequency. Based on the table from TMP03/04 specifications, the quantization error at 25°C is around 0.1°C, which is far sufficient in most custom applications.

Next post on same subject

Leave a Reply

You must be logged in to post a comment.