Close

Reading the thermometer with an Arduino

A project log for DIY Thermal Camera

A $50 thermal camera using a non-contact thermometer, 2 servos, and an Arduino

Michael ShaubMichael Shaub 03/26/2017 at 15:000 Comments

According to this Instructable the thermometer's pins should connect to an Arduino like this:

Here's the sample code I tried first to get some measurements streaming in:

byte n = 0;                            // Interrupt Bit Count        
volatile byte pos = 0;            // Values Position Count
volatile byte values[5] = {
  0,0,0,0,0};                                                   // Values to be stored by sensor
byte cbit = 0;                    // Current bit read in

boolean irFlag = false;           // Flag to indicate IR reading has been made
boolean ambFlag = false;          // Flag to indicate ambient temp reading has been made


byte irValues[5] = {
  0,0,0,0,0};                                      // Variable to store IR readings
byte ambValues[5] = {
  0,0,0,0,0};                                           // Variable to store Ambient readings

const int len = 5;                        // Length of values array
const int clkPin = 2;                           // Pins
const int dataPin = 12;
const int actionPin = 5;

void setup(){
  Serial.begin(9600);           

  pinMode(clkPin, INPUT);         // Initialize pins
  pinMode(dataPin, INPUT);
  pinMode(actionPin, OUTPUT);
  digitalWrite(clkPin, HIGH);
  digitalWrite(dataPin, HIGH);
  digitalWrite(actionPin, HIGH);

  Serial.println("Type to Start...");                   // Wait for input to start
  while(!Serial.available());
  Serial.println("Starting...");
  Serial.println("IR (C), Ambient (C), Time Since Start (ms)");

  attachInterrupt(1,tn9Data,FALLING);             // Interrupt
  digitalWrite(actionPin,LOW);          // Make sensor start sending data
}

void loop(){



  if(pos == len && values[0] == 0x4C){            // If sensor has sent IR packet...
    for(int i = 0; i < len; i++){                     // Store values to irValues
      irValues[i] = values[i];
    }
    irFlag = true;                               // Indicate IR reading
    pos = 0;
    digitalWrite(actionPin,LOW);             // Make sensor start sending data
  }

  if(pos == len && values[0] == 0x66){          // If sensor has sent ambient packet...
    for(int i = 0; i < len; i++){                   // Store values to ambValues
      ambValues[i] = values[i];
    }
    ambFlag = true;                     // Indicate Ambient reading
    pos = 0;
    digitalWrite(actionPin,LOW);           // Make sensor start sending data    
  }

  if(pos == len && values[0] == 0x53){         // If sensor has sent junk packet
    pos = 0;
    digitalWrite(actionPin,LOW);          // Make sensor start sending data   
  }

  if(irFlag && ambFlag){        // If successful IR and Ambient reading...
    digitalWrite(actionPin,HIGH);   // Make sensor stop sending data.  Because Timing is weird, I want to ensure the interrupts do not happen during this section.   
    word tempword = 0;        // Next 4 lines isolate temperature component of values
    tempword = tempword | irValues[1];
    tempword = tempword << 8;
    tempword = tempword | irValues[2];
    if(tn9Check(irValues)){       // If checksum is valid, print IR temperature
      //Serial.print("IR = ");
      Serial.print(int(tempword)/16.0 - 273.15);
      Serial.print(", ");       
    }
    else{                 // If checksum isn't valid, print impossible temp
      //Serial.print("IR = ");
      Serial.print("-273.15, "); 
    }

    tempword = 0;         // Isolate temperature component again for ambient
    tempword = tempword | ambValues[1];
    tempword = tempword << 8;
    tempword = tempword | ambValues[2];
    if(tn9Check(ambValues)){        // If checksum is valid, print ambient temperature
      //Serial.print("Amb = ");
      Serial.print(int(tempword)/16.0 - 273.15);        
    }
    else{           // If checksum isn't valid, print impossible temp
      //Serial.print("Amb = ");
      Serial.print("-273.15"); 
    }
    irFlag = false;         // Reset flags
    ambFlag = false;
    
    Serial.print(", ");
    Serial.println(millis());                           // Print time for logging purposes
    delay(2000);               // Simulate other sensors or code
    digitalWrite(actionPin,LOW);               // Make sensor start sending data  
}                     


}


void tn9Data(){           // Interrupt Function
  cbit =  digitalRead(dataPin);     // Read bit
  if(pos >= len) pos = 0;               // Keep index below 5
  values[pos] = (values[pos] << 1) | cbit;          // Store to values
  n++;              // Increment bit count
  if(n == 8){           // Increment position count based on bits read in
    pos++;
    n = 0; 
  }
  if(pos == len){           // If complete "packet" sent, stop sensor from sending 
    digitalWrite(actionPin,HIGH);     // again until main loop allows it.
  }
}


boolean tn9Check(byte tn9Values[]){     // Checksum calculating function
  int mcheck = (int)tn9Values[0] + (int)tn9Values[1] + (int)tn9Values[2]; // Checksum calculation
  int scheck = (int)tn9Values[3];            // Checksum sent by sensor
  boolean crc = false;            // Initialize return value
  if(mcheck > 510) mcheck = mcheck - 512;         // Handle sensor byte rollover
  if(mcheck > 255) mcheck = mcheck - 256;         // Handle sensor byte rollover
  if(mcheck == scheck) crc = true;      // Check checksum
  return(crc);            // Return
}

Discussions