148 lines
7.4 KiB
C++
148 lines
7.4 KiB
C++
/* Version C. JOUVE - février 2023 */
|
|
|
|
#include "mbed.h"
|
|
|
|
#define q_scale 1.241 /* scale ratio for voltage mesurement, ADC convertion and Temperature from sensor */
|
|
#define Maximum_PWM_Cyclic_Ratio 88 /* Iaverage = 15v/4,4ohm * Output_PWM_Heater : current limit on bench 3A => PWMmaxi = 88% */
|
|
#define Te_Controller 0.5 /* sampling period for controller in seconde */
|
|
#define Te_Measure_Temp 0.1 /* sampling period for temperature sensor measurement in seconde */
|
|
#define Nb_Sampl_Filter 16 /* number of samples of temperature for digital filtering */
|
|
#define Fan_Command 0.5 /* cyclic ratio for PWM Fan command */
|
|
|
|
/* Serial Communication with PC */
|
|
Serial pc(USBTX, USBRX); /* com port for serial link with PC */
|
|
|
|
/* Input Declaration */
|
|
AnalogIn Input_Sensor_Temperature(p20); /* analog input pin from LM35 temperature sensor : ratio 10mV/°C */
|
|
|
|
/* Output pin declaration */
|
|
PwmOut Output_PWM_Heater(p21); /* PWM output pin for power transistor to heater resistance : 3A maximum average current */
|
|
PwmOut Output_PWM_Fan(p22); /* PWM output pin for power transistor to DC FAN motor */
|
|
|
|
/* Ticker for Interruptions sampler */
|
|
Ticker Timer_Temperature_Measurement ; /* Sampling Ticker for temperature measurements */
|
|
Ticker Timer_Controller; /* Sampling Ticker for controller regulator */
|
|
|
|
/* Global data */
|
|
/* all temperature integer are x10 °C : 205 = 20.5°C */
|
|
unsigned short Air_Flow_Temperature; /* integer for filtered temperature data */
|
|
unsigned short Air_Flow_Temperature_Sensor_Measurement ; /* integer for temperature measurement */
|
|
unsigned short Set_Point_Air_Flow_Temperature; /* integer for set point temperature value */
|
|
|
|
float Air_Flow_Command_Heater; /* command value from corrector calculation (sample k) */
|
|
float Air_Flow_Command_Heater_1 = 0 ; /* previous command value from corrector calculation (sample k-1) */
|
|
short Steady_State_Error_1 = 0 ; /* previous steady state value from error calculation (sample k-1) */
|
|
|
|
/**************************/
|
|
void Interrupt_Function_for_Air_Flow_Temperature_Mesurement();
|
|
void Interrupt_Function_for_Keyboard_Touch();
|
|
void Interrupt_Function_for_Controller();
|
|
|
|
/****************************************************************/
|
|
/* Main Function */
|
|
/****************************************************************/
|
|
int main() {
|
|
pc.baud(115200); /* init com port speed with PC */
|
|
|
|
/* Set PWM outputs parameters */
|
|
Output_PWM_Heater.period_ms(2); /* PWM period for heater : 2ms (500Hz) */
|
|
Output_PWM_Fan.period_ms(2); /* PWM period for FAN : 2ms (500Hz) */
|
|
Output_PWM_Heater.write(1-0); /* 0% heater command cyclic ratio : (1-PWM) because of electronic inverter with transistor */
|
|
Output_PWM_Fan.write(1-Fan_Command); /* Fan command cyclic ration : electronic inverted with transistor */
|
|
|
|
/* Global data initialisation */
|
|
Set_Point_Air_Flow_Temperature = 200; /* starting with 20°C set point air flow */
|
|
Air_Flow_Command_Heater = 0;
|
|
|
|
/* Interrupts functions initialisation & event */
|
|
pc.attach(&Interrupt_Function_for_Keyboard_Touch, Serial::RxIrq); /* link to interrupt function from serial byte incoming on com port */
|
|
Timer_Temperature_Measurement.attach(&Interrupt_Function_for_Air_Flow_Temperature_Mesurement,Te_Measure_Temp); /* link between timer and ADC interrupt function */
|
|
Timer_Controller.attach(&Interrupt_Function_for_Controller,Te_Controller); /* link between timer and controller function */
|
|
|
|
/* main loop for others independent actions without interruptions */
|
|
while(1) {
|
|
// plot with SerialPlot software
|
|
pc.printf("%d,%d,%d\n", (int)Set_Point_Air_Flow_Temperature, (int)Air_Flow_Temperature, (int)Air_Flow_Command_Heater);
|
|
|
|
|
|
// plot with SerialPortPlotter software
|
|
// pc.printf("$%d %d %d;", (int)Set_Point_Air_Flow_Temperature, (int)Air_Flow_Temperature, (int)Air_Flow_Command_Heater);
|
|
|
|
// or print with CoolTerm software
|
|
//pc.printf("\n %u ",Set_Point_Air_Flow_Temperature);
|
|
|
|
wait(1); /* wait for plot display : no link with Te_Controller interrupt timer value */
|
|
}
|
|
}
|
|
|
|
/**********************************************************************************/
|
|
/* Temperature measurements from LM35 sensor : filtering or not */
|
|
/* - ADC 12 bits : read_u16 -> N define by the 12 most significant bits */
|
|
/* Ve = q x N , so q = 3.3/4096 = 0.8mV */
|
|
/* - LM35 analog output scale for temperature -> 10mV/°C that is 12.41 x q/°C */
|
|
/* and Sensor_Measurement = N / q_scale(1.241) to get ten ratio integer */
|
|
/**********************************************************************************/
|
|
void Interrupt_Function_for_Air_Flow_Temperature_Mesurement() {
|
|
/* you can implement a filtering algorithme on measurements in that function ! */
|
|
|
|
/* analog acquisition, 4 shift bits to keep the 12 most significant bits and scale ratio > Temperature measurement in 1/10°C */
|
|
Air_Flow_Temperature_Sensor_Measurement = (Input_Sensor_Temperature.read_u16()>>4)/q_scale ;
|
|
|
|
/* init the Air Flow Temperature value for controller */
|
|
Air_Flow_Temperature = Air_Flow_Temperature_Sensor_Measurement;
|
|
|
|
}
|
|
|
|
/**********************************************************************************/
|
|
/* Get the bytes from com port */
|
|
/* used for new Set Points or control */
|
|
/**********************************************************************************/
|
|
void Interrupt_Function_for_Keyboard_Touch(){
|
|
char tmp = pc.getc();
|
|
|
|
Output_PWM_Fan.write(1-Fan_Command); /* init FAN speed */
|
|
switch(tmp) {
|
|
case '3': { Set_Point_Air_Flow_Temperature = 300; /* Temperature SP at 30°C */
|
|
break; }
|
|
|
|
/* implement others cases for more Set_Point_Air_Flow_Temperature */
|
|
|
|
default : { Output_PWM_Fan.write(0); Set_Point_Air_Flow_Temperature = 0;
|
|
break; } /* FAN at maximum speed & no heater > fast decreasing temperature between two tests of set point value*/
|
|
}
|
|
|
|
}
|
|
|
|
/****************************************************************/
|
|
/* Corrector for Air Flow Flow regulation */
|
|
/* Format des variables du correcteur */
|
|
/* Temperature Measurement T°C [0-100] by 0.1°C steps */
|
|
/* Set Point T°C [0-100] by 0.1°C steps */
|
|
/* Air_Flow_Command_Heater [0-100%] limited at 88% */
|
|
/****************************************************************/
|
|
void Interrupt_Function_for_Controller(){
|
|
short Steady_State_Error =0 ;
|
|
float cst=0;
|
|
float Kp=0.6, Ki=1/180.0;
|
|
|
|
/* Write here your controller !! */
|
|
|
|
|
|
/* Command limitor = safety for heating resistance */
|
|
if (Air_Flow_Command_Heater > Maximum_PWM_Cyclic_Ratio)
|
|
{
|
|
Air_Flow_Command_Heater = Maximum_PWM_Cyclic_Ratio;
|
|
}
|
|
if (Air_Flow_Command_Heater < 0)
|
|
{
|
|
Air_Flow_Command_Heater = 0;
|
|
}
|
|
|
|
/* Output the heater command to PWM cyclic ratio for power transistor */
|
|
Output_PWM_Heater.write(1.0 - (float)Air_Flow_Command_Heater/100.0);
|
|
|
|
/* Keep memory of k value of data (in k-1 data) */
|
|
|
|
|
|
}
|