Subversion Repositories HomeAutomation

Rev

Rev 2264 | Rev 2270 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | SVN | RSS feed

  1.  
  2. #include "act_PIDv1.h"
  3. #include <drivers/misc/PID_v1.h>
  4. #include <drivers/misc/PID_AutoTune.h>
  5.  
  6. #if act_PIDv1_USEEEPROM==1
  7. #include "act_PIDv1_eeprom.h"
  8. struct eeprom_act_PIDv1 EEMEM eeprom_act_PIDv1 =
  9. {
  10.     {
  11.         ///TODO: Define initialization values on the EEPROM variables here, this will generate a *.eep file that can be used to store this values to the node, can in future be done with a EEPROM module and the make-scrips. Write the values in the exact same order as the struct is defined in the *.h file.
  12.         0x00000000, // referenceValue
  13.         CAN_MODULE_TYPE_SNS_DS18X20,    //SensorModuleType
  14.         0x00,   //SensorModuleId
  15.         0x00,   //SensorId
  16.         0x00000000, //uint32_t K_P; (float)
  17.         0x00000000, //uint32_t K_I; (float)
  18.         0x00000000, //uint32_t K_D; (float)
  19.         0x00,   //uint8_t TimeMsOrS;
  20.         0x0000, //uint16_t Time;
  21.         CAN_MODULE_TYPE_ACT_SOFTPWM,    //ActuatorModuleType
  22.         0x00,   //ActuatorModuleId
  23.         0x00,   //ActuatorId
  24.         10, //SendPeriod
  25.     },
  26.     0   // crc, must be a correct value, but this will also be handled by the EEPROM module or make scripts
  27. };
  28. #endif
  29. #define PID_ON 1
  30. #define PID_OFF 0
  31. #define PID_AUTO 2
  32.  
  33. //! Parameters for regulator
  34. PidType pid;
  35.  
  36. //struct PID_DATA pidData;
  37. //struct PIDv1_DEBUG_DATA pidDebugData;
  38.  
  39. uint8_t sensorModuleType, sensorModuleId,sensorId;
  40. uint8_t PID_Status;
  41. uint8_t calculatePID_flag,sendPID_flag = 0;
  42. uint16_t pwmValue=0;
  43. float referenceValue, measurementValue, outputValue;
  44.  
  45. void sendPID(void)
  46. {
  47.     if (eeprom_read_byte(EEDATA.actuatorModuleType) != 0) {
  48.         StdCan_Msg_t txMsg;
  49.         StdCan_Set_class(txMsg.Header, CAN_MODULE_CLASS_ACT); ///TODO: Change this to the actual class type
  50.         StdCan_Set_direction(txMsg.Header, DIRECTIONFLAG_TO_OWNER);
  51.         txMsg.Header.ModuleType = eeprom_read_byte(EEDATA.actuatorModuleType); ///TODO: Change this to the actual module type
  52.         txMsg.Header.ModuleId = eeprom_read_byte(EEDATA.actuatorModuleId);
  53.         txMsg.Header.Command = CAN_MODULE_CMD_PHYSICAL_PWM;
  54.         txMsg.Length = 3;
  55.         txMsg.Data[0] = eeprom_read_byte(EEDATA.actuatorId);
  56.         //uint16_t tempPWM =(uint16_t) (pwmValue*10000);
  57.         txMsg.Data[1] = ( ((uint16_t)outputValue)>>8)&0xff;
  58.         txMsg.Data[2] = ( ((uint16_t)outputValue))&0xff;
  59.         while (StdCan_Put(&txMsg) != StdCan_Ret_OK);
  60.     }
  61.     StdCan_Msg_t txMsg;
  62.     StdCan_Set_class(txMsg.Header, CAN_MODULE_CLASS_ACT); ///TODO: Change this to the actual class type
  63.     StdCan_Set_direction(txMsg.Header, DIRECTIONFLAG_FROM_OWNER);
  64.     txMsg.Header.ModuleType = CAN_MODULE_TYPE_ACT_PID; ///TODO: Change this to the actual module type
  65.     txMsg.Header.ModuleId = act_PIDv1_ID;
  66.     txMsg.Header.Command = CAN_MODULE_CMD_PID_PID_STATUS;
  67.     txMsg.Length = 8;
  68.     txMsg.Data[0] = (uint8_t)0x00ff & (((uint32_t)(measurementValue*64))>>8);
  69.     txMsg.Data[1] = (uint8_t)0x00ff & ((uint32_t)(measurementValue*64));
  70.     txMsg.Data[2] = (uint8_t)0x00ff & (((uint32_t)(referenceValue*64))>>8);
  71.     txMsg.Data[3] = (uint8_t)0x00ff & ((uint32_t)(referenceValue*64));
  72.     //uint16_t tempPWM =(uint16_t) (pwmValue*10000);
  73.         txMsg.Data[4] = (uint8_t)( ((uint16_t)outputValue)>>8)&0xff;
  74.         txMsg.Data[5] = (uint8_t)( ((uint16_t)outputValue))&0xff;
  75.     txMsg.Data[6] = ((int16_t) (PID_GetITerm(&pid))>>8)&0xff;
  76.     txMsg.Data[7] = ((int16_t) (PID_GetITerm(&pid)))&0xff;
  77.     while (StdCan_Put(&txMsg) != StdCan_Ret_OK);
  78. }
  79.  
  80. void sendPID_callback(uint8_t timer) {
  81.   sendPID_flag=1;
  82. }
  83.  
  84. #ifdef act_PIDv1_SEND_DEBUG_TIMER
  85. void sendPID_debug_callback(uint8_t timer)
  86. {
  87.    
  88.     StdCan_Msg_t txMsg;
  89.     StdCan_Set_class(txMsg.Header, CAN_MODULE_CLASS_ACT); ///TODO: Change this to the actual class type
  90.     StdCan_Set_direction(txMsg.Header, DIRECTIONFLAG_FROM_OWNER);
  91.     txMsg.Header.ModuleType = CAN_MODULE_TYPE_ACT_PID; ///TODO: Change this to the actual module type
  92.     txMsg.Header.ModuleId = act_PIDv1_ID;
  93.     txMsg.Header.Command = CAN_MODULE_CMD_PID_DEBUG;
  94.     txMsg.Length = 8;
  95.  
  96.     txMsg.Data[0] = ((int16_t) (PID_GetPTerm(&pid))>>8)&0xff;
  97.     txMsg.Data[1] = ((int16_t) (PID_GetPTerm(&pid)))&0xff;
  98.     txMsg.Data[2] = ((int16_t) (PID_GetITerm(&pid))>>8)&0xff;
  99.     txMsg.Data[3] = ((int16_t) (PID_GetITerm(&pid)))&0xff;
  100.     txMsg.Data[4] = ((int16_t) (PID_GetDTerm(&pid))>>8)&0xff;
  101.     txMsg.Data[5] = ((int16_t) (PID_GetDTerm(&pid)))&0xff;
  102.     //txMsg.Data[6] = ((int16_t) (pidDebugData.Sum)>>8)&0xff;
  103.     //txMsg.Data[7] = ((int16_t) (pidDebugData.Sum))&0xff;
  104.     txMsg.Data[6] = 0;
  105.     txMsg.Data[7] = 0;
  106.     while (StdCan_Put(&txMsg) != StdCan_Ret_OK);
  107.    
  108.     StdCan_Set_class(txMsg.Header, CAN_MODULE_CLASS_ACT);
  109.     StdCan_Set_direction(txMsg.Header, DIRECTIONFLAG_FROM_OWNER);
  110.     txMsg.Header.ModuleType = CAN_MODULE_TYPE_ACT_PID;
  111.     txMsg.Header.ModuleId = act_PIDv1_ID;
  112.     txMsg.Header.Command = CAN_MODULE_CMD_PID_P_I_TERM;
  113.     txMsg.Length = 8;
  114.     FloatType data = PID_GetPTerm(&pid);
  115.     data = 1.0f;
  116.     uint8_t *ptr;
  117.     ptr = (uint8_t*)&data;
  118.     txMsg.Data[0] = ptr[0];
  119.     txMsg.Data[1] = ptr[1];
  120.     txMsg.Data[2] = ptr[2];
  121.     txMsg.Data[3] = ptr[3];
  122.     data = PID_GetITerm(&pid);
  123.     data = -2.0f;
  124.     ptr = (uint8_t*)&data;
  125.     txMsg.Data[4] = ptr[0];
  126.     txMsg.Data[5] = ptr[1];
  127.     txMsg.Data[6] = ptr[2];
  128.     txMsg.Data[7] = ptr[3];
  129.     while (StdCan_Put(&txMsg) != StdCan_Ret_OK);
  130.    
  131.     StdCan_Set_class(txMsg.Header, CAN_MODULE_CLASS_ACT);
  132.     StdCan_Set_direction(txMsg.Header, DIRECTIONFLAG_FROM_OWNER);
  133.     txMsg.Header.ModuleType = CAN_MODULE_TYPE_ACT_PID;
  134.     txMsg.Header.ModuleId = act_PIDv1_ID;
  135.     txMsg.Header.Command = CAN_MODULE_CMD_PID_D_TERM_OUT;
  136.     txMsg.Length = 8;
  137.     data = PID_GetDTerm(&pid);
  138.     ptr = (uint8_t*)&data;
  139.     txMsg.Data[0] = ptr[0];
  140.     txMsg.Data[1] = ptr[1];
  141.     txMsg.Data[2] = ptr[2];
  142.     txMsg.Data[3] = ptr[3];
  143.     ptr = (uint8_t*)&outputValue;
  144.     txMsg.Data[4] = ptr[0];
  145.     txMsg.Data[5] = ptr[1];
  146.     txMsg.Data[6] = ptr[2];
  147.     txMsg.Data[7] = ptr[3];
  148.     while (StdCan_Put(&txMsg) != StdCan_Ret_OK);   
  149.    
  150. //printf("PID: P:%d, I:%d, D:%d, S:%d\n",(int16_t)pidDebugData.P_term,(int16_t)pidDebugData.I_term,(int16_t)pidDebugData.D_term,(int16_t)pidDebugData.Sum);
  151. }
  152. #endif
  153. void act_PIDv1_Init(void)
  154. {
  155. #if act_PIDv1_USEEEPROM==1
  156.     if (EEDATA_OK)
  157.     {
  158.     } else
  159.     {   //The CRC of the EEPROM is not correct, store default values and update CRC
  160.       eeprom_write_dword_crc(EEDATA32.referenceValue, 20.0f, WITHOUT_CRC);
  161.       eeprom_write_byte_crc(EEDATA.sensorModuleType, PIDv1_TEMPERATURE_SENSOR_MODULE_TYPE, WITHOUT_CRC);
  162.       eeprom_write_byte_crc(EEDATA.sensorModuleId, PIDv1_TEMPERATURE_SENSOR_MODULE_ID, WITHOUT_CRC);
  163.       eeprom_write_byte_crc(EEDATA.sensorId, PIDv1_TEMPERATURE_SENSOR, WITHOUT_CRC);
  164.       eeprom_write_dword_crc(EEDATA32.K_P, 850.0f, WITHOUT_CRC);
  165.       eeprom_write_dword_crc(EEDATA32.K_I, 0.5f, WITHOUT_CRC);
  166.       eeprom_write_dword_crc(EEDATA32.K_D, 0.1f, WITHOUT_CRC);
  167.       eeprom_write_byte_crc(EEDATA.TimeMsOrS, DEFAULT_PIDv1_CALC_PERIOD_UNIT, WITHOUT_CRC);
  168.       eeprom_write_word_crc(EEDATA16.Time, DEFAULT_PIDv1_CALC_PERIOD, WITHOUT_CRC);
  169.       eeprom_write_byte_crc(EEDATA.actuatorModuleType, PIDv1_PWM_ACTUATOR_MODULE_TYPE, WITHOUT_CRC);
  170.       eeprom_write_byte_crc(EEDATA.actuatorModuleId, PIDv1_PWM_ACTUATOR_MODULE_ID, WITHOUT_CRC);
  171.       eeprom_write_byte_crc(EEDATA.actuatorId, PIDv1_PWM_ACTUATOR, WITHOUT_CRC);
  172.       eeprom_write_byte_crc(EEDATA.sendPeriod, 10, WITHOUT_CRC);
  173.       EEDATA_UPDATE_CRC;
  174.     }
  175.    
  176. #else
  177. #error this driver needs EEPROM support
  178. #endif
  179.    
  180.     referenceValue = (float) eeprom_read_dword(EEDATA32.referenceValue);
  181.     sensorModuleType = eeprom_read_byte(EEDATA.sensorModuleType);
  182.     sensorModuleId = eeprom_read_byte(EEDATA.sensorModuleId);
  183.     sensorId = eeprom_read_byte(EEDATA.sensorId);
  184.    
  185.     PID_init(&pid, &measurementValue, &outputValue, &referenceValue, (float) eeprom_read_dword(EEDATA32.K_P), (float) eeprom_read_dword(EEDATA32.K_I), (float) eeprom_read_dword(EEDATA32.K_D), PID_Direction_Direct);
  186.  
  187.     if (eeprom_read_byte(EEDATA.TimeMsOrS) == CAN_MODULE_ENUM_PID_CONFIG_PARAMETER_TIMEUNIT_S) {
  188.         PID_SetSampleTime(&pid, (uint32_t)(eeprom_read_word(EEDATA16.Time))*1000);
  189.     } else {
  190.         PID_SetSampleTime(&pid, (uint32_t)(eeprom_read_word(EEDATA16.Time)));
  191.     }
  192.  
  193.     outputValue = DEFAULT_PWM_VALUE;
  194.  
  195.     PID_SetMode(&pid, PID_Mode_Automatic);
  196.    
  197.     Timer_SetTimeout(act_PIDv1_SEND_TIMER, eeprom_read_byte(EEDATA.sendPeriod)*1000, TimerTypeFreeRunning, &sendPID_callback);
  198.     #ifdef act_PIDv1_SEND_DEBUG_TIMER
  199.       Timer_SetTimeout(act_PIDv1_SEND_DEBUG_TIMER, PIDv1_SEND_DEBUG_PERIOD, TimerTypeFreeRunning, &sendPID_debug_callback);
  200.     #endif
  201. }
  202.  
  203. void act_PIDv1_Process(void)
  204. {
  205.     PID_Compute(&pid);
  206.    
  207.     if (sendPID_flag) {
  208.         sendPID();
  209.         sendPID_flag= 0;
  210.     }
  211. }
  212.  
  213. void act_PIDv1_HandleMessage(StdCan_Msg_t *rxMsg)
  214. {
  215.     FloatType data2;
  216.     uint8_t *ptr;
  217.     if (    StdCan_Ret_class(rxMsg->Header) == CAN_MODULE_CLASS_ACT &&
  218.             StdCan_Ret_direction(rxMsg->Header) == DIRECTIONFLAG_TO_OWNER &&
  219.             rxMsg->Header.ModuleType == CAN_MODULE_TYPE_ACT_PID &&
  220.             rxMsg->Header.ModuleId == act_PIDv1_ID)
  221.     {
  222.         switch (rxMsg->Header.Command)
  223.         {
  224.         case CAN_MODULE_CMD_PHYSICAL_TEMPERATURE_CELSIUS:
  225.             if (rxMsg->Data[0]==0)  //sensor id shall be zero
  226.             {
  227.                 printf("New setpoint with: %X %X\n",rxMsg->Data[1],rxMsg->Data[2]);
  228.  
  229.                 if (rxMsg->Length == 3)
  230.                 {
  231.                     if (0x80 == rxMsg->Data[1] && 0x00 == rxMsg->Data[2]) //512 degrees
  232.                     {
  233.                         //pid_Reset_Integrator(&pidData);
  234.                         PID_Status = PID_AUTO;
  235.                     }
  236.                     else
  237.                     {
  238.                         //pid_Reset_Integrator(&pidData);
  239.                         referenceValue = (((float)((rxMsg->Data[1]<<8) + rxMsg->Data[2]))/64);
  240.                         eeprom_write_dword_crc(EEDATA32.referenceValue, referenceValue, WITH_CRC);
  241.                     }
  242.                 }
  243.                 rxMsg->Data[1] = (uint8_t)0x00ff & (((uint32_t)(referenceValue*64))>>8);
  244.                 rxMsg->Data[2] = (uint8_t)0x00ff & ((uint32_t)referenceValue*64);
  245.                 StdCan_Set_direction(rxMsg->Header, DIRECTIONFLAG_FROM_OWNER);
  246.                 rxMsg->Length = 3;
  247.                 while (StdCan_Put(rxMsg) != StdCan_Ret_OK);
  248.             }
  249.         break;
  250.         case CAN_MODULE_CMD_PID_CONFIG_SENSOR:
  251.             if (rxMsg->Length == 3)
  252.             {
  253.                 eeprom_write_byte_crc(EEDATA.sensorModuleType, rxMsg->Data[0] , WITHOUT_CRC);
  254.                 eeprom_write_byte_crc(EEDATA.sensorModuleId, rxMsg->Data[1] , WITHOUT_CRC);
  255.                 eeprom_write_byte_crc(EEDATA.sensorId, rxMsg->Data[2] , WITH_CRC);
  256.                 sensorModuleType = eeprom_read_byte(EEDATA.sensorModuleType);
  257.                 sensorModuleId = eeprom_read_byte(EEDATA.sensorModuleId);
  258.                 sensorId = eeprom_read_byte(EEDATA.sensorId);
  259.             }
  260.             rxMsg->Data[0] = eeprom_read_byte(EEDATA.sensorModuleType);
  261.             rxMsg->Data[1] = eeprom_read_byte(EEDATA.sensorModuleId);
  262.             rxMsg->Data[2] = eeprom_read_byte(EEDATA.sensorId);
  263.             StdCan_Set_direction(rxMsg->Header, DIRECTIONFLAG_FROM_OWNER);
  264.             rxMsg->Length = 3;
  265.             while (StdCan_Put(rxMsg) != StdCan_Ret_OK);
  266.         break;
  267.         case CAN_MODULE_CMD_PID_CONFIG_ACTUATOR:
  268.             if (rxMsg->Length == 3)
  269.             {
  270.                 eeprom_write_byte_crc(EEDATA.actuatorModuleType, rxMsg->Data[0] , WITHOUT_CRC);
  271.                 eeprom_write_byte_crc(EEDATA.actuatorModuleId, rxMsg->Data[1] , WITHOUT_CRC);
  272.                 eeprom_write_byte_crc(EEDATA.actuatorId, rxMsg->Data[2] , WITH_CRC);
  273.             }
  274.             rxMsg->Data[0] = eeprom_read_byte(EEDATA.actuatorModuleType);
  275.             rxMsg->Data[1] = eeprom_read_byte(EEDATA.actuatorModuleId);
  276.             rxMsg->Data[2] = eeprom_read_byte(EEDATA.actuatorId);
  277.             StdCan_Set_direction(rxMsg->Header, DIRECTIONFLAG_FROM_OWNER);
  278.             rxMsg->Length = 3;
  279.             while (StdCan_Put(rxMsg) != StdCan_Ret_OK);
  280.         break;
  281.         case CAN_MODULE_CMD_GLOBAL_REPORT_INTERVAL:
  282.             if (rxMsg->Length == 1) {
  283.                 if (65 <= rxMsg->Data[0])
  284.                     rxMsg->Data[0]=65;
  285.                 if (0 == rxMsg->Data[0])
  286.                     rxMsg->Data[0]=1;
  287.                 eeprom_write_byte_crc(EEDATA.sendPeriod, rxMsg->Data[0], WITH_CRC);
  288.                 Timer_SetTimeout(act_PIDv1_SEND_TIMER, rxMsg->Data[0]*1000, TimerTypeFreeRunning, &sendPID_callback);
  289.                 StdCan_Set_direction(rxMsg->Header, DIRECTIONFLAG_FROM_OWNER);
  290.                 while (StdCan_Put(rxMsg) != StdCan_Ret_OK);
  291.             }
  292.         break;
  293.  
  294.         case CAN_MODULE_CMD_PID_CONFIG_PARAMETER:
  295.             if (rxMsg->Length == 8)
  296.             {
  297.                 eeprom_write_dword_crc(EEDATA32.K_P, (((float)((rxMsg->Data[0]<<8) + rxMsg->Data[1]))/64), WITHOUT_CRC);
  298.                 eeprom_write_dword_crc(EEDATA32.K_I, (((float)((rxMsg->Data[2]<<8) + rxMsg->Data[3]))/64), WITHOUT_CRC);
  299.                 eeprom_write_dword_crc(EEDATA32.K_D, (((float)((rxMsg->Data[4]<<8) + rxMsg->Data[5]))/64), WITHOUT_CRC);
  300.                 eeprom_write_byte_crc(EEDATA.TimeMsOrS, ((rxMsg->Data[6]&0x80)>>7), WITHOUT_CRC);
  301.                 eeprom_write_word_crc(EEDATA16.Time, (uint16_t)rxMsg->Data[7]+((rxMsg->Data[6]&0x7f)<<8), WITH_CRC);
  302.                 if (eeprom_read_byte(EEDATA.TimeMsOrS) == 0) {
  303.                     //Timer_SetTimeout(act_PIDv1_TIMER, 1000, TimerTypeFreeRunning, &calculatePID_callback);
  304.                 } else {
  305.                     //Timer_SetTimeout(act_PIDv1_TIMER, eeprom_read_word(EEDATA16.Time), TimerTypeFreeRunning, &calculatePID_callback);
  306.                 }
  307.                 PID_SetTunings(&pid, (float) eeprom_read_dword(EEDATA32.K_P), (float) eeprom_read_dword(EEDATA32.K_I), (float) eeprom_read_dword(EEDATA32.K_D));
  308.                 PID_Status = PID_ON;
  309.                 pwmValue = DEFAULT_PWM_VALUE;
  310.             }
  311.             rxMsg->Data[0] = ((int16_t) (PID_GetKp(&pid))>>8)&0xff;
  312.             rxMsg->Data[1] = ((int16_t) (PID_GetKp(&pid)))&0xff;
  313.             rxMsg->Data[2] = ((int16_t) (PID_GetKi(&pid))>>8)&0xff;
  314.             rxMsg->Data[3] = ((int16_t) (PID_GetKi(&pid)))&0xff;
  315.             rxMsg->Data[4] = ((int16_t) (PID_GetKd(&pid))>>8)&0xff;
  316.             rxMsg->Data[5] = ((int16_t) (PID_GetKd(&pid)))&0xff;
  317.             rxMsg->Data[6] = (0x7f&(eeprom_read_word(EEDATA16.Time)>>8));
  318.             rxMsg->Data[7] = (0xff&(eeprom_read_word(EEDATA16.Time)));
  319.             rxMsg->Data[6] |= (0x80&(eeprom_read_byte(EEDATA.TimeMsOrS))<<7);
  320.             StdCan_Set_direction(rxMsg->Header, DIRECTIONFLAG_FROM_OWNER);
  321.             rxMsg->Length = 8;
  322.             while (StdCan_Put(rxMsg) != StdCan_Ret_OK);
  323.         break;
  324.        
  325.         case CAN_MODULE_CMD_PID_CONFIG_PARAMETER_D_T:
  326.             if (rxMsg->Length == 8)
  327.             {
  328.                 float *data = (float*)&rxMsg->Data[0];
  329.                
  330.                 eeprom_write_dword_crc(EEDATA32.K_D, *data, WITHOUT_CRC);
  331.                 eeprom_write_byte_crc(EEDATA.TimeMsOrS, ((rxMsg->Data[6]&0x80)>>7), WITHOUT_CRC);
  332.                 eeprom_write_word_crc(EEDATA16.Time, (uint16_t)rxMsg->Data[7]+((rxMsg->Data[6]&0x7f)<<8), WITH_CRC);
  333.                 PID_SetTunings(&pid, PID_GetKp(&pid), PID_GetKi(&pid), (float) eeprom_read_dword(EEDATA32.K_D));
  334.                 PID_Status = PID_ON;
  335.                 pwmValue = DEFAULT_PWM_VALUE;
  336.             }
  337.             data2 = PID_GetKd(&pid);
  338.             ptr = (uint8_t*)&data2;
  339.             rxMsg->Data[0] = ptr[0];
  340.             rxMsg->Data[1] = ptr[1];
  341.             rxMsg->Data[2] = ptr[2];
  342.             rxMsg->Data[3] = ptr[3];
  343.             rxMsg->Data[4] = 0u;
  344.             rxMsg->Data[5] = 0u;
  345.             rxMsg->Data[6] = (0x7f&(eeprom_read_word(EEDATA16.Time)>>8));
  346.             rxMsg->Data[7] = (0xff&(eeprom_read_word(EEDATA16.Time)));
  347.             rxMsg->Data[6] |= (0x80&(eeprom_read_byte(EEDATA.TimeMsOrS))<<7);
  348.            
  349.             StdCan_Set_direction(rxMsg->Header, DIRECTIONFLAG_FROM_OWNER);
  350.             rxMsg->Length = 8;
  351.             while (StdCan_Put(rxMsg) != StdCan_Ret_OK);
  352.         break;
  353.         case CAN_MODULE_CMD_PID_CONFIG_PARAMETER_P_I:
  354.             if (rxMsg->Length == 8)
  355.             {
  356.                 float *data = (float*)&rxMsg->Data[0];
  357.                
  358.                 eeprom_write_dword_crc(EEDATA32.K_P, *data, WITHOUT_CRC);
  359.                 data = (float*)&rxMsg->Data[4];
  360.                 eeprom_write_dword_crc(EEDATA32.K_I, *data, WITH_CRC);
  361.                
  362.                 PID_SetTunings(&pid, (float) eeprom_read_dword(EEDATA32.K_P), (float) eeprom_read_dword(EEDATA32.K_I), PID_GetKd(&pid));
  363.                 PID_Status = PID_ON;
  364.                 pwmValue = DEFAULT_PWM_VALUE;
  365.             }
  366.             data2 = PID_GetKp(&pid);
  367.             ptr = (uint8_t*)&data2;
  368.             rxMsg->Data[0] = ptr[0];
  369.             rxMsg->Data[1] = ptr[1];
  370.             rxMsg->Data[2] = ptr[2];
  371.             rxMsg->Data[3] = ptr[3];
  372.             data2 = PID_GetKi(&pid);
  373.             ptr = (uint8_t*)&data2;
  374.             rxMsg->Data[4] = ptr[0];
  375.             rxMsg->Data[5] = ptr[1];
  376.             rxMsg->Data[6] = ptr[2];
  377.             rxMsg->Data[7] = ptr[3];
  378.             StdCan_Set_direction(rxMsg->Header, DIRECTIONFLAG_FROM_OWNER);
  379.             rxMsg->Length = 8;
  380.             while (StdCan_Put(rxMsg) != StdCan_Ret_OK);
  381.         break;
  382.         }
  383.     }
  384.  
  385.  
  386.     if (    StdCan_Ret_class(rxMsg->Header) == CAN_MODULE_CLASS_SNS &&
  387.                 StdCan_Ret_direction(rxMsg->Header) == DIRECTIONFLAG_FROM_OWNER &&
  388.                 rxMsg->Header.ModuleType == sensorModuleType &&
  389.                 rxMsg->Header.ModuleId == sensorModuleId &&
  390.                 rxMsg->Header.Command == CAN_MODULE_CMD_PHYSICAL_TEMPERATURE_CELSIUS &&
  391.                 rxMsg->Data[0] == sensorId)
  392.         {
  393.             if (0x80 == rxMsg->Data[1] && 0x00 == rxMsg->Data[2])
  394.             {
  395.                 //Error on the temperature signal, do something
  396.             }
  397.             else
  398.             {
  399.                 measurementValue = ((float)((rxMsg->Data[1]<<8) + rxMsg->Data[2]))/64;
  400.             }
  401.  
  402.         }
  403. }
  404.  
  405. void act_PIDv1_List(uint8_t ModuleSequenceNumber)
  406. {
  407.     StdCan_Msg_t txMsg;
  408.  
  409.     StdCan_Set_class(txMsg.Header, CAN_MODULE_CLASS_ACT); ///TODO: Change this to the actual class type
  410.     StdCan_Set_direction(txMsg.Header, DIRECTIONFLAG_FROM_OWNER);
  411.     txMsg.Header.ModuleType = CAN_MODULE_TYPE_ACT_PID; ///TODO: Change this to the actual module type
  412.     txMsg.Header.ModuleId = act_PIDv1_ID;
  413.     txMsg.Header.Command = CAN_MODULE_CMD_GLOBAL_LIST;
  414.     txMsg.Length = 6;
  415.  
  416.     uint32_t HwId=BIOS_GetHwId();
  417.     txMsg.Data[0] = HwId&0xff;
  418.     txMsg.Data[1] = (HwId>>8)&0xff;
  419.     txMsg.Data[2] = (HwId>>16)&0xff;
  420.     txMsg.Data[3] = (HwId>>24)&0xff;
  421.  
  422.     txMsg.Data[4] = NUMBER_OF_MODULES;
  423.     txMsg.Data[5] = ModuleSequenceNumber;
  424.  
  425.     while (StdCan_Put(&txMsg) != StdCan_Ret_OK);
  426. }
  427.