Hey guys!
So, I'm building a 3D printer module for a CNC Mill and I decided to make the heating for the hotend with Arduino and a transistor. I am powering everything with an ATX power supply and I wired everything as shown below.
Now imagine I turn SW3 on (it makes the output go to the transistor witch turns the heater on) with a setpoint of 200°C, the temperature starts going up and up, until it gets to around 195°C. My problem is, if I turn the heating off (either by lowering the setpoint or flipping the switch) the temperature immediately jumps up 5 to 10 degrees. If I turn it back on, the temperature goes back down by the same 5 to 10 degrees. Since the Arduino calculates the temperature based on the voltage on pin A0, I suppose there's some voltage drop happening when I turn the heater on.
I measure the voltage on the 5V pin and ground and indeed I got ~4.70V when the heater is off and ~4.20V when it's on. For the 3.3V pin (which is the one the thermistor uses) I got ~3.10V and ~2.70V.
I'm pretty sure this was not happening before, it started a couple days ago, and I don't remember changing anything before then. I might be wrong though. If anyone knows what might be going on I'd appreciate if you could help me.
This is the information on the power supply (sorry for the bad picture):
And this is my code:
#include <PID_v1.h>
#include <LiquidCrystal.h>
#include <Encoder.h>
double Setpoint, currentTemp, Output;
const float kP = 5;
const float kI = 0.01;
const float kD = 8;
PID myPID(¤tTemp, &Output, &Setpoint,kP,kI,kD, DIRECT);
LiquidCrystal lcd(12, 11, 7, 6, 5, 4);
const int buttonPin = 8;
const int encoder1Pin = 2;
const int encoder2Pin = 3;
const int thermistorPin = A0;
const int transistorPin = 10;
const int ledPin = 9;
const int switchPin = 13;
Encoder myEnc(encoder1Pin, encoder2Pin);
long oldPosition = -999;
long newPosition;
boolean buttonPress;
int buttonState = 0;
int thermistorMax = 260;
int thermistorMin = 20;
#define resistorResistence 988
const int numSamples = 5;
int samples[numSamples];
const int SAMPLETIME = 200;
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);
pinMode(ledPin, OUTPUT);
pinMode(switchPin, INPUT);
Setpoint = 195;
myPID.SetMode(AUTOMATIC); //ligar PID
myPID.SetSampleTime(SAMPLETIME);
TCCR1B = TCCR1B & B11111000 | B00000100;
lcd.begin(16, 2);
lcd.home();
lcd.print("Controlador");
lcd.setCursor(5,1);
lcd.print("Temperatura");
delay(2000);
lcd.clear();
Serial.begin(9600);
delay(100);
lcd.setCursor(0,0);
lcd.print("SetPoint:");
lcd.setCursor(0,1);
lcd.print("Extrusor:");
delay(100);
}
void loop() {
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 ");
Setpoint = thermistorMax;
delay(1000);
}
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 ");
Setpoint = thermistorMin;
delay(1000);
}
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();
if (currentTemp < -25) {
Output = 0;
lcd.setCursor(11,1);
lcd.print("ERRO ");
}
else {
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");
if (digitalRead(switchPin) == LOW) {
Output = 0;
}
else {
myPID.Compute();
}
}
if (Output > 0) {
digitalWrite(ledPin, HIGH);
}
else {
digitalWrite(ledPin, LOW);
}
analogWrite(transistorPin, Output);
}
float getThermistor() {
uint8_t i;
float average;
int ms = millis();
if (ms >= nextUpdate) {
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;
average = 1023 / average - 1; // (1023/ADC - 1)
average = resistorResistence / average; // Rr / (1023/ADC - 1)
// 1/T = A + B * ln(R) + C * ln(R)^3
const float Acoef = 0.00069881617;
const float Bcoef = 0.00021539301;
const float Ccoef = 0.00000011493814;
float steinhart;
float lnR = log(average);
steinhart = Ccoef * pow(lnR, 3);
steinhart += Bcoef * lnR;
steinhart += Acoef;
steinhart = 1.0 / steinhart;
steinhart -= 273.15;
Serial.print(average);
Serial.print(" ");
Serial.print(steinhart);
Serial.print(" ");
Serial.print(Setpoint);
Serial.print(" ");
Serial.println(Output);
nextUpdate = ms + 500;
return steinhart;
}
}