Hey guys, I'm stuck and need your help.
I'm making a 3D printer module for a CNC Mill, and needed to make a circuit to control the temperature of the hot-end. So I hooked up a heater, a 100K thermistor, an LCD screen, an encoder to set the temperature and a fan. Just like the circuit below:
However, as I was testing the thermistor, I was getting some weird response at higher temperatures (>110°C). So I improvised a test rig, where I would put the thermistor and a cooking thermometer next to each other in a pan, where I would put some oil and heat it up. The graph below shows something close to the results I got:
The temperature Arduino shows me goes hand in hand with the temperature shown by the thermometer up to around 110°C, then it simply can't go above 140°C.
"This thermistor must be faulty", is what I think, so I check its resistance with a multimeter at various points, and they also start to differ from the resistance shown by Arduino at around 110°C. In fact, the measured resistance was exactly the expected value at that temperature.
TL;DR: The thermistor resistance calculated by my code fits the resistance measured with a multimeter up to around 110°C, then it sort of stagnates above 2kOhms, while the multimeter shows that it actually keeps going down.
So definitely there must be something wrong with either my code, or my wiring (I'm using a breadboard and a lot of jumper wires, even though I heard they're not ideal, sorry it's my first time).
EDIT: Here is an approximation of the results for the resistance shown by Arduino and by a multimeter:
(The data in these graphs is not completely accurate, it's just based on what I remember from my test)
Here is my full code, the thermistor's resistance function is at the end. The Steinhart-Hart equation appears to be working just fine.
#include <PID_v1.h>
#include <LiquidCrystal.h>
#include <Encoder.h>
double Setpoint, currentTemp, Output;
const int kP = 3;
const int kI = 1.5;
const int kD = 2;
PID myPID(¤tTemp, &Output, &Setpoint,kP,kI,kD, DIRECT);
LiquidCrystal lcd(12, 11, 7, 6, 5, 4);
//pins
const int buttonPin = 8;
const int encoder1Pin = 2;
const int encoder2Pin = 3;
const int thermistorPin = A0;
const int transistorPin = 10;
const int ledPin = 9;
Encoder myEnc(encoder1Pin, encoder2Pin);
//Variables
long oldPosition = -999;
long newPosition;
boolean buttonPress;
int buttonState = 0;
int thermistorMax = 260;
int thermistorMin = 30;
#define resistorResistence 98500 //series resistor resistance
#define thermistorNominal 100000 //termistor nominal resistance
const int temperatureNominal = 25; //nominal temperature (C)
const int numSamples = 5;
const int betaCoefficient = 4083;
int samples[numSamples];
const int SAMPLETIME = 1000;
int nextUpdate = 0;
void setup() {
analogReference(EXTERNAL);
pinMode(transistorPin, OUTPUT);
pinMode(thermistorPin, INPUT);
pinMode(buttonPin, INPUT_PULLUP);
pinMode(encoder1Pin, INPUT_PULLUP);
pinMode(encoder2Pin, INPUT_PULLUP);
Setpoint = 95;
myPID.SetMode(AUTOMATIC);
myPID.SetSampleTime(SAMPLETIME);
lcd.begin(16, 2);
lcd.home();
lcd.print("Controlador");
lcd.setCursor(5,1);
lcd.print("Temperatura");
delay(2000);
lcd.clear();
Serial.begin(9600);
delay(200);
lcd.setCursor(0,0);
lcd.print("SetPoint:");
lcd.setCursor(0,1);
lcd.print("Extrusor:");
delay(200);
}
void loop() {
//routine for detecting one of two encoder button states
buttonPress = digitalRead(buttonPin);
if (buttonPress == 0) {
if (buttonState == 0) {
buttonState = 1;
while (buttonPress == 0) {
buttonPress = digitalRead(buttonPin);
delay(100);
}
}
else {
buttonState = 0;
while (buttonPress == 0) {
buttonPress = digitalRead(buttonPin);
delay(100);
}
}
}
newPosition = myEnc.read();
if (newPosition > oldPosition) {
if (Setpoint >= thermistorMax) {
lcd.setCursor(11,0);
lcd.print(" MAX ");
delay(1000);
Setpoint = thermistorMax;
}
else {
if (buttonState == 0) {
Setpoint += 5;
}
else {
Setpoint += 1;
}
}
delay(100);
oldPosition = myEnc.read();
lcd.setCursor(11,0);
if (Setpoint < 99.5) {
lcd.print(" ");
}
lcd.print(Setpoint);
lcd.setCursor(14,0);
lcd.print(char(223));
lcd.println("C");
}
else if (newPosition < oldPosition) {
if (Setpoint <= thermistorMin) {
lcd.setCursor(11,0);
lcd.print(" MIN ");
delay(1000);
Setpoint = thermistorMin;
}
else {
if (buttonState == 0) {
Setpoint -= 5;
}
else {
Setpoint -= 1;
}
}
delay(100);
oldPosition = myEnc.read();
lcd.setCursor(11,0);
if (Setpoint < 99.5) {
lcd.print(" ");
}
lcd.print(Setpoint);
lcd.setCursor(14,0);
lcd.print(char(223));
lcd.println("C");
}
currentTemp = getThermistor();
lcd.setCursor(11,1);
if (currentTemp < 99.5) {
lcd.print(" ");
}
lcd.print(round(currentTemp));
lcd.setCursor(14,1);
lcd.print(char(223));
lcd.println("C");
myPID.Compute();
analogWrite(transistorPin, Output);
if (Output > 0) {
digitalWrite(ledPin, HIGH);
}
else {
digitalWrite(ledPin, LOW);
}
}
float getThermistor() {
uint8_t i;
float average;
int ms = millis();
if (ms >= nextUpdate) { //repeats routine after a certain time period (500 ms)
for (i=0; i<numSamples; i++) {
samples[i] = analogRead(thermistorPin);
delay(10);
}
average = 0;
for (i=0; i<numSamples; i++) {
average += samples[i];
}
average /= numSamples;
//Calculate thermistor resistance:
// [Thermistor Resistance] = [Series Resistor] / (1023/ADC - 1)
float average = 1023 / average - 1; // (1023/ADC - 1)
float average = resistorResistence / average; // 98500 / (1023/ADC - 1)
//Steinhart-Hart equation:
// 1/T = 1/To + 1/Beta * ln(R/Ro)
float steinhart;
steinhart = average3 / thermistorNominal; // (R/Ro)
steinhart = log(steinhart); // ln(R/Ro)
steinhart /= betaCoefficient; // 1/Beta * ln(R/Ro)
steinhart += 1.0 / (temperatureNominal + 273.15); // 1/To + 1/Beta * ln(R/Ro)
steinhart = 1.0 / steinhart; // inverts
steinhart -= 273.15; // converts to Celsius
Serial.print(average);
Serial.print(" ");
Serial.print(steinhart);
Serial.print(" ");
Serial.println(Output);
nextUpdate = ms + 500;
return steinhart;
}
}
