Subversion Repositories HomeAutomation

Rev

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