How to read an SMT 160-30, improved ?


As shown in How to read an SMT 160-30 to get the duty cycle the data output of the sensor has to be read very frequently.
In this example, the data output of the sensor was connected to pin A0 which can be read by PINC & 1.

Actually, 50 per cent of the time are spent by the loop control (increment the loop counter and test if finished).
You can remove those steps by repeating the input command in the code:

j = j + (PINC & 1);
j = j + (PINC & 1);
j = j + (PINC & 1);
...

If "j" is a byte variable you should not repeat this command more than 255 times otherwise you get an overflow which will be ignored.

Reading just 255 times will not be enough, so you have to nest this sequence in another loop. As this one is performed much less frequently you simply can ignore its overhead. At the very end you have the high count. Divide it by the total number of readings to get the duty cycle.

float readSMT160_30() {
  long c = 0;
  cli();
  for (long i = 0; i < i1; i++) {
    byte j = 0;       // j must not overflow
    j = j + (PINC & 1);
    j = j + (PINC & 1);
    j = j + (PINC & 1);
    ...                 // repeated 255 times
    j = j + (PINC & 1);
    j = j + (PINC & 1);
    j = j + (PINC & 1);
    c = c + j;
  }
  sei();
  // duty cycle = 0.320 + 0.00470 * t
  float dc = c / counts;
  return (dc - 0.32) / 0.0047;
}

It is recommended to move the j = j + (PINC & 1); to an external #include file.

Further improvements

The version above starts immediately and records a given number of samples. According to the data sheet you should better start and stop at the falling edge of the data pin. This is done in the following version.
The falling edge is detected by the conjunction of the previous sample and the inverted actual sample. To reduce the noise a certain number of intervalls is recorded and evaluated.

float readSMT160_30() {
  long count = 0;
  long total = 0;
  long eins  = 1;
  const long nMax = 10000;
  // wait for 1
  while (SAMPLE == 0);
  // wait for 0
  while (SAMPLE == 1);
  cli();
  byte alt = SAMPLE;
  for (long n = 0; n < nMax; ) {
    byte neu = SAMPLE;
    count = count + neu;
    total = total + eins;
    byte falling = alt & (neu ^ 1);
    n = n + falling; // counts the falling edges
    alt = neu;
  }
  sei();
  // duty cycle = 0.320 + 0.00470 * t
  float dc = (float)count / total;
  return (dc - 0.32) / 0.0047;
}

In this graph the temperature is rising from 25.3° to 25.36 °. The correlation coefficient is 0.9871.

Heat Radiation

Placing a glass of hot tea next to the temperature sensor at a distance of about one centimeter:

and logging the data, I got these results:




contact: nji(at)gmx.de