Subversion Repositories HomeAutomation

Rev

Rev 1752 | Blame | Compare with Previous | Last modification | View Log | SVN | RSS feed

  1. #include "sns_PIR.h"
  2.  
  3. #define ABS(a) ((a) < 0 ? (-a) : (a))
  4.  
  5.  
  6. // a weighted moving avarage value is used to remove "DC offset"
  7. static uint32_t zeroOffset = 0;
  8.  
  9. // a second avarage value is used to detect changes in avarage "energy"
  10. #define NR_AVG_VALUES   15
  11. static int16_t avgValues[NR_AVG_VALUES];
  12. static uint8_t avgIndex = 0;
  13.  
  14.  
  15. void sns_PIR_Init(void)
  16. {
  17.     ADC_Init();
  18.     ltc2450_init();
  19.     Timer_SetTimeout(sns_PIR_SAMPLE_TIMER,  sns_PIR_SAMPLE_PERIOD,  TimerTypeFreeRunning, 0);
  20.     Timer_SetTimeout(sns_PIR_SEND_TIMER,    sns_PIR_SEND_PERIOD,    TimerTypeFreeRunning, 0);
  21. }
  22.  
  23.  
  24. void sns_PIR_Process(void)
  25. {
  26.     static uint8_t motionDetect = 0;
  27.     uint16_t brightness;
  28.     if (Timer_Expired(sns_PIR_SAMPLE_TIMER)) {
  29.         /**
  30.          * Read PIR sensor (via external ADC)
  31.          */
  32.         uint16_t pirValue;
  33.         do {
  34.             // if ADC is busy, returned value is 0xFFFF
  35.             pirValue = ltc2450_read();
  36.         } while (pirValue >= 0xFFFF);
  37.         // first time?
  38.         if (zeroOffset == 0) {
  39.             zeroOffset = pirValue;
  40.         }
  41.         else {
  42.             zeroOffset = (zeroOffset*4 + (uint32_t)pirValue)/5;
  43.         }
  44.         int8_t test = (int8_t)((int32_t)pirValue - (int32_t)zeroOffset);
  45.         avgValues[avgIndex++] = test;
  46.         if (avgIndex >= NR_AVG_VALUES) {
  47.             avgIndex = 0;
  48.         }
  49.         uint16_t avgValue = 0;
  50.         for (uint8_t i=0; i<NR_AVG_VALUES; i++) {
  51.             avgValue += ABS(avgValues[i]);
  52.         }
  53.        
  54.         /* Or to keep motiondetect==1 true for at least one CAN send period, so detections are never lost */
  55.         motionDetect |= (avgValue >= 80);
  56.        
  57.     }
  58.     if (Timer_Expired(sns_PIR_SEND_TIMER)) {
  59.         /**
  60.          * Read brightness sensor (via internal ADC).
  61.          */
  62.         brightness = ADC_Get(sns_PIR_BRIGHTNESS_AD);
  63.  
  64.         /**
  65.          * Time to send CAN message.
  66.          */
  67.         StdCan_Msg_t txMsg;
  68.         StdCan_Set_class(txMsg.Header, CAN_MODULE_CLASS_SNS);
  69.         StdCan_Set_direction(txMsg.Header, DIRECTIONFLAG_FROM_OWNER);
  70.         txMsg.Header.ModuleType = CAN_MODULE_TYPE_SNS_PIR;
  71.         txMsg.Header.ModuleId = sns_PIR_ID;
  72.         txMsg.Header.Command = CAN_MODULE_CMD_PIR_MOTION;
  73.         txMsg.Length = 4;
  74.         txMsg.Data[0] = 0;
  75.         txMsg.Data[1] = (uint8_t)((brightness&0xFF00) >> 8);
  76.         txMsg.Data[2] = (uint8_t)((brightness&0x00FF) >> 0);
  77.         txMsg.Data[3] = motionDetect;
  78.         StdCan_Put(&txMsg);
  79.         // also print data to debug
  80.         //printf("M:%u,B:%d\n", motionDetect, brightness);
  81.         motionDetect = 0;
  82.     }
  83. }
  84.  
  85. void sns_PIR_HandleMessage(StdCan_Msg_t *rxMsg)
  86. {
  87.     /*if (  StdCan_Ret_class(rxMsg->Header) == CAN_MODULE_CLASS_xyz && ///TODO: Change this to the actual class type
  88.         StdCan_Ret_direction(rxMsg->Header) == DIRECTIONFLAG_FROM_OWNER &&
  89.         rxMsg->Header.ModuleType == CAN_MODULE_TYPE_xyz && ///TODO: Change this to the actual module type
  90.         rxMsg->Header.ModuleId == sns_PIR_ID)
  91.     {
  92.         switch (rxMsg->Header.Command)
  93.         {
  94.         case CAN_CMD_MODULE_DUMMY:
  95.         ///TODO: Do something dummy
  96.         break;
  97.         }
  98.     }*/
  99. }
  100.  
  101. void sns_PIR_List(uint8_t ModuleSequenceNumber)
  102. {
  103.     StdCan_Msg_t txMsg;
  104.    
  105.     StdCan_Set_class(txMsg.Header, CAN_MODULE_CLASS_SNS);
  106.     StdCan_Set_direction(txMsg.Header, DIRECTIONFLAG_FROM_OWNER);
  107.     txMsg.Header.ModuleType = CAN_MODULE_TYPE_SNS_PIR;
  108.     txMsg.Header.ModuleId = sns_PIR_ID;
  109.     txMsg.Header.Command = CAN_MODULE_CMD_GLOBAL_LIST;
  110.     txMsg.Length = 6;
  111.  
  112.     uint32_t HwId=BIOS_GetHwId();
  113.     txMsg.Data[0] = HwId&0xff;
  114.     txMsg.Data[1] = (HwId>>8)&0xff;
  115.     txMsg.Data[2] = (HwId>>16)&0xff;
  116.     txMsg.Data[3] = (HwId>>24)&0xff;
  117.    
  118.     txMsg.Data[4] = NUMBER_OF_MODULES;
  119.     txMsg.Data[5] = ModuleSequenceNumber;
  120.    
  121.     while (StdCan_Put(&txMsg) != StdCan_Ret_OK);
  122. }
  123.  
  124.