Subversion Repositories HomeAutomation

Rev

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

  1.  
  2. #include "act_PID_eeprom.h"
  3.  
  4. #include "act_PID.h"
  5. #include <drivers/misc/pid.h>
  6.  
  7. #define PID_ON 1
  8. #define PID_OFF 0
  9. #define PID_AUTO 2
  10.  
  11. //! Parameters for regulator
  12. struct PID_DATA pidData;
  13. struct PID_DEBUG_DATA pidDebugData;
  14.  
  15. uint8_t sensorModuleType, sensorModuleId,sensorId;
  16. uint8_t PID_Status;
  17. uint8_t calculatePID_flag,sendPID_flag = 0;
  18. uint16_t pwmValue=0;
  19. float referenceValue, measurementValue, inputValue;
  20.  
  21. struct eeprom_act_PID EEMEM eeprom_act_PID =
  22. {
  23.     {
  24.         ///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.
  25.         0x0200, // referenceValue
  26.         0x00,   //SensorModuleType
  27.         0x00,   //SensorModuleId
  28.         0x00    //SensorId
  29.     },
  30.     0   // crc, must be a correct value, but this will also be handled by the EEPROM module or make scripts
  31. };
  32.  
  33. void calculatePID(void) {
  34.     if (PID_Status == PID_OFF){
  35.         ;// use current PWMvalue
  36.     } else {
  37.         pwmValue += (int16_t) pid_Controller(referenceValue, measurementValue, &pidData, &pidDebugData);
  38.        
  39.         if (pwmValue < MIN_PWM_VALUE) {
  40.             pwmValue = MIN_PWM_VALUE;
  41.         }
  42.         else if (pwmValue > MAX_PWM_VALUE) {
  43.             pwmValue = MAX_PWM_VALUE-1;
  44.         }
  45.         //send current PWM value as soon as possible
  46.         sendPID_flag=1;
  47.     }
  48. }
  49.  
  50.  
  51. void calculatePID_callback(uint8_t timer)
  52. {
  53.     #ifdef PID_CALC_PERIOD_SECONDS
  54.     static uint8_t seconds = 0;
  55.     seconds++;
  56.     if (seconds >= PID_CALC_PERIOD_SECONDS)
  57.     {
  58.       seconds = 0;
  59.       calculatePID_flag = 1;
  60.     }
  61.     #else
  62.     calculatePID_flag = 1;
  63.     #endif
  64. }
  65.  
  66. void sendPID(void)
  67. {
  68.     StdCan_Msg_t txMsg;
  69.     StdCan_Set_class(txMsg.Header, CAN_MODULE_CLASS_ACT); ///TODO: Change this to the actual class type
  70.     StdCan_Set_direction(txMsg.Header, DIRECTIONFLAG_FROM_OWNER);
  71.     txMsg.Header.ModuleType = CAN_MODULE_TYPE_ACT_PID; ///TODO: Change this to the actual module type
  72.     txMsg.Header.ModuleId = act_PID_ID;
  73.     txMsg.Header.Command = CAN_MODULE_CMD_PHYSICAL_PWM;
  74.     txMsg.Length = 3;
  75.     txMsg.Data[0] = PWM_ID;
  76.     txMsg.Data[1] = ((int16_t) (pwmValue)>>8)&0xff;
  77.     txMsg.Data[2] = ((int16_t) (pwmValue))&0xff;
  78.    
  79.     StdCan_Put(&txMsg);
  80. }
  81.  
  82. void sendPID_callback(uint8_t timer) {
  83.   sendPID_flag=1;
  84. }
  85.  
  86. #ifdef act_PID_SEND_DEBUG_TIMER
  87. void sendPID_debug_callback(uint8_t timer)
  88. {
  89.     StdCan_Msg_t txMsg;
  90.     StdCan_Set_class(txMsg.Header, CAN_MODULE_CLASS_ACT); ///TODO: Change this to the actual class type
  91.     StdCan_Set_direction(txMsg.Header, DIRECTIONFLAG_FROM_OWNER);
  92.     txMsg.Header.ModuleType = CAN_MODULE_TYPE_ACT_PID; ///TODO: Change this to the actual module type
  93.     txMsg.Header.ModuleId = act_PID_ID;
  94.     txMsg.Header.Command = CAN_MODULE_CMD_PID_DEBUG;
  95.     txMsg.Length = 8;
  96.  
  97.     txMsg.Data[0] = ((int16_t) (pidDebugData.P_term)>>8)&0xff;
  98.     txMsg.Data[1] = ((int16_t) (pidDebugData.P_term))&0xff;
  99.     txMsg.Data[2] = ((int16_t) (pidDebugData.I_term)>>8)&0xff;
  100.     txMsg.Data[3] = ((int16_t) (pidDebugData.I_term))&0xff;
  101.     txMsg.Data[4] = ((int16_t) (pidDebugData.D_term)>>8)&0xff;
  102.     txMsg.Data[5] = ((int16_t) (pidDebugData.D_term))&0xff;
  103.     txMsg.Data[6] = ((int16_t) (pidDebugData.Sum)>>8)&0xff;
  104.     txMsg.Data[7] = ((int16_t) (pidDebugData.Sum))&0xff;
  105.     StdCan_Put(&txMsg);
  106. }
  107. #endif
  108.  
  109. void act_PID_Init(void)
  110. {
  111.     if (EEDATA_OK)
  112.     {
  113.     } else
  114.     {   //The CRC of the EEPROM is not correct, store default values and update CRC
  115.       eeprom_write_word_crc(EEDATA16.referenceValue, 0x0200, WITHOUT_CRC);
  116.       eeprom_write_byte_crc(EEDATA.sensorModuleType, PID_TEMPERATURE_SENSOR_MODULE_TYPE, WITHOUT_CRC);
  117.       eeprom_write_byte_crc(EEDATA.sensorModuleId, PID_TEMPERATURE_SENSOR_MODULE_ID, WITHOUT_CRC);
  118.       eeprom_write_byte_crc(EEDATA.sensorId, PID_TEMPERATURE_SENSOR, WITH_CRC);
  119.     }
  120.     referenceValue = (float) eeprom_read_word(EEDATA16.referenceValue)/64;
  121.     sensorModuleType = eeprom_read_byte(EEDATA.sensorModuleType);
  122.     sensorModuleId = eeprom_read_byte(EEDATA.sensorModuleId);
  123.     sensorId = eeprom_read_byte(EEDATA.sensorId);
  124.  
  125.     #ifdef PID_CALC_PERIOD_SECONDS
  126.     Timer_SetTimeout(act_PID_TIMER, 1000, TimerTypeFreeRunning, &calculatePID_callback);
  127.     #else
  128.     Timer_SetTimeout(act_PID_TIMER, PID_CALC_PERIOD_mSECONDS, TimerTypeFreeRunning, &calculatePID_callback);
  129.     #endif
  130.  
  131.     pid_Init(K_P * SCALING_FACTOR, K_I * SCALING_FACTOR , K_D * SCALING_FACTOR , &pidData);
  132.     pwmValue += (int16_t) pid_Controller(referenceValue, measurementValue, &pidData, &pidDebugData);
  133.     PID_Status = PID_ON;
  134.     pwmValue = DEFAULT_PWM_VALUE;
  135.     Timer_SetTimeout(act_PID_SEND_TIMER, PID_SEND_PERIOD, TimerTypeFreeRunning, &sendPID_callback);
  136.     #ifdef act_PID_SEND_DEBUG_TIMER
  137.       Timer_SetTimeout(act_PID_SEND_DEBUG_TIMER, PID_SEND_DEBUG_PERIOD, TimerTypeFreeRunning, &sendPID_debug_callback);
  138.     #endif
  139. }
  140.  
  141. void act_PID_Process(void)
  142. {
  143.     if (calculatePID_flag) {
  144.         calculatePID();
  145.         calculatePID_flag = 0;
  146.     }
  147.     if (sendPID_flag) {
  148.         sendPID();
  149.     }
  150. }
  151.  
  152. void act_PID_HandleMessage(StdCan_Msg_t *rxMsg)
  153. {
  154.  
  155.     if (    StdCan_Ret_class(rxMsg->Header) == CAN_MODULE_CLASS_ACT &&
  156.             StdCan_Ret_direction(rxMsg->Header) == DIRECTIONFLAG_TO_OWNER &&
  157.             rxMsg->Header.ModuleType == CAN_MODULE_TYPE_ACT_PID &&
  158.             rxMsg->Header.ModuleId == act_PID_ID)
  159.     {
  160.         switch (rxMsg->Header.Command)
  161.         {
  162.         case CAN_MODULE_CMD_PHYSICAL_TEMPERATURE_CELSIUS:
  163.             if (rxMsg->Data[0]==0)  //sensor id shall be zero
  164.             {
  165.                 if (rxMsg->Length == 3)
  166.                 {
  167.                     if (0x80 == rxMsg->Data[1] && 0x00 == rxMsg->Data[2])
  168.                     {
  169.                         pid_Reset_Integrator(&pidData);
  170.                         PID_Status = PID_AUTO;
  171.                     }
  172.                     else
  173.                     {
  174.                         pid_Reset_Integrator(&pidData);
  175.                         eeprom_write_word_crc(EEDATA16.referenceValue, ((rxMsg->Data[1]<<8) + rxMsg->Data[2]), WITH_CRC);
  176.                         referenceValue = ((rxMsg->Data[1]<<8) + rxMsg->Data[2])/64;
  177.                     }
  178.                 } else
  179.                 {
  180.                     rxMsg->Data[1] = (uint8_t)0x00ff & (((uint32_t)(referenceValue*64))>>8);
  181.                     rxMsg->Data[2] = (uint8_t)0x00ff & ((uint32_t)referenceValue*64);
  182.                     StdCan_Set_direction(rxMsg->Header, DIRECTIONFLAG_FROM_OWNER);
  183.                     rxMsg->Length = 3;
  184.                     while (StdCan_Put(rxMsg) != StdCan_Ret_OK);
  185.                 }
  186.  
  187.             }
  188.         break;
  189.         case CAN_MODULE_CMD_PID_CONFIG:
  190.             if (rxMsg->Length == 3)
  191.             {
  192.                 eeprom_write_byte_crc(EEDATA.sensorModuleType, rxMsg->Data[0] , WITHOUT_CRC);
  193.                 eeprom_write_byte_crc(EEDATA.sensorModuleId, rxMsg->Data[1] , WITHOUT_CRC);
  194.                 eeprom_write_byte_crc(EEDATA.sensorId, rxMsg->Data[2] , WITH_CRC);
  195.                 sensorModuleType = eeprom_read_byte(EEDATA.sensorModuleType);
  196.                 sensorModuleId = eeprom_read_byte(EEDATA.sensorModuleId);
  197.                 sensorId = eeprom_read_byte(EEDATA.sensorId);
  198.             } else
  199.             {
  200.                 rxMsg->Data[0] = eeprom_read_byte(EEDATA.sensorModuleType);
  201.                 rxMsg->Data[1] = eeprom_read_byte(EEDATA.sensorModuleId);
  202.                 rxMsg->Data[2] = eeprom_read_byte(EEDATA.sensorId);
  203.                 StdCan_Set_direction(rxMsg->Header, DIRECTIONFLAG_FROM_OWNER);
  204.                 rxMsg->Length = 3;
  205.                 while (StdCan_Put(rxMsg) != StdCan_Ret_OK);
  206.             }
  207.         break;
  208.         }
  209.     }
  210.  
  211.  
  212.     if (    StdCan_Ret_class(rxMsg->Header) == CAN_MODULE_CLASS_SNS &&
  213.                 StdCan_Ret_direction(rxMsg->Header) == DIRECTIONFLAG_FROM_OWNER &&
  214.                 rxMsg->Header.ModuleType == sensorModuleType &&
  215.                 rxMsg->Header.ModuleId == sensorModuleId &&
  216.                 rxMsg->Header.Command == CAN_MODULE_CMD_PHYSICAL_TEMPERATURE_CELSIUS &&
  217.                 rxMsg->Data[0] == sensorId)
  218.         {
  219.             if (0x80 == rxMsg->Data[1] && 0x00 == rxMsg->Data[2])
  220.             {
  221.                 //Error on the temperature signal, do something
  222.             }
  223.             else
  224.             {
  225.                 measurementValue = ((rxMsg->Data[1]<<8) + rxMsg->Data[2])/64;
  226.             }
  227.  
  228.         }
  229.  
  230. }
  231.  
  232. void act_PID_List(uint8_t ModuleSequenceNumber)
  233. {
  234.     StdCan_Msg_t txMsg;
  235.    
  236.     StdCan_Set_class(txMsg.Header, CAN_MODULE_CLASS_ACT); ///TODO: Change this to the actual class type
  237.     StdCan_Set_direction(txMsg.Header, DIRECTIONFLAG_FROM_OWNER);
  238.     txMsg.Header.ModuleType = CAN_MODULE_TYPE_ACT_PID; ///TODO: Change this to the actual module type
  239.     txMsg.Header.ModuleId = act_PID_ID;
  240.     txMsg.Header.Command = CAN_MODULE_CMD_GLOBAL_LIST;
  241.     txMsg.Length = 6;
  242.  
  243.     txMsg.Data[0] = NODE_HW_ID_BYTE0;
  244.     txMsg.Data[1] = NODE_HW_ID_BYTE1;
  245.     txMsg.Data[2] = NODE_HW_ID_BYTE2;
  246.     txMsg.Data[3] = NODE_HW_ID_BYTE3;
  247.    
  248.     txMsg.Data[4] = NUMBER_OF_MODULES;
  249.     txMsg.Data[5] = ModuleSequenceNumber;
  250.    
  251.     while (StdCan_Put(&txMsg) != StdCan_Ret_OK);
  252. }
  253.