diff options
Diffstat (limited to 'Software/Embedded_SW/Embedded/Modules/Heaters')
6 files changed, 472 insertions, 0 deletions
diff --git a/Software/Embedded_SW/Embedded/Modules/Heaters/Heaters.h b/Software/Embedded_SW/Embedded/Modules/Heaters/Heaters.h new file mode 100644 index 000000000..beaf32b2a --- /dev/null +++ b/Software/Embedded_SW/Embedded/Modules/Heaters/Heaters.h @@ -0,0 +1,62 @@ +#include "PMR/Hardware/HardwarePidControl.pb-c.h" +#include "PMR/Hardware/HardwarePidControlType.pb-c.h" +/******************** DEFINITIONS ********************************************/ +#define MAX_AC_HEATERS HARDWARE_PID_CONTROL_TYPE__DryerHeater200w2+1 +#define MAX_TIMESLICES 200 +#define MAX_HEATERS_NUM HARDWARE_PID_CONTROL_TYPE__MixerHeater+1 +#define MAX_HEATERS_TEMPERATURE 300 + +extern uint32_t OutputProportionalSingleStep; //A/C Heaters step size from one decision point to another - in cpu clocks. 120000 = 1 millisecod +extern uint32_t OutputProportionalCycleTime; //A/C Heaters Cycle time in milliseconds - one for all heaters +//extern uint32_t Heater_timerBase; //Timer handle +extern char TimeSliceAllocation[MAX_TIMESLICES]; +extern int NumberOFSlicesInUse; + + +typedef struct HeaterPIDControlConfigstruc +{ + int id; //HardwarePidControlType + char name[20]; + int32_t outputproportionalpowerlimit; + int32_t outputproportionalband; + int32_t integraltime; + int32_t derivativetime; + int32_t sensorcorrectionadjustment; + int32_t sensortypeandsetpointlimits; + int32_t setpointramprateorsoftstartramp; + int32_t setpointcontroloutputrate; + int32_t controloutputtype; + int32_t ssrcontroloutputtype; + int32_t outputonoffhysteresisvalues; + int32_t processvariablesamplingrate; + int32_t pvinputfilterfactormode; + double kp; + double ki; + double kd; +}HeaterPIDControlConfig; + +typedef struct HeaterCommandstruc +{ + int heaterid; //HardwarePidControlType + bool command; + uint32_t targettemperatue; +}HeaterCommand; + +typedef struct +{ + bool m_isEnabled; + uint32_t m_SetParam; + uint32_t m_mesuredParam; + float m_preError; + float m_integral; + float m_calculatedError; + bool m_isReady; + PID_Config_Params m_params; +}HeaterControlConfig_t; + +extern HeaterPIDControlConfig HeaterControl[MAX_HEATERS_NUM]; +extern HeaterControlConfig_t HeaterPIDConfig[MAX_HEATERS_NUM]; +extern HeaterCommand HeaterCmd[MAX_HEATERS_NUM]; +extern uint32_t DeviceId2Heater[MAX_HEATERS_NUM]; + + diff --git a/Software/Embedded_SW/Embedded/Modules/Heaters/Heaters_bit.c b/Software/Embedded_SW/Embedded/Modules/Heaters/Heaters_bit.c new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/Software/Embedded_SW/Embedded/Modules/Heaters/Heaters_bit.c diff --git a/Software/Embedded_SW/Embedded/Modules/Heaters/Heaters_ex.h b/Software/Embedded_SW/Embedded/Modules/Heaters/Heaters_ex.h new file mode 100644 index 000000000..b5249d302 --- /dev/null +++ b/Software/Embedded_SW/Embedded/Modules/Heaters/Heaters_ex.h @@ -0,0 +1,9 @@ +#include "PMR/common/MessageContainer.pb-c.h" +#include "PMR/Hardware/HardwarePidControl.pb-c.h" + +//uint32_t HeaterCommandRequestMessage(MessageContainer* requestContainer); +uint32_t HeaterConfigRequestMessage(HardwarePidControl* request); +uint32_t HeaterConfigSetSharedHeatersParams (uint32_t outputproportionalcycletime, uint32_t outputproportionalsinglestep); + +uint32_t HeaterCommandRequestMessage(int HeaterId, bool OnOff, int Temperature); + diff --git a/Software/Embedded_SW/Embedded/Modules/Heaters/Heaters_init.c b/Software/Embedded_SW/Embedded/Modules/Heaters/Heaters_init.c new file mode 100644 index 000000000..55da2ecfa --- /dev/null +++ b/Software/Embedded_SW/Embedded/Modules/Heaters/Heaters_init.c @@ -0,0 +1,154 @@ +/************************************************************************************************************************ + * Heaters_init.c + **************************************************************************************************************************/ + +////////////////////////////////State machine operation//////////////////////////////////// +//the state machine operation is used to operate in runtime correct profile flow execution +//by recieved esign flow of the user from the UI +/////////////////////////////////////////////////////////////////////////////////////////// +#include "include.h" + +#include <Modules/Stubs_Handler/DataDef.h> +//#include "PMR/Hardware/PIDControlConfig.pb-c.h" +//#include "PMR/Hardware/PIDCluster.pb-c.h" +//#include "PMR/Hardware/HeaterControl.pb-c.h" +//#include "PMR/Hardware/HeaterCommandRequest.pb-c.h" +//#include "PMR/Hardware/HeaterCommandRequest.pb-c.h" +#include "PMR/Hardware/HardwarePidControl.pb-c.h" +#include "PMR/Hardware/HardwarePidControlType.pb-c.h" +#include "PMR/common/MessageContainer.pb-c.h" + +#include "../control/control.h" +#include "../control/pidalgo.h" +#include "include.h" +#include <driverlib/timer.h> + +#include "heaters.h" +#include "Drivers/Heater/Heater.h" + + + +/******************** STRUCTURES AND ENUMs ********************************************/ +typedef enum { + HeatersInitialState, + HeatersInit, + HeatersControlledOp, + HeatersShutdown, + HeatersTest, + MaxHeatersStates +}HEATERS_STATES_ENUM; +typedef enum { + HeatersCold, + HeatersAtPIDStrip, + HeatersOverHeat, + HeatersOnTest +}HEATERS_EVENTS_ENUM; + +/******************** GLOBAL PARAMETERS ********************************************/ +HeaterPIDControlConfig HeaterControl[MAX_HEATERS_NUM] = {0}; +HeaterControlConfig_t HeaterPIDConfig[MAX_HEATERS_NUM] = {0}; +uint32_t DeviceId2Heater[MAX_HEATERS_NUM] = {0}; +bool AcHeaterConfigured[MAX_AC_HEATERS] = {0}; + +/******************** CODE ********************************************/ +/* + * HeatersInit + * called by: General Hardware Init + * initialized all global data + */ +uint32_t Heaters_Init(void) +{ + return OK; +} + + +uint32_t HeaterConfigRequestMessage(HardwarePidControl* request) +{ + //uint32_t status = OK; + HardwarePidControlType HeaterId; + + HeaterId = request->hardwarepidcontroltype; + int ValidationError = 0; + + if ((HeaterId)&&(HeaterId< MAX_HEATERS_NUM)) + { + HeaterControl[HeaterId].id = HeaterId; + //strncpy (HeaterControl[HeaterId].name, request->name, 20); + HeaterControl[HeaterId].outputproportionalpowerlimit = request->outputproportionalpowerlimit; + HeaterControl[HeaterId].outputproportionalband = request->outputproportionalband; + HeaterControl[HeaterId].integraltime = request->integraltime; + HeaterControl[HeaterId].derivativetime = request->derivativetime; + HeaterControl[HeaterId].sensorcorrectionadjustment = request->sensorcorrectionadjustment; + //HeaterControl[HeaterId].sensortypeandsetpointlimits = request->sensortypeandsetpointlimits; + HeaterControl[HeaterId].setpointramprateorsoftstartramp = request->setpointramprateorsoftstartramp; + HeaterControl[HeaterId].setpointcontroloutputrate = request->setpointcontroloutputrate; + HeaterControl[HeaterId].controloutputtype = request->controloutputtype; + HeaterControl[HeaterId].ssrcontroloutputtype = request->ssrcontroloutputtype; + HeaterControl[HeaterId].outputonoffhysteresisvalues = request->outputonoffhysteresisvalue; + HeaterControl[HeaterId].processvariablesamplingrate = request->processvariablesamplingrate; + HeaterControl[HeaterId].pvinputfilterfactormode = request->pvinputfilterfactormode; + + if (HeaterId < MAX_AC_HEATERS) + AcHeaterConfigured[HeaterId] = true; + + //check if all A/C heaters are defined. if they are - validate the configuration + if (HeaterControl[HARDWARE_PID_CONTROL_TYPE__DryerHeater1000w].id + &&HeaterControl[HARDWARE_PID_CONTROL_TYPE__DryerHeater200w1].id + &&HeaterControl[HARDWARE_PID_CONTROL_TYPE__DryerHeater200w2].id) + { + if (HeaterControl[HARDWARE_PID_CONTROL_TYPE__DryerHeater1000w].outputproportionalpowerlimit + + HeaterControl[HARDWARE_PID_CONTROL_TYPE__DryerHeater200w1].outputproportionalpowerlimit + + HeaterControl[HARDWARE_PID_CONTROL_TYPE__DryerHeater200w2].outputproportionalpowerlimit> 100) + ValidationError += 2; + if (ValidationError) + { + LOG_ERROR (ValidationError, "Validation Error in Heaters Control"); + return ERROR; + } + } + return OK; + } + return ERROR; + +} + +/* + * HeaterConfigSetSharedHeatersParams - prepare the time slices for A/C heaters co-ordinated operation + * called by the general hardware HWConfigurationFunc + * parameters - the cycle time for the coordinated operation, the size (in MCU cycles) of a single step. + */ +uint32_t HeaterConfigSetSharedHeatersParams(uint32_t outputproportionalcycletime, uint32_t outputproportionalsinglestep) +{ + int Slice_i; + int Heater1000Slices,Heater200aSlices /*,Heater200bSlices Currently both 200W heaters will work together*/; + + //A/C Heaters Cycle time in milliseconds - one for all heaters + OutputProportionalCycleTime = outputproportionalcycletime; + + //A/C Heaters step size from one decision point to another - in cpu clocks. 120000 = 1 millisecod + OutputProportionalSingleStep = outputproportionalsinglestep; + + // calculate how many milliseconds is in each operating cycle (should be an integer number) + uint32_t MillisecondsPerChange = OutputProportionalSingleStep/120000; + + // calculate how many time slices are used. the total cycle time / the length of one operating cycle. (one added to put a time gap??? TBD) + NumberOFSlicesInUse = (OutputProportionalCycleTime/MillisecondsPerChange); + + if (NumberOFSlicesInUse > MAX_TIMESLICES ) + { + LOG_ERROR (NumberOFSlicesInUse, "NumberOFSlicesInUse too high"); + return ERROR;//NumberOFSlicesInUse = MAX_TIMESLICES; + } + + // all numbers are rounded down. better to have carefully calculated numbers + Heater1000Slices = HeaterControl[HARDWARE_PID_CONTROL_TYPE__DryerHeater1000w].outputproportionalpowerlimit * NumberOFSlicesInUse / 100; + Heater200aSlices = HeaterControl[HARDWARE_PID_CONTROL_TYPE__DryerHeater200w1].outputproportionalpowerlimit * NumberOFSlicesInUse / 100; + + //mark the time slices for heaters operation as empty / Heater1000 / Heater 200 + memset (TimeSliceAllocation,0xFF,sizeof(TimeSliceAllocation)); + for (Slice_i = 0; Slice_i < Heater1000Slices;Slice_i++ ) TimeSliceAllocation[Slice_i] = HARDWARE_PID_CONTROL_TYPE__DryerHeater1000w; + for (Slice_i = Heater1000Slices; Slice_i < Heater1000Slices+Heater200aSlices;Slice_i++ ) TimeSliceAllocation[Slice_i] = HARDWARE_PID_CONTROL_TYPE__DryerHeater200w1; + + return OK; + +} diff --git a/Software/Embedded_SW/Embedded/Modules/Heaters/Heaters_maint.c b/Software/Embedded_SW/Embedded/Modules/Heaters/Heaters_maint.c new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/Software/Embedded_SW/Embedded/Modules/Heaters/Heaters_maint.c diff --git a/Software/Embedded_SW/Embedded/Modules/Heaters/Heaters_print.c b/Software/Embedded_SW/Embedded/Modules/Heaters/Heaters_print.c new file mode 100644 index 000000000..3eeff9ec3 --- /dev/null +++ b/Software/Embedded_SW/Embedded/Modules/Heaters/Heaters_print.c @@ -0,0 +1,247 @@ +/************************************************************************************************************************ + * Heaters_print.c + **************************************************************************************************************************/ + +////////////////////////////////State machine operation//////////////////////////////////// +//the state machine operation is used to operate in runtime correct profile flow execution +//by recieved esign flow of the user from the UI +/////////////////////////////////////////////////////////////////////////////////////////// +#include "include.h" + +#include <Modules/Stubs_Handler/DataDef.h> +//#include "PMR/Hardware/PIDCluster.pb-c.h" +#include "PMR/Hardware/HardwarePidControlType.pb-c.h" +#include "PMR/Hardware/HardwarePidControl.pb-c.h" +#include "PMR/common/MessageContainer.pb-c.h" + +#include "../control/control.h" +#include "../control/pidalgo.h" +#include "include.h" +#include <driverlib/timer.h> + +#include "heaters.h" +#include "Drivers/Heater/Heater.h" + + +/******************** GLOBAL PARAMETERS ********************************************/ +HeaterCommand HeaterCmd[MAX_HEATERS_NUM] = {}; +int NumberOFSlicesInUse = 0; +bool HeatersRestart = false; + +uint32_t OutputProportionalSingleStep = 0; //A/C Heaters step size from one decision point to another - in cpu clocks. 120000 = 1 millisecod +uint32_t Heater_timerBase = TIMER2_BASE; //Timer handle +uint32_t OutputProportionalCycleTime = 0; //A/C Heaters Cycle time in milliseconds - one for all heaters +char TimeSliceAllocation[MAX_TIMESLICES] = {0}; + +bool InitialHeatingState = false; +/******************** FUNCTIONS ********************************************/ +uint32_t HeaterControlCBFunction(uint32_t deviceID, uint32_t ReadValue); +uint32_t PrepareHeater(int HeaterId, uint32_t SetTemperatue); + +/* + * HeaterCommandRequestMessage + * called by: Communication from host + * initialized all global data + */ +uint32_t HeaterCommandRequestMessage(int HeaterId, bool OnOff, int Temperature) +{ + //uint32_t status = NOT_SUPPORTED; + //MessageContainer responseContainer; + if ((HeaterId)&&(HeaterId< MAX_HEATERS_NUM)) + { + if (HeaterControl[HeaterId].id != HeaterId) // heater configuration missing + { + LOG_ERROR (HeaterId, "Heater is not yet configured"); + return ERROR; + } + HeaterCmd[HeaterId].heaterid = HeaterId; + HeaterCmd[HeaterId].command = OnOff; + HeaterCmd[HeaterId].targettemperatue = Temperature; + } + bool HeaterState = GetHeaterState(HeaterId); + + if ((HeaterState == HEATER_OFF)&& (OnOff == HEATER_ON)) //start heating + { + //set the heater control parameters + //set the target operation temperature + //start the control + PrepareHeater(HeaterId,Temperature); //prepare the heaters control info + //set the power balance handler (if not set yet) + ROM_TimerConfigure(Heater_timerBase, TIMER_CFG_PERIODIC); // 32 bits Timer + ROM_IntEnable(INT_TIMER2B); + ROM_TimerIntEnable(Heater_timerBase, TIMER_TIMA_TIMEOUT); + // if the heater is off (?) start it. + ActivateHeater(HeaterId); + //set the heater operation mode to fast heating - depended on the current temperature + // timers are prepared but not started yet!!! only when the system is hot. + + } + else if ((HeaterState == HEATER_ON)&& (OnOff == HEATER_ON)) //set temperature + { + HeaterPIDConfig[HeaterId].m_SetParam = Temperature; + // if the heater is not on return (?). + //set the target operation temperature + //set the heater operation mode to fast heating - depended on the current temperature + } + else if ((HeaterState == HEATER_ON)&& (OnOff == HEATER_OFF)) //stop heating + { + //turn off the heater + //stop the control + HeaterPIDConfig[HeaterId].m_SetParam = HeaterId; + } + else + { + LOG_ERROR (OnOff, "unsupported command id"); + return ERROR; + } + + return OK; +} +/* + * PrepareHeater + * called by: Communication from host + * initialized all global data + */ +uint32_t PrepareHeater(int HeaterId, uint32_t SetTemperatue) +{ + assert(HeaterId < MAX_HEATERS_NUM); + assert(SetTemperatue < MAX_HEATERS_TEMPERATURE); + + //start thread control for all motors + HeaterPIDConfig[HeaterId].m_params.MAX = HeaterControl[HeaterId].outputproportionalpowerlimit; + HeaterPIDConfig[HeaterId].m_params.MIN = .0; + HeaterPIDConfig[HeaterId].m_params.Kd = HeaterControl[HeaterId].kd; + HeaterPIDConfig[HeaterId].m_params.Kp = HeaterControl[HeaterId].kp; + HeaterPIDConfig[HeaterId].m_params.Ki = HeaterControl[HeaterId].ki; + HeaterPIDConfig[HeaterId].m_params.dt = eHunderdMillisecond; + HeaterPIDConfig[HeaterId].m_calculatedError = 0; + HeaterPIDConfig[HeaterId].m_integral = 0; + HeaterPIDConfig[HeaterId].m_isEnabled = true; + HeaterPIDConfig[HeaterId].m_isReady = true; + HeaterPIDConfig[HeaterId].m_mesuredParam = 0; + HeaterPIDConfig[HeaterId].m_preError = 0; + HeaterPIDConfig[HeaterId].m_SetParam = SetTemperatue;//need to update SetParams on presegment stage + AddControlCallback(DeviceId2Heater[HeaterId], HeaterControlCBFunction, eHunderdMillisecond); + + return OK; +} + +/* + * HeaterControlCBFunction + * called by: Communication from host + * initialized all global data + */ + +uint32_t HeaterControlCBFunction(uint32_t deviceID, uint32_t ReadValue) +{ + int i,index=MAX_HEATERS_NUM; + char str[100]; + uint8_t len = 0; + + for (i=0;i<MAX_HEATERS_NUM;i++) + if (DeviceId2Heater[i] == deviceID) + { + index = i; + break; + } + if (index==MAX_HEATERS_NUM) + { + LOG_ERROR (deviceID, "No heater for device"); + return 0xFFFFFFFF; + } + // check if the read value is within the proportional band + if (ReadValue > (HeaterCmd[index].targettemperatue * (1+HeaterControl[index].outputproportionalband))) + { + //Heaters OFF until coming into the proportional band + len = usnprintf(str, 100, "\r\n HeaterControlCBFunction devId %d temp %d over proportional band %d of set temp %d " + ,index, ReadValue,HeaterControl[index].outputproportionalband,HeaterCmd[index].targettemperatue); + Report(str, __FILE__,__LINE__,0, RpMessage, index, deviceID); + return OK; + } + if (ReadValue < (HeaterCmd[index].targettemperatue * (1-HeaterControl[index].outputproportionalband))) + { + len = usnprintf(str, 100, "\r\n HeaterControlCBFunction devId %d temp %d below proportional band %d of set temp %d " + ,index, ReadValue,HeaterControl[index].outputproportionalband,HeaterCmd[index].targettemperatue); + Report(str, __FILE__,__LINE__,0, RpMessage, index, deviceID); + //Heaters ON until coming into the proportional band + return OK; + } + + if(HeaterPIDConfig[index].m_isEnabled && (HeaterPIDConfig[index].m_SetParam != 0)) + { + HeaterPIDConfig[index].m_mesuredParam = ReadValue; + HeaterPIDConfig[index].m_calculatedError = PIDAlgorithmCalculation(HeaterPIDConfig[index].m_SetParam , HeaterPIDConfig[index].m_mesuredParam, + &HeaterPIDConfig[index].m_params, &HeaterPIDConfig[index].m_preError, &HeaterPIDConfig[index].m_integral); + if (HeaterPIDConfig[index].m_calculatedError >= HeaterPIDConfig[index].m_params.MAX) + { + HeaterPIDConfig[index].m_calculatedError = HeaterPIDConfig[index].m_params.MAX; + } + if (HeaterPIDConfig[index].m_calculatedError < HeaterPIDConfig[index].m_params.MIN) + { + HeaterPIDConfig[index].m_calculatedError = HeaterPIDConfig[index].m_params.MIN; + } + + //SetMotorFreq (index, HeaterControl[index].m_calculatedError); + } + + return OK; +} + +/* + * EightMilliSecondHeatersInterrupt - a timer based interrupt, that will handle the time sharing between the A/C heaters + * There is a need to prevent the system from activating all A/C heaters at the same time, due to electrical current problems + */ +int SliceCounter = 0; +void EightMilliSecondHeatersInterrupt(UArg arg0) +{ + char str[100]; + uint8_t len = 0; + + len = usnprintf(str, 100, "\r\n EightMilliSecondHeatersInterrupt SliceCounter %d Owner %d H1000 %d H2000 %d" + ,SliceCounter,TimeSliceAllocation[SliceCounter],HeatersRestart,NumberOFSlicesInUse); + Report(str, __FILE__,__LINE__,0, RpMessage, SliceCounter, TimeSliceAllocation[SliceCounter]); + ROM_IntMasterDisable(); + + if (TimeSliceAllocation[SliceCounter] == HARDWARE_PID_CONTROL_TYPE__DryerHeater1000w) + { + //If HARDWARE_PID_CONTROL_TYPE__DryerHeater1000w should be active + //Activate HARDWARE_PID_CONTROL_TYPE__DryerHeater1000w + ActivateHeater (HARDWARE_PID_CONTROL_TYPE__DryerHeater1000w); + //DeActivate HARDWARE_PID_CONTROL_TYPE__DryerHeater200w1 + DeActivateHeater (HARDWARE_PID_CONTROL_TYPE__DryerHeater200w1); + DeActivateHeater (HARDWARE_PID_CONTROL_TYPE__DryerHeater200w2); + } + else if (TimeSliceAllocation[SliceCounter] == HARDWARE_PID_CONTROL_TYPE__DryerHeater200w1) + { + //DeActivate HARDWARE_PID_CONTROL_TYPE__DryerHeater1000w + DeActivateHeater (HARDWARE_PID_CONTROL_TYPE__DryerHeater1000w); + //If HARDWARE_PID_CONTROL_TYPE__DryerHeater200w1 should be active + //Activate HARDWARE_PID_CONTROL_TYPE__DryerHeater200w1 + ActivateHeater (HARDWARE_PID_CONTROL_TYPE__DryerHeater200w1); + ActivateHeater (HARDWARE_PID_CONTROL_TYPE__DryerHeater200w2); + } + else + { + //DeActivate HARDWARE_PID_CONTROL_TYPE__DryerHeater1000w + DeActivateHeater (HARDWARE_PID_CONTROL_TYPE__DryerHeater1000w); + //DeActivate HARDWARE_PID_CONTROL_TYPE__DryerHeater200w1 + DeActivateHeater (HARDWARE_PID_CONTROL_TYPE__DryerHeater200w1); + DeActivateHeater (HARDWARE_PID_CONTROL_TYPE__DryerHeater200w2); + } + //handle the time sharing module + SliceCounter++; + if (SliceCounter >= NumberOFSlicesInUse) + SliceCounter = 0; + + if (HeatersRestart == true) + { + ROM_TimerLoadSet(Heater_timerBase, TIMER_BOTH,OutputProportionalSingleStep/*twelve millisecond???*/); + } + + ROM_TimerIntClear(Heater_timerBase, TIMER_TIMA_TIMEOUT); // Clear the timer interrupt + // + // Enable all interrupts. + // + ROM_IntMasterEnable(); + return ; +} |
