Add Serial Output to Harbor Freight IR Thermometers

Bartimaeus

10 W
Joined
May 31, 2012
Messages
94
This hack will allow you to interface with the cheap Harbor Freight pocket infared (IR) thermometers (specifically Item#93983 and Item#93984). This may or may not work with other IR temp guns (I read that the more expensive ones use proprietary methods), but it will definitely not work for the Harbor Freight #96451 pistol grip style gun. There is a way to do that, but the protocol (rs-232) is different from the one discussed here. For details about the other temp gun see the following link: http://www.exisle.net/mb/index.php?/topic/66532-fun-with-cen-tech-ir-thermometers/

This will allow you to use your cheap IR thermometer as a sensor for a microcontroller or to add a datalogging functionality that you don't normally see except for in high end models.

Lately I've been working with the Melexis MLX90614ESF-BAA infared temperature sensor to monitor the temperature of outrunner motors and to control a liquid cooling system. I had one of the Harbor Freight thermometers and decided to pop it open. I was pleased to find that there were clear tabs for interfacing with the device:
file.php


Front side for reference:
file.php


On the front you can see "TN105 ver 007", which led to this product page for ZyTemp, who appears to relabel these for other brands and sell them: http://www.zytemp.com/products/tn105c.asp

More digging led me to this blog of a teardown for another harbor freight model with the same pinout: http://dbearsblog.blogspot.com/2011/04/harbor-freight-infrared-thermometer.html

From there I learned that the pin assignments were:
V= Vdd
G = GND
D = Data (serial)
C = Clock (for data)
A = Action Pin (pull to GND to take a measurement. Shorting to ground will make it do continuous measurements)

Interfacing with the pads is convenient because the spacing is perfect for standard 0.1" header pins, and it only takes a little filing on the plastic case to make room for the pins to stick out. Alternately there are four holes in the case under the battery that were used for testing that you could run wires through if you didn't want to hack the case.
file.php


Unfortunately the blog post ends before it gets too useful, but while researching that model I came across some instructables that use them with an Arduino: http://www.instructables.com/id/Build-an-Arduino-based-thermal-scanner/
http://www.instructables.com/id/Closing-the-Loop-on-Surface-Mount-Soldering/

I downloaded the code from the first instructable and modified it to spit out the temperature in degrees Celcius and Fahrenheit
Code:
//baseline of this code was from http://dorkbotpdx.org/blog/scott_d/inexpensive_ir_based_temperature_sensor_for_microprocessors
//Modified by David_G and Bartimaeus

#define IR_CLK 2 //this is interrupt driven, pin 2 or 3
#define IR_DATA 12 //data pin

volatile int nbits = 0;
volatile byte hexbyte = 0;

volatile unsigned char message[4];
volatile int nbytes = 0;
volatile int message_waiting = 0;

unsigned long last_time = 0;

float temp= 99.00;
float ambient;
boolean light = false;

int irSetup = 1;

float latestReading = 0.0;


void setupTempSensor() {
  pinMode(IR_CLK, INPUT);
  pinMode(IR_DATA, INPUT);
  pinMode(13, OUTPUT); 
  attachInterrupt(0, readBit, FALLING); //0 -> pin2, 1 -> pin3
}  

/*
//attempt to filter out beginning false readings. Works fairly well but still has a bug or two
int isStartup(){
  if(irSetup){
    if((int)temp != 99){
      irSetup = 0;  
    }
  }
  return irSetup;
}
*/

void temp_output() {
   //updateTempSensor();
   float tmp = getFreshTemp(); //gets the temperature reading
   //float tmp = getFeshAmb(); //gets the ambient temperature  
   //if(!(isStartup())){    //filters out the bad data at the beginning
     float fahrenheit = (tmp*1.8) + 32;
     Serial.print(tmp);
     Serial.print(" C");
     Serial.print('\t');
     Serial.print(fahrenheit);
     Serial.println(" F");
   //}
 
   /*
      //debug information for cmdline 
       Serial.print("DD: "); 
       Serial.print(message[0]);
       Serial.print(message[1]);         
       Serial.print(message[2]); 
       Serial.print(" H:");
       Serial.print(hexbyte);
       Serial.println(';');
   */
 
}

void updateTempSensor() {
  if (message_waiting == 1) {
    last_time = millis();
    if (message[0] == 0x4c) { //from zytemp
      int t = message[1]<<8 | message[2];
      temp = t/16.0 -273.15;
    } 
    else if (message[0] == 0x66) {
      int t = message[1]<<8 | message[2];
      ambient = t/16.0 -273.15;
    }
    message_waiting = 0;
  }

  //update evry second
  if (millis() - last_time > 1000) {
    nbits = 0;
    nbytes = 0;
    hexbyte = 0;
    message_waiting = 0;
    last_time = millis();
  }
  
}

// Interupt routine for handling IR sensor clock trailing edge
void readBit() {
  int val = digitalRead(IR_DATA);  //read the data from the IR module
  if(!light) digitalWrite(13, HIGH);   // set the LED on
  else digitalWrite(13, LOW);
  light = !light;  //change light state when a bit was read in
  nbits++;
  int bit = (val == HIGH) ? 1 : 0; 
  hexbyte = (hexbyte << 1) | bit; //compound bytes so that we creat a 8-bit key
  if (nbits == 8) { 
    if (hexbyte == 0xd) {
      nbytes = 0;
      message_waiting = 1;
    } 
    else if (message_waiting == 0) {
      if (nbytes < 4) {
        message[nbytes] = hexbyte;
      }
      nbytes++;
    }
    hexbyte = 0;
    nbits = 0;
  }
}

float getFreshTemp() { 
  return temp;
}

float getFeshAmb() {
   return ambient; 
}

void setup() {
   Serial.begin(9600);
   setupTempSensor(); //start temperature
}

void loop() {
  updateTempSensor();  //allwas update the temp sensor each cycle
  temp_output();
  delay(100);
    
}
You can copy and paste into a blank Arduino sketch or download the file here: View attachment HarborFreightIRTempGun.zip

Wiring:
[Note: You should remove the battery from the thermometer before you power it from the Arduino]
To wire the IR thermometer to the Arduino, attach the pins as follows:
V to 3.3v on the Arduino
G to GND on the Arduino
A to GND on the Arduino
D to digital input 12 on the Arduino (or other digital input pin. Make sure to modify code to match if you do)
C to digital input 2 on the Arduino (or other interrupt pin. Make sure to modify code to match if you do)

file.php


Final Setup:
If you don't have the Arduino program installed you should be able to get it here: http://arduino.cc/en/main/software
Upload the sketch to the Arduino and open up a serial terminal (if you've never used one before you can find a basic one in the Arduino program under Tools->Serial Monitor)

The output will look something like this:
file.php


You can use this to take log temperature data and enter it into Microsoft Excel to make a graph, or parse the data in the Arduino to use for your microcontroller project. If you want to change the formatting of the output(make is comma seperated values, show only celcius, etc.) you should modify the temp_output() function. Any Arduino should work, although if you are new to Arduino I would highly recommend getting the Arduino Uno r3. The IR temp sensor I mentioned at the beginning costs ~$10-12 from Digikey by itself, so depending on your needs a ~$13 Ir thermometer with a built in display might be a lot more economical.

I hope you found this educational and interesting, and I am more than willing to help with any problems that you post below and I'd love to hear any success stories as well!
 

Attachments

  • 2013-04-05121301_zps50ea979f.jpg
    2013-04-05121301_zps50ea979f.jpg
    100.5 KB · Views: 2,158
  • 2013-04-05134707_zpsbb95a1c0.jpg
    2013-04-05134707_zpsbb95a1c0.jpg
    138.1 KB · Views: 2,158
  • 2013-04-05174725_zps1f504745.jpg
    2013-04-05174725_zps1f504745.jpg
    121.6 KB · Views: 2,158
  • Serial IR Temp Output.jpeg
    Serial IR Temp Output.jpeg
    19.6 KB · Views: 5,726
Thanks for posting, I thought the ir unit could be hacked. Had mine apart last year, but never found time to play with it.
 
Hi,

i am using a Zytemp TN168
(http://www.zytemp.com/products/tn168.asp). As shown on the Picture i connected it to a Mega 2560 Arduino Board. i used this new libs:

https://github.com/freetronics/IRTemp

to read out the 3 data pins.

At the first time everything works fine.I uploaded this code:

Code:
/*

    File: readTemperature.ino
    Version: 1.0
    Author: Andy Gelme (@geekscape)
    License: GPLv3 *
    For more information see www.freetronics.com/irtemp *
    IRTemp library uses an Arduino interrupt:
    If PIN_CLOCK = 2, then Arduino interrupt 0 is used
    If PIN_CLOCK = 3, then Arduino interrupt 1 is used */

#include "IRTemp.h"

static const byte PIN_DATA = 2;
static const byte PIN_CLOCK = 3; // Must be either pin 2 or pin 3
static const byte PIN_ACQUIRE = 4;

static const TempUnit SCALE=CELSIUS; // Options are CELSIUS, FAHRENHEIT

IRTemp irTemp(PIN_ACQUIRE, PIN_CLOCK, PIN_DATA);

void setup(void) {
Serial.begin(9600);
Serial.println("IRTemp example");
Serial.println("~~~~~~~~~~~~~~");
}

void loop(void) {
float irTemperature = irTemp.getIRTemperature(SCALE);
printTemperature("IR", irTemperature);

float ambientTemperature = irTemp.getAmbientTemperature(SCALE);
printTemperature("Ambient", ambientTemperature);

delay(1000);
}

void printTemperature(
char *type,
float temperature) {

Serial.print(type);
Serial.print(" temperature: ");

if (isnan(temperature)) {
Serial.println("Failed");
}
else {
Serial.print(temperature);
Serial.println(SCALE == FAHRENHEIT ? " F" : " C");
}
}

After this i get good values from the sensor.

But if i disconnect the Board from the USB i always get FAILURE.
The only way to repair it is, to change all pins for example to 7,8,9 than i upload the data and the Controller is working. but if i disconnect USB i get the same problem.
If i only reset the Board. There is no Problem. Only the Power Up makes this problem.
Here is a picture of my Wiring:

http://picpaste.com/Foto-navNvrWt.JPG

Please help me.

cu kami
 
Back
Top