Reading Temperature with AD595AQ

I would like to make a simple (the emphasis is on simple)temperature indicator using a Arduino Diecimila 328, protype shield, K-type thermocouple and an AD595AQ amplifier.

The data sheet for the 595 makes sense to me and I don't think I will have any problems wiring it up on the prototype shield.

But the software is the problem. :-[

I would like to see the temperature in the “serial port monitor” window of the environment. I would like to see the temperature printed on the computer screen every minute.

Is there anyone who knows where I can download such software that is well documented so that I can learn?

This is a very easy job for an Arduino. It is nice you have a 328 but a 168 could easily do the job as well.
Here’s a simple sketch I wrote that is the start of a differential temperature controller:
I implemented a lookup table using an array based on the AD595 datasheet values and do a linear interpolation between the points - there’s lots of other ways to do it.

You’ll just need to change up the main loop. Use the millis() function and fire off your Serial.print statements after 60101000 = 600000 milliseconds have elapsed, that’s what long integers are for!

BTW lcd.print(223) will give you a degree character on your display.

Have fun.

/* AD595 thermocouple temperature display */
#include <LCD4Bit_mod.h>

LCD4Bit_mod lcd = LCD4Bit_mod(2); // 2 lines on the display

#define AD595_PIN 1  // analog pin 1
//Function for Temp(C) depending on Voltage (milliamp)
#define SIZE_FTV_TBL 32
int ftv[32][2] = {
  {-20,-189},
  {-10,-94},
  {0,3},
  {10,101},
  {20,200},
  {25,250},
  {30,300},
  {40,401},
  {50,503},
  {60,605},
  {80,810},
  {100,1015},
  {120,1219},
  {140,1420},
  {160,1620},
  {180,1817},
  {200,2015},
  {220,2213},
  {240,2413},
  {260,2614},
  {280,2817},
  {300,3022},
  {320,3227},
  {340,3434},
  {360,3641},
  {380,3849},
  {400,4057},
  {420,4266},
  {440,4476},
  {460,4686},
  {480,4896},
  {500,5107}
  };
  
float tCel;

void CelsiusToFarenheit(float const tCel, float &tFar)
{
  tFar = tCel * 1.8 + 32;
}

void readThermocouple(float &tCel)
{
  byte thermoADval = analogRead(AD595_PIN); 
  int mV = (thermoADval/1023.0) * 5000;
//  Serial.print("mV = ");
//  Serial.print(mV,DEC);
  int i=1;
  int C1=0;
  int C2=0;
  int V1,V2;
  for( i=1; (i<32) && C2==0; i++)
  {
    if (ftv[i][1]>mV)
    {
      C2 = ftv[i][0];
      C1 = ftv[i-1][0];
      V1 = ftv[i-1][1];
      V2 = ftv[i][1];
    }
  }
//  Serial.print(", ");
  if (i==SIZE_FTV_TBL)
    tCel = 9999;
  else
  {
    tCel = float(mV-V1)/(V2-V1);
    tCel = tCel * (C2-C1) + C1;
  }
}

void displayTemp()
{
  float tFar;
  CelsiusToFarenheit(tCel,tFar);  
  lcd.clear();
  lcd.cursorTo(1,0);
  lcd.printIn("TCouple=");
  char buf[6];
  itoa(int(tCel),buf,10);
  lcd.printIn(buf);
  lcd.print('C');
  lcd.print('/');
  itoa(int(tFar),buf,10);
  lcd.printIn(buf);
  lcd.print('F');
  
  Serial.print("Temp: ");
  Serial.print(tCel,DEC);
  Serial.print("C, ");
  Serial.print(tFar,DEC);
  Serial.println('F');
}
  
void setup()
{
  Serial.begin(57600);
  pinMode(22, OUTPUT);
  lcd.init();
  lcd.clear();
  delay(10);
}

boolean pump_on = false;
boolean status_change = true;
void loop()
{
  readThermocouple(tCel);
  displayTemp();
  if (tCel>30)
  {  lcd.cursorTo(2,0);
    lcd.printIn("PUMP ON");
    status_change = !pump_on;
    pump_on = true;
  }
  else
  {
    status_change = pump_on;
    pump_on = false;
  }
  if (status_change)
    digitalWrite(22,pump_on);
  delay(1000);
}

Ooops, I gave the formula for a 10 minute interval! Just 60000 millis for one minute!

Emdee, Thank you very much. After a quick look I believe I can understand this program. This is great! :slight_smile:

Am I correct in saying this program prints to an LCD screen and not the computer? I do not have an LCD display. I guess this is a good reason I should get one. :slight_smile:

Jim,
Yes this program prints to an LCD, as well as outputting to the serial port.
Just delete the extra LCD stuff from the displayTemp() function, and any other lcd calls in setup() and main().

The LCD shield from nuelectronics is a nice choice because of the buttons that also provide user input.

In case you haven't figured it out yet, Serial.print() statements are your best friend in the Arduino world. Feel free to sprinkle your code with them so that you can see what's going on in the serial monitor window while it executes. This is called instrumenting your code. Once you have everything debugged you can get rid of all the extra Serial.print() statements. I would call this standard operating procedure.

BTW: I have switched over to using the MAX6675 thermocouple chip, which is slightly cheaper, and in in my opinion, easier to implement as long as you aren't intimidated by the SOIC form factor. Another forum member, Ryan, has made a nice library for using this. The MAX6675 uses SPI to digitally transmit the temperature to the ATMEL CPU, so the software doesn't have to calculate the temperature based on voltage levels.