Extruder/Heated bed PID control for the FRDM-K64F
main.cpp
- Committer:
- unix_guru
- Date:
- 2016-02-07
- Revision:
- 2:6e731a17523c
- Parent:
- 0:8b77aea74642
File content as of revision 2:6e731a17523c:
/** A demo application to show how to mangage and control a heater element
* through a PID loop using a Thermistor input and PWM output
* for the @NXP (@freescale) FRDM-K64F demo board.
*
* This particular example drives the heater element for a 3d Printer Extruder.
*
* For more information on PID control check out Brett Beauregard's Arduino PID library:
*
* https://github.com/br3ttb/Arduino-PID-Library
*
* The wikipedia article on PID controllers is a good place to start on
* understanding how they work:
*
* http://en.wikipedia.org/wiki/PID_controller
*
* The Thermistor value to Temerature routine uses the Steinhart-Hart equation.
This is a Thermistor to Temerature conversion demo
Much thanks to @Adafruit for this tutorial:
https://learn.adafruit.com/thermistor/using-a-thermistor
The 100K Thermistor is configured with a 4.7k series resistor
tied to vcc (3.3v) like this:
+3.3v
|
\
/ 4.7k series resistor
\
/
|
.-----------O To Anlog pin on FRDM board
|
\
/
Thermistor 100k Nominal
\
/
|
---
GND
*
* Author(s): Michael Ball unix_guru@hotmail.com
*
*/
#include "mbed.h"
#include "millis.h"
#include "PID.h"
float getTemperature();
Serial pc(USBTX, USBRX);
Ticker PrintTicker; // Send process results to Console once per second
Ticker ticker; // Set up the millis() ticker.
#define DEFAULT_Kp 1
#define DEFAULT_Ki 0.002
#define DEFAULT_Kd 20
#define AUTOMATIC 1
#define MANUAL 0
#define DIRECT 0
#define REVERSE 1
#define thermistor A3 // FRDM-K64F Analog input pin A3 - Adjust to your particular board
#define driver PTC3 // FRDM-K64F PWM output pin PTC3 - Adjust to your particular board
AnalogIn Thermistor(thermistor); // Read temperature value from thermistor on A3
PwmOut Driver(driver); // PWM drive FET heater on PTC3 values are 0-1.0
// For 0-100%
float Input, Output, Setpoint;
PID controller(&Input, &Output, &Setpoint, DEFAULT_Kp , DEFAULT_Ki , DEFAULT_Kd , DIRECT);
#define RATE 1.0 // Print rate Once per second
void PrintValues() { // Routine to print out results to console
pc.printf("Input Output Setpoint Kp Ki Kd time\r\n");
pc.printf("%f, %f, %f, %f, %f, %f, %d \r\n",
Input, Output, Setpoint, controller.GetKp() , controller.GetKi() , controller.GetKd() , millis() );
}
int main(){
startMillis(); // Initialize timer.
pc.baud(115200);
pc.printf("\r\nThermistor PID Test - Build " __DATE__ " " __TIME__ "\r\n");
PrintTicker.attach(&PrintValues,RATE); // Start PID process running at 100ms rate.
Setpoint = 80; // Set target temperature in degrees Celcius.
controller.SetMode(AUTOMATIC); // Turn PID controller on.
while(1){
Input = getTemperature(); // Actual temperature in Degrees Celcius
controller.Compute(); // Process PID loop.
Driver = Output/1000; // Sent PWM value scaled 0 - 1.0 as mbed requires
}
}
// This is the workhorse routine that calculates the temperature
// using the Steinhart-Hart equation for thermistors
// https://en.wikipedia.org/wiki/Steinhart%E2%80%93Hart_equation
float getTemperature() {
#define THERMISTORNOMINAL 100000 // 100k
// temp. for nominal resistance (almost always 25 C)
#define TEMPERATURENOMINAL 25
// The beta coefficient of the thermistor (usually 3000-4000)
#define BCOEFFICIENT 3950
// the value of the 'other' resistor
#define SERIESRESISTOR 4700
// This is the workhorse routine that calculates the temperature
// using the Steinhart-Hart equation for thermistors
// https://en.wikipedia.org/wiki/Steinhart%E2%80%93Hart_equation
float temperature, resistance;
float steinhart;
int a;
a = Thermistor.read_u16(); // Read 16bit Analog value
// pc.printf("Raw Analog Value for Thermistor = %d\r\n",a);
/* Calculate the resistance of the thermistor from analog votage read. */
resistance = (float) SERIESRESISTOR / ((65536.0 / a) - 1);
// pc.printf("Resistance for Thermistor = %f\r\n",resistance);
steinhart = resistance / THERMISTORNOMINAL; // (R/Ro)
steinhart = log(steinhart); // ln(R/Ro)
steinhart /= BCOEFFICIENT; // 1/B * ln(R/Ro)
steinhart += 1.0 / (TEMPERATURENOMINAL + 273.15); // + (1/To)
steinhart = 1.0 / steinhart; // Invert
temperature = steinhart - 273.15; // convert to C
// pc.printf("Extruder Temperature is %f\r\n", temperature);
return temperature;
}