Add Serial Output to Harbor Freight IR Thermometers


10 W
May 31, 2012
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:

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:

Front side for reference:

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:

More digging led me to this blog of a teardown for another harbor freight model with the same pinout:

From there I learned that the pin assignments were:
V= Vdd
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.

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:

I downloaded the code from the first instructable and modified it to spit out the temperature in degrees Celcius and Fahrenheit
//baseline of this code was from
//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((int)temp != 99){
      irSetup = 0;  
  return irSetup;

void temp_output() {
   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(" C");
     Serial.println(" F");
      //debug information for cmdline 
       Serial.print("DD: "); 
       Serial.print(" H:");

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
  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;
    hexbyte = 0;
    nbits = 0;

float getFreshTemp() { 
  return temp;

float getFeshAmb() {
   return ambient; 

void setup() {
   setupTempSensor(); //start temperature

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

[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)


Final Setup:
If you don't have the Arduino program installed you should be able to get it here:
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:

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!


  • 2013-04-05121301_zps50ea979f.jpg
    100.5 KB · Views: 2,158
  • 2013-04-05134707_zpsbb95a1c0.jpg
    138.1 KB · Views: 2,158
  • 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.

i am using a Zytemp TN168
( As shown on the Picture i connected it to a Mega 2560 Arduino Board. i used this new libs:

to read out the 3 data pins.

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


    File: readTemperature.ino
    Version: 1.0
    Author: Andy Gelme (@geekscape)
    License: GPLv3 *
    For more information see *
    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


void setup(void) {
Serial.println("IRTemp example");

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

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


void printTemperature(
char *type,
float temperature) {

Serial.print(" temperature: ");

if (isnan(temperature)) {
else {
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:

Please help me.

cu kami