Has anyone succeeded in using Arduino to control a heater and read thermocouple values?
I am going to work with K-thermocouple.
Is there any exapmple( code)?
What configuration do you use?
Assuming this is an AC powered heater you can control it with a relay. A solid state relay is more expensive, but you can find solid state relays that can be driven directly from the Arduino's 5V low-current output. An electro-mechanical relay will usually require a driver circuit, although you can get a relay board with a driver built-in.
Thermocouples are tricky... You may want ot do some thermocouple research and/or unless you have some special requirements, you might want to consider an [u]LM34[/u] or LM35 These slick little solid state devices are cheap, accurate, and easy to use.
Thermocouples put-out a very-low voltage and they require an amplifier and an ice bath (or simulated ice bath/temperature reference). Where I work we use an [u]AD594[/u] (for type J) which is an amplifier circuit and a thermal reference. Like the ice bath method, it requires a 2nd reference-thermocouple mounted under (on top of) the chip for the thermal reference.
Once you have an amplified voltage (usually around 1V) you can convert the voltage (or ADC reading) to temperature in software. You can look-up the curve for the thermocouple type you're using and apply the amplifier gain to find the conversion factor(s). But, you'll probably need to calibrate the readings for accuracy.
Our circuit can be off by 5 degrees centigrade (or more) before calibration. And, we can to get a half-degree or so of noise and instability. For calibration, we happen to have a thermocouple simulator and we calibrate between 7 points between -200 and +400 without having to use any actual temperatures. (The thermocouple itself should be super-accurate, but high-gain analog amplifiers are not perfect.)
Ours is an old design and if it were designed today, I don't know if they'd use a thermocouple or a solid state temperature sensor. (We don't supply the thermocouple, just the data acquisition interface box).
What temperature range are you anticipating? Thermocouples are normally used for high temperatures such as a furnace. Thermocouple voltage is usually down in the microvolt area. Take look at a resistance temperature detector (RTD).
Phoxx
I use this
Thank you all for your replies.
I will need to control a heater that can have temperature from an ambient to 250 C, so my solution should be K-thermocouple . Is it so?
Works with any K type thermocouple
Will not work with any other kind of thermocouple other than K type
-200°C to +1350°C output in 0.25 degree increments - note that K thermocouples have about ±2°C to ±6°C accuracy
Try reading the links ...
I used a arduino to control my 3d printer extruder with a thermocouple
The heater was running on 12V and controlled with a MOSFET.
For the thermocouple i used a breakout bord.
To control it a wrote a simple PID controller its far from perfect but it worked.
Here is the code i used.
const int g_HeaterPin = 9;
char inputString[200];
int SET_Point = 0;
double pwm=0;
#define P_value 12
#define I_value 0.5
#define D_value 45
int HeatingTime=0;
#define MAX_HEATINGTIME 36000
//#define SET_Point 150
#define MAX_PWM 150
double Pid_Ivalue=0,Pid_Dvalue=0;
double lastError=0;
void setup()
{
Serial.begin(9600);
pinMode(g_HeaterPin, OUTPUT);
analogWrite(g_HeaterPin,0);
Serial.println("please enter temp end with a '!' :");
int c=0;
while (true) {
// get the new byte:
if (Serial.available()) {
char inChar = (char)Serial.read();
// add it to the inputString:
inputString[c] = inChar;
c++;
if (inChar == '!') {
inputString[c]=0;
if (atoi(inputString) > 0 && atoi(inputString) < 350) {
SET_Point=atoi(inputString);
break;
}
}
}
delay(10);
}
HeatingTime=0;
Serial.println("Start");
Serial.print("Set point is: ");
Serial.println(SET_Point);
}
double CalcPid(double currentTemp)
{
double error= SET_Point-currentTemp;
Pid_Dvalue = D_value * (error - lastError);
lastError=error;
if (error > 30) error=30;
double result;
Pid_Ivalue+=(error * I_value);
if (Pid_Ivalue < 0) Pid_Ivalue=0;
if (Pid_Ivalue > 100) Pid_Ivalue=100;
result = error*P_value+Pid_Ivalue + Pid_Dvalue;
Serial.print("PID P:");
Serial.print(error*P_value);
Serial.print(" : I:");
Serial.print(Pid_Ivalue);
Serial.print(" : D:");
Serial.print(Pid_Dvalue);
Serial.print("PID:");
Serial.print(result);
if (result > MAX_PWM) result = MAX_PWM;
if (result < 0) result = 0;
return result;
}
void loop()
{
int raw = analogRead(0);
Serial.print(" raw: ");
Serial.print(raw);
double celsius = ( 5.0 * raw * 100.0) / 1024.0;
int result=CalcPid(celsius);
if (celsius < SET_Point-2) {
if (HeatingTime > MAX_HEATINGTIME) {
Serial.println("Error heating shut down");
analogWrite(g_HeaterPin,0);
delay(100);
return;
}
HeatingTime++;
}
else HeatingTime=0;
analogWrite(g_HeaterPin,result);
Serial.print(" Celsius: ");
Serial.print(celsius);
Serial.print(" : PWM output");
Serial.print(result);
Serial.print(" : set point");
Serial.println(SET_Point);
delay(500);
}
@raschemmel: which link should I read?
@Michel000 : Thanks for the code of your PID controller. You use past tense. Does it mean you already found an even better solution?
For what ?
CHeck - MAX31855 library - Libraries - Arduino Forum - for a lib for MAX31855 with example code