Sunday, December 16, 2007

Temperature Measurements Simple But Hard



I decided to test my new "understand" by trying a "simple" project which would use what I learned of serial communication and Arduino and Processing programming.

Perseverance got me through. I did learn quite a bit and in the end it was rather simple, just about as simple as I imagined it to be, except for all the learning I had to go through.

All I wanted to do was wire up a AD595 "Monolithic Thermocouple Amplifiers with Cold Junction Compensation" (click this to checkout the datasheet, it is what I used to wire up the AD595)to take the 10mV/Deg Celsius output and read it with the Arduino analog input and send it to the PC over the USB serial connection. Then using Processing to convert that data into a real Celsius and Fahrenheit temperature output.

I had several problems, first the K type thermocouple was not working correctly, I substituted it with a second that did work and reassured me that the IC was working correctly. I finally decided to use the internal ability of the AD595 to measure temperatures, they call it a "Stand-Alone Celsius Thermometer" if you are looking for it on the datasheet.

I decided that using the "stand-alone" feature would ease my troubleshooting. I also hooked up my voltmeter to measure the output mV reading of the AD595 to make sure it really was doing what it was supposed to. I recommend this step since I did have a K-type thermocouple that was not reading at all. It helps to know that the individual subsections are working.

I tried to do the programming of the Arduino with as little help from existing code as possible, also I decided I would also only set up the AD595 from the data sheet only also. More or less worked and I spent a lot of time reading the data sheet and reading the Help, Reference section of the Arduino page and Processing page, which were thankfully actually helpful! I did fall back on the code from Making Things Talk for troubleshooting the serial connection, and without that I think I would have had a much harder time. Having something that works to compare against really makes a big difference.

Next I set up the Arduino to take the mV reading from the AD595 through one of the analog inputs. This went fairly well and I could view the serial input through the serial monitor quite well. One thing I did notice and have not yet done anything with is that the values will fluctuate on the analog input. I don't know why but I found it annoying. I don't know if it is picking up some stray AC signal but I just don't like it!

I setup the Processing program to read the serial input which was just the analog input value, had to convert to mV, (mostly to troubleshoot) then convert to Celsius by a somewhat inaccurate conversion method of dividing the mV reading by 10. It is close but if you look at the data sheet there is some divergence from this in their tablulation of mV vs. temperature.

I hope to get into refining the Processing program but for now I am happy that it worked. Probably the first thing is to setup the "handshake" serial transfer method that ends up project 1 in Making Things Talk.





























Processing Program to read the serial input and do conversions to show the temperature in Farenheit, Very rough, just got it working rough. Some of it may not make sense and be wrong! I was just happy that I finally got the temperature to read correct within a few degrees of my RadioShack digital thermometer!

/*
Temperature reader
Program Language: Processing 0133 Beta
Author: Lee Cavanagh
Revision:.1
Date: 12/15/07
Program reads serial data sent from an Arduino reading output from
a AD595AQ "Monolithic Thermocouple Amplifier
with Cold Junction Compensation"
Data is read through a analog input that coverts the 10mV/Deg C AD595 output
to a value within the range of 0-1023.
*/
import processing.serial.*; //Import the processing serial library
int linefeed = 10; //Linefeed in Ascii
Serial myPort; //The serial Port
PFont myFont; //Adds Font for displaying Temperature
int fontSize = 32; //sets the size of the Text
float rawTempData = 0.0; //the raw input of the temperature data
float tCelsius = 0.0; //temperature converted to Celsius
float tFarenheit = 0.0; //terperature converted to Farenheit
String myString = "0"; //input string from serial port
float miliVTemp = 500.0;


void setup() {
size (640,480); //sets the size of the display window
//uses font from system
PFont myFont = createFont(PFont.list()[2], fontSize);
textFont(myFont);

// list the available serial ports
//println(Serial.list());
//sets serial port
myPort = new Serial(this, Serial.list()[1], 9600);
//Read from buffer until it hits a linefeed.
//The linefeed tells it that it is at the group or piece of data I want
myPort.bufferUntil(linefeed);
}

