Subversion Repositories HomeAutomation

Rev

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

  1.  
  2. #include "sns_water.h"
  3.  
  4. static uint8_t volatile sns_water_status = LOW;
  5. static uint32_t volatile sns_water_liter_cnt=0;
  6. static uint32_t volatile sns_water_microliter_cnt=0;
  7. static uint32_t volatile sns_water_TimePrevTick;
  8. static uint32_t volatile sns_water_Buffer[4]= {0x0000ffff,0x0000ffff,0x0000ffff,0x0000ffff};
  9. static uint8_t volatile sns_water_Buf_Pointer=0;
  10.  
  11. /* Set this parameter to 1000 to send volume in ml instead of liters, useful for debugging */
  12. #define MIKROLITERINLITER 1000000
  13.  
  14. /* When printf is enabled the number of ticks are sent on can instead of volume */
  15. #if CAN_PRINTF==1
  16. uint32_t sns_water_debug_cnt=0;
  17. #endif
  18.  
  19. StdCan_Msg_t txMsg;
  20.  
  21. #if sns_water_USEEEPROM==1
  22. #include "sns_water_eeprom.h"
  23. struct eeprom_sns_water EEMEM eeprom_sns_water =
  24. {
  25.     {
  26.         ///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.
  27.         0xAB,       // x
  28.         0x1234      // y
  29.         0x12345678  // z
  30.     },
  31.     0   // crc, must be a correct value, but this will also be handled by the EEPROM module or make scripts
  32. };
  33. #endif
  34.  
  35. void sns_water_Init(void)
  36. {
  37. #if sns_water_USEEEPROM==1
  38.     if (EEDATA_OK)
  39.     {
  40.       ///TODO: Use stored data to set initial values for the module
  41.       blablaX = eeprom_read_byte(EEDATA.x);
  42.       blablaY = eeprom_read_word(EEDATA16.y);
  43.       blablaZ = eeprom_read_dword(EEDATA32.y);
  44.     } else
  45.     {   //The CRC of the EEPROM is not correct, store default values and update CRC
  46.       eeprom_write_byte_crc(EEDATA.x, 0xAB, WITHOUT_CRC);
  47.       eeprom_write_word_crc(EEDATA16.y, 0x1234, WITHOUT_CRC);
  48.       eeprom_write_dword_crc(EEDATA32.y, 0x12345678, WITHOUT_CRC);
  49.       EEDATA_UPDATE_CRC;
  50.     }
  51. #endif
  52.  
  53.     ADC_Init();
  54.     sns_water_TimePrevTick = Timer_GetTicks();
  55.     Timer_SetTimeout(sns_water_ADPOLL_TIMER, sns_water_ADPOLL_PERIOD_MS, TimerTypeFreeRunning, 0);
  56.     Timer_SetTimeout(sns_water_SEND_TIMER, sns_water_SEND_PERIOD_S*1000, TimerTypeFreeRunning, 0);
  57.  
  58.     uint16_t ADvalue = ADC_Get(sns_water_AD_CHANNEL);
  59.     if (ADvalue > (sns_water_HIGH_THRESHOLD_MV*1024UL/5000UL))
  60.     {
  61.         sns_water_status = HIGH;
  62.     }
  63.  
  64.     StdCan_Set_class(txMsg.Header, CAN_MODULE_CLASS_SNS);
  65.     StdCan_Set_direction(txMsg.Header, DIRECTIONFLAG_FROM_OWNER);
  66.     txMsg.Header.ModuleType = CAN_MODULE_TYPE_SNS_WATER;
  67.     txMsg.Header.ModuleId = sns_water_ID;
  68.     txMsg.Header.Command = CAN_MODULE_CMD_PHYSICAL_FLOW;
  69.     txMsg.Length = 6;
  70. }
  71.  
  72. void sns_water_Process(void)
  73. {
  74.     /*
  75.     Notes
  76.     maybe its better to skip the poll timer and always poll when in process
  77.     */
  78.     uint8_t oldstatus = sns_water_status;
  79.     if (Timer_Expired(sns_water_ADPOLL_TIMER))
  80.     {
  81.         uint16_t ADvalue = ADC_Get(sns_water_AD_CHANNEL);
  82.         if (sns_water_status == LOW && ADvalue > (sns_water_HIGH_THRESHOLD_MV*1024UL/5000UL))
  83.         {
  84.             sns_water_status = HIGH;
  85.         }
  86.         else if (sns_water_status == HIGH && ADvalue < (sns_water_LOW_THRESHOLD_MV*1024UL/5000UL))
  87.         {
  88.             sns_water_status = LOW;
  89.         }
  90.     }
  91.    
  92.     /* If status changed */
  93.     if (oldstatus != sns_water_status)
  94.     {
  95.         sns_water_microliter_cnt += sns_water_UL_PER_TICK;
  96.         /* If microliter counter has more than one liter */
  97.         while (sns_water_microliter_cnt >= MIKROLITERINLITER)
  98.         {
  99.             /* Add one liter to liter counter */
  100.             sns_water_liter_cnt += 1;
  101.             /* Decrease microliter counter with the volume added to liter counter */
  102.             sns_water_microliter_cnt -= MIKROLITERINLITER;
  103.         }
  104.        
  105.         sns_water_Buffer[sns_water_Buf_Pointer] = Timer_GetTicks() - sns_water_TimePrevTick;
  106.         if (sns_water_Buf_Pointer++ == 4)
  107.         {
  108.             sns_water_Buf_Pointer = 0;
  109.         }
  110.        
  111.         sns_water_TimePrevTick = Timer_GetTicks();
  112.  
  113. #if CAN_PRINTF==1
  114.         sns_water_debug_cnt += 1;
  115. #endif
  116.     }
  117.    
  118.     if (Timer_Expired(sns_water_SEND_TIMER))
  119.     {
  120.         uint32_t flow4 = 0;
  121.         for (uint8_t i = 0; i<4;i++) {
  122.              flow4 += sns_water_Buffer[i];
  123.         }
  124.         flow4 = flow4/4;
  125.         /* The flow is ml per tick / time between ticks */
  126.         flow4 = sns_water_UL_PER_TICK/flow4;
  127.  
  128.         txMsg.Data[0] = (uint8_t)((flow4>>8) & 0xff);
  129.         txMsg.Data[1] = (uint8_t)(flow4 & 0xff);
  130.         txMsg.Data[5] = (uint8_t)sns_water_liter_cnt & 0xff;
  131.         txMsg.Data[4] = (uint8_t)(sns_water_liter_cnt >> 8) & 0xff;
  132.         txMsg.Data[3] = (uint8_t)(sns_water_liter_cnt >> 16) & 0xff;
  133.         txMsg.Data[2] = (uint8_t)(sns_water_liter_cnt >> 24) & 0xff;
  134. #if CAN_PRINTF==1
  135.         txMsg.Data[5] = (uint8_t)sns_water_debug_cnt & 0xff;
  136.         txMsg.Data[4] = (uint8_t)(sns_water_debug_cnt >> 8) & 0xff;
  137.         txMsg.Data[3] = (uint8_t)(sns_water_debug_cnt >> 16) & 0xff;
  138.         txMsg.Data[2] = (uint8_t)(sns_water_debug_cnt >> 24) & 0xff;
  139. #endif
  140.         while (StdCan_Put(&txMsg) != StdCan_Ret_OK);
  141.  
  142.         /* TODO How to handle no flow? (means no ticks, no new time-diffs) */
  143.         /* This solution starts to fill buffer with older values if ticks come in slower than we send out data */
  144.         if (Timer_GetTicks() - sns_water_TimePrevTick > sns_water_SEND_PERIOD_S*2000)
  145.         {
  146.             sns_water_Buffer[sns_water_Buf_Pointer] = Timer_GetTicks() - sns_water_TimePrevTick;
  147.             if (sns_water_Buf_Pointer++ == 4)
  148.             {
  149.                 sns_water_Buf_Pointer = 0;
  150.             }
  151.         }
  152. #if CAN_PRINTF==1
  153.         //printf("c:%d\n", sns_water_debug_cnt);
  154. #endif
  155.     }
  156. }
  157.  
  158. void sns_water_HandleMessage(StdCan_Msg_t *rxMsg)
  159. {
  160. #if 0
  161.     if (    StdCan_Ret_class(rxMsg->Header) == CAN_MODULE_CLASS_SNS &&
  162.         StdCan_Ret_direction(rxMsg->Header) == DIRECTIONFLAG_FROM_OWNER &&
  163.         rxMsg->Header.ModuleType == CAN_MODULE_TYPE_SNS_WATER &&
  164.         rxMsg->Header.ModuleId == sns_water_ID)
  165.     {
  166.         switch (rxMsg->Header.Command)
  167.         {
  168.         case CAN_CMD_MODULE_DUMMY:
  169.        
  170.         break;
  171.         }
  172.     }
  173. #endif
  174. }
  175.  
  176. void sns_water_List(uint8_t ModuleSequenceNumber)
  177. {
  178.     StdCan_Msg_t txMsg;
  179.  
  180.     StdCan_Set_class(txMsg.Header, CAN_MODULE_CLASS_SNS);
  181.     StdCan_Set_direction(txMsg.Header, DIRECTIONFLAG_FROM_OWNER);
  182.     txMsg.Header.ModuleType = CAN_MODULE_TYPE_SNS_WATER;
  183.     txMsg.Header.ModuleId = sns_water_ID;
  184.     txMsg.Header.Command = CAN_MODULE_CMD_GLOBAL_LIST;
  185.     txMsg.Length = 6;
  186.  
  187.     uint32_t HwId=BIOS_GetHwId();
  188.     txMsg.Data[0] = HwId&0xff;
  189.     txMsg.Data[1] = (HwId>>8)&0xff;
  190.     txMsg.Data[2] = (HwId>>16)&0xff;
  191.     txMsg.Data[3] = (HwId>>24)&0xff;
  192.  
  193.     txMsg.Data[4] = NUMBER_OF_MODULES;
  194.     txMsg.Data[5] = ModuleSequenceNumber;
  195.  
  196.     while (StdCan_Put(&txMsg) != StdCan_Ret_OK);
  197. }
  198.