Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Diff: main.cpp
- Revision:
- 2:6e731a17523c
- Parent:
- 0:8b77aea74642
--- a/main.cpp Wed Jan 27 21:32:34 2016 +0000
+++ b/main.cpp Sun Feb 07 19:08:57 2016 +0000
@@ -1,39 +1,151 @@
/** 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 more information on PID control
+ * 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 "PIDHeater.h" // PIDHeater simply takes two variables
- // The Thermistor input and the Heater output.
- //
+#include "millis.h"
+#include "PID.h"
+
+float getTemperature();
+
Serial pc(USBTX, USBRX);
-Ticker ticker;
+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 RATE 0.1 // Check temp every 100ms
-PIDHeater extruder(A3, PTC3); // Thermistor on A3 heater on PTC3
+#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
-void run_PID_loop() { // Periodically test temperature and set output
- extruder.run();
+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(){
- extruder.configureRange(0,250); // Set MIN/MAX temperature in degrees Celcius.
- extruder.setTemperature(25); // Set target temperature to 25 degrees Celcius.
+ startMillis(); // Initialize timer.
+
+ pc.baud(115200);
+ pc.printf("\r\nThermistor PID Test - Build " __DATE__ " " __TIME__ "\r\n");
- ticker.attach(&run_PID_loop,RATE); // Start PID process running at 100ms rate.
+ 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){
- pc.printf("Extruder Temperature is %f\r\n", extruder.getTemperature());
-
- wait(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
}
-}
\ No newline at end of file
+}
+
+
+// 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;
+
+}
+