void draw() {
background(100,204,0);

//Print the temperature:
text("TEMP: " + tFarenheit + " ºF" , 10, 50); //should print the temp in the middle of the screen
//println("Temperature : " + tFarenheit + " ºF");
}

void serialEvent(Serial myPort) {
//read serial buffer
String myString = myPort.readStringUntil(linefeed);
//if you got any bytes other than the linefeed it trims:
if (myString != null) {
myString = trim(myString);
//split the string at the commas
//and convert the sections into integers:
int sensors[] = int(split(myString, ','));
//pritn out the values you got:
for (int sensorNum =0; sensorNum < sensors.length; sensorNum++) {
print("Sensor " + sensorNum + ": " + sensors[sensorNum] + "\t");
//sets rawTempData equal to sensor[0]
rawTempData = sensors[0];
miliVTemp = rawTempData/1024*5.0*1000; //converts input to mV
println("miliVTemp=" + miliVTemp);
}

//add a linefeed after all the sensor values are printed:
println();
}
// text(myString, 10, 200);
//rawTempData = int(myString); //Puts the value into rawTempData
//convert to Celsius:
//Divide output of AD594 and you get the approx Celsius Temp
//There is some error as compared to the Manufacturer Datasheet
tCelsius = miliVTemp / 10.0 ;
//Convert C reading to Farenheit
tFarenheit = ((tCelsius * (1.8)) + 32);
println("Temperature : " + tCelsius + " ºC");
}


Arduino program to read the AD595 Thermocouple IC

/*
Program Language: Arduino
Author: Lee Cavanagh
Revision:.1
Date: 12/15/07
Program reads a AD595AQ Monolithic Thermocouple Amplifiers
with Cold Junction Compensation through a analog input and covert the 10mV/Deg C
to a analog input within the range of 0-1023.
That value will be sent through the serial USB by the Arduino to be read by the PC
*/

int temperature = 0; //value for the temperature voltage from the AD595
//converted to analog input value, will have to convert it at the PC to a real value
int tempSensor = 2; //analog input pin for temperature voltage input
void setup() {
//opens serial port to pc, rate to 9600
Serial.begin(9600);
}

void loop() {
//reads the analog sensor
temperature = analogRead(tempSensor);
//Prints the results from the analogRead
Serial.println(temperature,DEC);
}

3 comments:

Pete said...

The Sparkfun site for the AD-595 mentions using a decoupling capacitor. I can't find mention of that in the datasheet, but I assume that putting a decoupling cap in the supply voltage could perhaps improve the stability of the output voltage, without effecting the response time.

doog said...

Try averaging the sample and slowing down the loop a little to smooth out the temp readings and ease up on the CPU usage.

Here's an updated Sketch averaging over 10 samples and using a 1sec loop delay:

/*
Program Language: Arduino
Author: Lee Cavanagh
Revision:.1
Date: 12/15/07
Program reads a AD595AQ Monolithic Thermocouple Amplifiers
with Cold Junction Compensation through a analog input and covert the 10mV/Deg C
to a analog input within the range of 0-1023.
That value will be sent through the serial USB by the Arduino to be read by the PC
*/
#define SAMPLE_SIZE 10

int temperature[SAMPLE_SIZE]; //value for the temperature voltage from the AD595
//converted to analog input value, will have to convert it at the PC to a real value
int tempSensor = 1; //analog input pin for temperature voltage input
void setup() {
//opens serial port to pc, rate to 9600
Serial.begin(115200);
}

void loop() {
//reads the analog sensor
for( int i = 0; i < SAMPLE_SIZE; i++)
temperature[i] = analogRead(tempSensor);
for( int j = 1; j < SAMPLE_SIZE; j++)
temperature[0] += temperature[j];
//Prints the results from the analogRead
Serial.println(temperature[0]/SAMPLE_SIZE,DEC);
delay(1000); // 1 sec loop cycle
}

Clark said...

Thank you so much for posting this great article, I am so interested on what I read, good and useful content about "Temperature Measurements Simple But Hard", I would like to invite you to take a look to order viagra, you will find some good stuff there.