Extruder/Heated bed PID control for the FRDM-K64F

Dependencies:   PID millis mbed

Committer:
unix_guru
Date:
Sun Feb 07 19:08:57 2016 +0000
Revision:
2:6e731a17523c
Parent:
0:8b77aea74642
FRDM-K64F - First version of PID heater control demo to manage temperature on a 3d printer extruder.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
unix_guru 0:8b77aea74642 1 /** A demo application to show how to mangage and control a heater element
unix_guru 2:6e731a17523c 2 * through a PID loop using a Thermistor input and PWM output
unix_guru 2:6e731a17523c 3 * for the @NXP (@freescale) FRDM-K64F demo board.
unix_guru 2:6e731a17523c 4 *
unix_guru 2:6e731a17523c 5 * This particular example drives the heater element for a 3d Printer Extruder.
unix_guru 2:6e731a17523c 6 *
unix_guru 2:6e731a17523c 7 * For more information on PID control check out Brett Beauregard's Arduino PID library:
unix_guru 2:6e731a17523c 8 *
unix_guru 2:6e731a17523c 9 * https://github.com/br3ttb/Arduino-PID-Library
unix_guru 2:6e731a17523c 10 *
unix_guru 2:6e731a17523c 11 * The wikipedia article on PID controllers is a good place to start on
unix_guru 2:6e731a17523c 12 * understanding how they work:
unix_guru 2:6e731a17523c 13 *
unix_guru 2:6e731a17523c 14 * http://en.wikipedia.org/wiki/PID_controller
unix_guru 2:6e731a17523c 15 *
unix_guru 2:6e731a17523c 16 * The Thermistor value to Temerature routine uses the Steinhart-Hart equation.
unix_guru 2:6e731a17523c 17 This is a Thermistor to Temerature conversion demo
unix_guru 2:6e731a17523c 18
unix_guru 2:6e731a17523c 19 Much thanks to @Adafruit for this tutorial:
unix_guru 2:6e731a17523c 20 https://learn.adafruit.com/thermistor/using-a-thermistor
unix_guru 2:6e731a17523c 21
unix_guru 2:6e731a17523c 22 The 100K Thermistor is configured with a 4.7k series resistor
unix_guru 2:6e731a17523c 23 tied to vcc (3.3v) like this:
unix_guru 2:6e731a17523c 24
unix_guru 2:6e731a17523c 25 +3.3v
unix_guru 2:6e731a17523c 26 |
unix_guru 2:6e731a17523c 27 \
unix_guru 2:6e731a17523c 28 / 4.7k series resistor
unix_guru 2:6e731a17523c 29 \
unix_guru 2:6e731a17523c 30 /
unix_guru 2:6e731a17523c 31 |
unix_guru 2:6e731a17523c 32 .-----------O To Anlog pin on FRDM board
unix_guru 2:6e731a17523c 33 |
unix_guru 2:6e731a17523c 34 \
unix_guru 2:6e731a17523c 35 /
unix_guru 2:6e731a17523c 36 Thermistor 100k Nominal
unix_guru 2:6e731a17523c 37 \
unix_guru 2:6e731a17523c 38 /
unix_guru 2:6e731a17523c 39 |
unix_guru 2:6e731a17523c 40 ---
unix_guru 2:6e731a17523c 41 GND
unix_guru 0:8b77aea74642 42 *
unix_guru 0:8b77aea74642 43 * Author(s): Michael Ball unix_guru@hotmail.com
unix_guru 0:8b77aea74642 44 *
unix_guru 0:8b77aea74642 45 */
unix_guru 0:8b77aea74642 46
unix_guru 0:8b77aea74642 47 #include "mbed.h"
unix_guru 2:6e731a17523c 48 #include "millis.h"
unix_guru 2:6e731a17523c 49 #include "PID.h"
unix_guru 2:6e731a17523c 50
unix_guru 2:6e731a17523c 51 float getTemperature();
unix_guru 2:6e731a17523c 52
unix_guru 0:8b77aea74642 53 Serial pc(USBTX, USBRX);
unix_guru 2:6e731a17523c 54 Ticker PrintTicker; // Send process results to Console once per second
unix_guru 2:6e731a17523c 55 Ticker ticker; // Set up the millis() ticker.
unix_guru 2:6e731a17523c 56
unix_guru 2:6e731a17523c 57 #define DEFAULT_Kp 1
unix_guru 2:6e731a17523c 58 #define DEFAULT_Ki 0.002
unix_guru 2:6e731a17523c 59 #define DEFAULT_Kd 20
unix_guru 0:8b77aea74642 60
unix_guru 2:6e731a17523c 61 #define AUTOMATIC 1
unix_guru 2:6e731a17523c 62 #define MANUAL 0
unix_guru 2:6e731a17523c 63 #define DIRECT 0
unix_guru 2:6e731a17523c 64 #define REVERSE 1
unix_guru 2:6e731a17523c 65 #define thermistor A3 // FRDM-K64F Analog input pin A3 - Adjust to your particular board
unix_guru 2:6e731a17523c 66 #define driver PTC3 // FRDM-K64F PWM output pin PTC3 - Adjust to your particular board
unix_guru 0:8b77aea74642 67
unix_guru 2:6e731a17523c 68 AnalogIn Thermistor(thermistor); // Read temperature value from thermistor on A3
unix_guru 2:6e731a17523c 69 PwmOut Driver(driver); // PWM drive FET heater on PTC3 values are 0-1.0
unix_guru 2:6e731a17523c 70 // For 0-100%
unix_guru 2:6e731a17523c 71
unix_guru 2:6e731a17523c 72 float Input, Output, Setpoint;
unix_guru 2:6e731a17523c 73 PID controller(&Input, &Output, &Setpoint, DEFAULT_Kp , DEFAULT_Ki , DEFAULT_Kd , DIRECT);
unix_guru 2:6e731a17523c 74
unix_guru 2:6e731a17523c 75 #define RATE 1.0 // Print rate Once per second
unix_guru 2:6e731a17523c 76
unix_guru 2:6e731a17523c 77 void PrintValues() { // Routine to print out results to console
unix_guru 2:6e731a17523c 78 pc.printf("Input Output Setpoint Kp Ki Kd time\r\n");
unix_guru 2:6e731a17523c 79 pc.printf("%f, %f, %f, %f, %f, %f, %d \r\n",
unix_guru 2:6e731a17523c 80 Input, Output, Setpoint, controller.GetKp() , controller.GetKi() , controller.GetKd() , millis() );
unix_guru 2:6e731a17523c 81
unix_guru 0:8b77aea74642 82 }
unix_guru 0:8b77aea74642 83
unix_guru 2:6e731a17523c 84
unix_guru 0:8b77aea74642 85 int main(){
unix_guru 0:8b77aea74642 86
unix_guru 2:6e731a17523c 87 startMillis(); // Initialize timer.
unix_guru 2:6e731a17523c 88
unix_guru 2:6e731a17523c 89 pc.baud(115200);
unix_guru 2:6e731a17523c 90 pc.printf("\r\nThermistor PID Test - Build " __DATE__ " " __TIME__ "\r\n");
unix_guru 0:8b77aea74642 91
unix_guru 2:6e731a17523c 92 PrintTicker.attach(&PrintValues,RATE); // Start PID process running at 100ms rate.
unix_guru 2:6e731a17523c 93
unix_guru 2:6e731a17523c 94 Setpoint = 80; // Set target temperature in degrees Celcius.
unix_guru 2:6e731a17523c 95 controller.SetMode(AUTOMATIC); // Turn PID controller on.
unix_guru 2:6e731a17523c 96
unix_guru 0:8b77aea74642 97
unix_guru 0:8b77aea74642 98 while(1){
unix_guru 0:8b77aea74642 99
unix_guru 2:6e731a17523c 100 Input = getTemperature(); // Actual temperature in Degrees Celcius
unix_guru 2:6e731a17523c 101
unix_guru 2:6e731a17523c 102 controller.Compute(); // Process PID loop.
unix_guru 2:6e731a17523c 103
unix_guru 2:6e731a17523c 104 Driver = Output/1000; // Sent PWM value scaled 0 - 1.0 as mbed requires
unix_guru 0:8b77aea74642 105
unix_guru 0:8b77aea74642 106 }
unix_guru 0:8b77aea74642 107
unix_guru 2:6e731a17523c 108 }
unix_guru 2:6e731a17523c 109
unix_guru 2:6e731a17523c 110
unix_guru 2:6e731a17523c 111 // This is the workhorse routine that calculates the temperature
unix_guru 2:6e731a17523c 112 // using the Steinhart-Hart equation for thermistors
unix_guru 2:6e731a17523c 113 // https://en.wikipedia.org/wiki/Steinhart%E2%80%93Hart_equation
unix_guru 2:6e731a17523c 114
unix_guru 2:6e731a17523c 115 float getTemperature() {
unix_guru 2:6e731a17523c 116 #define THERMISTORNOMINAL 100000 // 100k
unix_guru 2:6e731a17523c 117 // temp. for nominal resistance (almost always 25 C)
unix_guru 2:6e731a17523c 118 #define TEMPERATURENOMINAL 25
unix_guru 2:6e731a17523c 119 // The beta coefficient of the thermistor (usually 3000-4000)
unix_guru 2:6e731a17523c 120 #define BCOEFFICIENT 3950
unix_guru 2:6e731a17523c 121 // the value of the 'other' resistor
unix_guru 2:6e731a17523c 122 #define SERIESRESISTOR 4700
unix_guru 2:6e731a17523c 123
unix_guru 2:6e731a17523c 124 // This is the workhorse routine that calculates the temperature
unix_guru 2:6e731a17523c 125 // using the Steinhart-Hart equation for thermistors
unix_guru 2:6e731a17523c 126 // https://en.wikipedia.org/wiki/Steinhart%E2%80%93Hart_equation
unix_guru 2:6e731a17523c 127
unix_guru 2:6e731a17523c 128 float temperature, resistance;
unix_guru 2:6e731a17523c 129 float steinhart;
unix_guru 2:6e731a17523c 130 int a;
unix_guru 2:6e731a17523c 131
unix_guru 2:6e731a17523c 132 a = Thermistor.read_u16(); // Read 16bit Analog value
unix_guru 2:6e731a17523c 133 // pc.printf("Raw Analog Value for Thermistor = %d\r\n",a);
unix_guru 2:6e731a17523c 134
unix_guru 2:6e731a17523c 135 /* Calculate the resistance of the thermistor from analog votage read. */
unix_guru 2:6e731a17523c 136 resistance = (float) SERIESRESISTOR / ((65536.0 / a) - 1);
unix_guru 2:6e731a17523c 137 // pc.printf("Resistance for Thermistor = %f\r\n",resistance);
unix_guru 2:6e731a17523c 138
unix_guru 2:6e731a17523c 139 steinhart = resistance / THERMISTORNOMINAL; // (R/Ro)
unix_guru 2:6e731a17523c 140 steinhart = log(steinhart); // ln(R/Ro)
unix_guru 2:6e731a17523c 141 steinhart /= BCOEFFICIENT; // 1/B * ln(R/Ro)
unix_guru 2:6e731a17523c 142 steinhart += 1.0 / (TEMPERATURENOMINAL + 273.15); // + (1/To)
unix_guru 2:6e731a17523c 143 steinhart = 1.0 / steinhart; // Invert
unix_guru 2:6e731a17523c 144 temperature = steinhart - 273.15; // convert to C
unix_guru 2:6e731a17523c 145
unix_guru 2:6e731a17523c 146 // pc.printf("Extruder Temperature is %f\r\n", temperature);
unix_guru 2:6e731a17523c 147
unix_guru 2:6e731a17523c 148 return temperature;
unix_guru 2:6e731a17523c 149
unix_guru 2:6e731a17523c 150 }
unix_guru 2:6e731a17523c 151