beard_99
Newbie
Hello, I am relatively new to microcontrollers and to electronics in general. I need some help in building a PID temperature controller for a soldering iron, with K-type thermocouple sensor.
The code is not working, it only displays the temperature but the iron is not heating.
Please find attached the code and the schematic.
The code is not working, it only displays the temperature but the iron is not heating.
Please find attached the code and the schematic.
C:
//source: http://www.instructables.com/id/Arduino-controlled-light-dimmer-The-circuit/?lang=pt&ALLSTEPS
//Arduino controlled light dimmer: The software III
//The code below has been confirmed to work on the Leonardo
/*
AC Light Control
Updated by Robert Twomey
Changed zero-crossing detection to look for RISING edge rather
than falling. (originally it was only chopping the negative half
of the AC wave form).
Also changed the dim_check() to turn on the Triac, leaving it on
until the zero_cross_detect() turn's it off.
Adapted from sketch by Ryan McLaughlin
<a href="http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1230333861/30" rel="nofollow"> <a rel="nofollow"> http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1...</a>>
(now here: <a rel="nofollow"> http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1...</a>
*/
#include <TimerOne.h> // Avaiable from <a href="http://www.arduino.cc/playground/Code/Timer1" rel="nofollow"> <a href="http://www.arduino.cc/playground/Code/Timer1" rel="nofollow"> http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1...</a>
#include <PID_v1.h>
#include <max6675.h>
#include <LiquidCrystal.h>
#include <SPI.h>
#include <Wire.h>
#define thermoDO 12
#define thermoCS 10
#define thermoCLK 13
#define potentiometer A0
#define zerocrossing 2
#define relay A1
float realTemperature;
int pottemperature;
LiquidCrystal lcd(3, 4, 5, 6, 8, 9);
byte thermometer[8] = //icon for termometer
{
B00100,
B01010,
B01010,
B01110,
B01110,
B11111,
B11111,
B01110
};
byte arrow[8] = //icon for arrow
{
B11000,
B01100,
B00110,
B00011,
B00011,
B00110,
B01100,
B11000
};
MAX6675 thermocouple(thermoCLK, thermoCS, thermoDO);
double Setpoint, Input, Output;
double aggKp = 4, aggKi = 0.2, aggKd = 1;
double consKp = 1, consKi = 0.05, consKd = 0.25;
PID myPID(&Input, &Output, &Setpoint, consKp, consKi, consKd, DIRECT);
volatile int i = 0; // Variable to use as a counter
volatile boolean zero_cross = 0; // Boolean to store a "switch" to tell us if we have crossed zero
int triac = 7; // Output to Opto Triac
int dim = 0; // Dimming level (0-128) 0 = on, 128 = 0ff
int inc = 1; // counting up or down, 1=up, -1=down
int freqStep = 75; // This is the delay-per-brightness step in microseconds.
// For 60 Hz it should be 65
// It is calculated based on the frequency of your voltage supply (50Hz or 60Hz)
// and the number of brightness steps you want.
//
// Realize that there are 2 zerocrossing per cycle. This means
// zero crossing happens at 120Hz for a 60Hz supply or 100Hz for a 50Hz supply.
// To calculate freqStep divide the length of one full half-wave of the power
// cycle (in microseconds) by the number of brightness steps.
//
// (120 Hz=8333uS) / 128 brightness steps = 65 uS / brightness step
// (100Hz=10000uS) / 128 steps = 75uS/step
void setup() {
lcd.begin(16, 2);
lcd.createChar(0, thermometer);
lcd.createChar(1, arrow);
lcd.setCursor(0, 0);
lcd.print("STATIE DE LIPIT");
myPID.SetMode(AUTOMATIC);
myPID.SetOutputLimits(0, 128);
pinMode(relay, OUTPUT);
pinMode(potentiometer, INPUT);
pinMode(zerocrossing, INPUT_PULLUP);
pinMode(triac, OUTPUT); // Set the Triac pin as output
delay(1200);
lcd.clear();
digitalWrite(triac, LOW);
digitalWrite(relay, HIGH);
attachInterrupt(digitalPinToInterrupt(2), zero_cross_detect, RISING); // Attach an Interupt to Pin 2 (interupt 0) for Zero Cross Detection
Timer1.initialize(freqStep); // Initialize TimerOne library for the freq we need
Timer1.attachInterrupt(dim_check, freqStep);
// Use the TimerOne Library to attach an interrupt
// to the function we use to check to see if it is
// the right time to fire the triac. This function
// will now run every freqStep in microseconds.
}
void zero_cross_detect() {
zero_cross = true; // set the boolean to true to tell our dimming function that a zero cross has occured
i = 0;
digitalWrite(triac, LOW); // turn off TRIAC (and AC)
}
// Turn on the TRIAC at the appropriate time
void dim_check() {
if (zero_cross == true) {
if (i >= dim) {
digitalWrite(triac, HIGH); // turn on light
i = 0; // reset time step counter
zero_cross = false; //reset zero cross detection
}
else {
i++; // increment time step counter
}
}
}
void loop() {
pottemperature = analogRead(potentiometer);
pottemperature = map(pottemperature, 0, 1023, 150, 400); //pottemperature is volatile
Setpoint = pottemperature;
realTemperature = thermocouple.readCelsius();
Input = int(0.779828 * realTemperature - 10.3427); // make temperature an integer
if (isnan(realTemperature) || Input >= 432){
while(true){
displayErrors();
}
} else {
updateDisplay();
}
double gap = abs(Setpoint - Input); //distance away from setpoint
if (gap < 10)
{ //we're close to setpoint, use conservative tuning parameters
myPID.SetTunings(consKp, consKi, consKd);
}
else
{
//we're far from setpoint, use aggressive tuning parameters
myPID.SetTunings(aggKp, aggKi, aggKd);
}
myPID.Compute();
dim = Output;
delay(300);
}
void updateDisplay() {
pottemperature = analogRead(potentiometer);
Setpoint = map(pottemperature, 0, 1023, 150, 400);
lcd.clear();
lcd.setCursor(0, 0);
lcd.write((byte)0);
lcd.setCursor(2, 0);
lcd.print((int)Setpoint);
lcd.setCursor(6, 0);
lcd.print((char)223); //degree sign
lcd.setCursor(7, 0);
lcd.print("C");
lcd.setCursor(0, 1);
lcd.write((byte)1);
if (Input <= 45) {
lcd.setCursor(2, 1);
lcd.print("Lo");
} else {
lcd.setCursor(2, 1);
lcd.print((int)Input);
}
lcd.setCursor(6, 1);
lcd.print("[");
lcd.setCursor(7, 1);
lcd.print((int)realTemperature);
lcd.setCursor(10, 1);
lcd.print("]");
lcd.setCursor(12, 1);
lcd.print((char)223);
lcd.setCursor(13, 1);
lcd.print("C");
}
void displayErrors() {
digitalWrite(relay, LOW);
lcd.clear();
lcd.setCursor(0, 0);
lcd.write((byte)0);
lcd.setCursor(1, 0);
lcd.write((byte)0);
lcd.setCursor(5, 0);
lcd.print("ERROR!");
lcd.setCursor(14, 0);
lcd.write((byte)0);
lcd.setCursor(15, 0);
lcd.write((byte)0);
}