FRDM-K64F Code Share
/
PIDHeater
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; }