Hi there!
I've been attempting to replicate the PID control tutorial found here: http://electronoobs.com/eng_arduino_tut24.php
I've made a few small changes - no LCD, no encoder, and I've replaced the 12V heater with a piece of nichrome wire. The rest of the connections are the same.
I think I may be making some sort of rudimentary error when it comes to connecting my power supply. When I connect the positive terminal of my power supply to the wire and the negative terminal to my resistor, the thermocouple reading jumps to >400ºC but the wire does not heat up. When I swap the terminals so that negative is connected to the wire and positive to the resistor the thermocouple reading goes to 0ºC but still the wire does not heat.
As for connecting the thermocouple to the wire, I had the wire tip of the thermocouple just wrapped around my nichrome wire. Even if I do remove the thermocouple from the wire and adjusts the PWM value output to pin D3 manually (tried 0, 255, 127) the wire does not heat regardless of where I connect the positive/negative power terminals.
If anyone has any insight into what I may be doing wrong, I would greatly appreciate the help!
I'm happy to provide pictures of my breadboard set up if that would be helpful.
UPDATE: picture of schematic
Code:
#include <SPI.h>
//We define the SPI pìns
#define MAX6675_CS 10
#define MAX6675_SO 12
#define MAX6675_SCK 13
//Pins
int PWM_pin = 3;
//Variables
float temperature_read = 0.0;
float set_temperature = 100;
float PID_error = 0;
float previous_error = 0;
float elapsedTime, Time, timePrev;
int PID_value = 0;
//PID constants
int kp = 0; int ki = 0; int kd = 0;
int PID_p = 0; int PID_i = 0; int PID_d = 0;
void setup() {
pinMode(PWM_pin,OUTPUT);
TCCR2B = TCCR2B & B11111000 | 0x03; // pin 3 and 11 PWM frequency of 980.39 Hz
Time = millis();
}
void loop() {
// First we read the real value of temperature
temperature_read = readThermocouple();
//Next we calculate the error between the setpoint and the real value
PID_error = set_temperature - temperature_read;
//Calculate the P value
PID_p = kp * PID_error;
//Calculate the I value in a range on +-3
if(-3 < PID_error <3)
{
PID_i = PID_i + (ki * PID_error);
}
//For derivative we need real time to calculate speed change rate
timePrev = Time; // the previous time is stored before the actual time read
Time = millis(); // actual time read
elapsedTime = (Time - timePrev) / 1000;
//Now we can calculate the D calue
PID_d = kd*((PID_error - previous_error)/elapsedTime);
//Final total PID value is the sum of P + I + D
PID_value = PID_p + PID_i + PID_d;
//We define PWM range between 0 and 255
if(PID_value < 0)
{ PID_value = 0; }
if(PID_value > 255)
{ PID_value = 255; }
//Now we can write the PWM signal to the mosfet on digital pin D3
analogWrite(PWM_pin,255-PID_value); // have tried manually sending values 0, 127, 255 to see if wire will heat, no luck
previous_error = PID_error; //Remember to store the previous error for next loop.
delay(300);
}
double readThermocouple() {
uint16_t v;
pinMode(MAX6675_CS, OUTPUT);
pinMode(MAX6675_SO, INPUT);
pinMode(MAX6675_SCK, OUTPUT);
digitalWrite(MAX6675_CS, LOW);
delay(1);
// Read in 16 bits,
// 15 = 0 always
// 14..2 = 0.25 degree counts MSB First
// 2 = 1 if thermocouple is open circuit
// 1..0 = uninteresting status
v = shiftIn(MAX6675_SO, MAX6675_SCK, MSBFIRST);
v <<= 8;
v |= shiftIn(MAX6675_SO, MAX6675_SCK, MSBFIRST);
digitalWrite(MAX6675_CS, HIGH);
if (v & 0x4)
{
// Bit 2 indicates if the thermocouple is disconnected
return NAN;
}
// The lower three bits (0,1,2) are discarded status bits
v >>= 3;
// The remaining bits are the number of 0.25 degree (C) counts
return v*0.25;
}