Wiring Temperature Sensor ?

I need some help connecting this sensor (SPI):
to the MEGA2560 .

I added a picture with the wiring down below, if you cant see it clearly it goes:
V: Vdd to 5V
D: Data (Serial Data) to Digital 2
C: Clock (Serial Clock) to Digital 3
A: Action Pin to Digital 4

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 = 3;			                      // Pins
const int dataPin = 2;
const int actionPin = 4;

void setup(){
  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
  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 = ");
    irFlag = false;					// Reset flags
    ambFlag = false;
    Serial.print(", ");
    Serial.println(millis());                           // Print time for logging purposes
    delay(500);					     // 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
    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


I can see a few issues:

First, the manual says you should pull the Action pin low to get readings, and leave it floating otherwise. But you are driving it high. This might work, or it might damage the sensor.

Second, you are setting the pinMode of the Action pin before setting the Action pin high. So it will go low briefly, and the device will probably start sending data. It sounds from the datasheet that when the action pin becomes floating, the device carries on sending data until a full 5 byte packet has been sent.

Third, when you set the action pin high (and should really set it to floating), the clock and data pins will go hi-Z and you may pick up spurious data.

Fourth, if you get out of sync with the device (i.e. you start receiving in the middle of a message), you will not get back in sync because you have not allowed for being out of sync in the code.

I suggest the following:

  1. Write LOW to the action pin at the start of setup (or rely on it being low in the first place). When you want to pull the action pin low, change its pin mode to output. When you want to set it floating, set the pin mode back to input. This covers the first two issues.

  2. Set the pin mode of the clock and data pins to INPUT_PULLUP. This covers the third issue.

  3. Whenever you have received 5 bytes but the packet does not start with one of the expected opcodes or does not end with CR, begin error recovery:

  • set the Action pin floating
  • wait for long enough for the sensor to stop transmitting (i.e. at least 40 bit times @ 2kbps), or until no more clock pulses are received
  • set pos to 0
  • clear the state flags
  • set the Action pin low to start again

Thank you for your answer!

As it turns out it worked for me via installing the IR-Temp Library that also comes with an example. While the wiring is correct and stays the same , this time i get to the point where the TX is actually blinking and im getting the IR temperature returned on the serial monitor. I was confused at the beginning since the TN9 sensor is SPI based and thought i had to connect it to the respective SPI pins of the MEGA2560. But the digital pins worked for me.

Source: https://github.com/freetronics/IRTemp