Measurement of low frequencys based on timing between pulses

Dependents:   Energy_Meter_S0_Example

Committer:
jocis
Date:
Thu Nov 08 14:40:51 2012 +0000
Revision:
3:36dd0d59fdc8
Parent:
2:fc21262db17a
rework of documentation, minor bug fixes

Who changed what in which revision?

UserRevisionLine numberNew contents of line
jocis 0:ef402fb370c5 1 #include "Pulses.h"
jocis 0:ef402fb370c5 2
jocis 0:ef402fb370c5 3 //////////////////////////////////////////////////////////////////////////////////
jocis 0:ef402fb370c5 4
jocis 1:6eb686d7d16a 5 Pulses::Pulses(PinName inPin, PulseType type, unsigned int timeout, unsigned int counter) : _in(inPin) {
jocis 0:ef402fb370c5 6 _timer.reset();
jocis 0:ef402fb370c5 7 _timer.start();
jocis 0:ef402fb370c5 8
jocis 2:fc21262db17a 9 _lastTimer = 0;
jocis 0:ef402fb370c5 10 _ActTime = 0;
jocis 1:6eb686d7d16a 11 _MinTime = 0;
jocis 1:6eb686d7d16a 12 _MaxTime = 0;
jocis 1:6eb686d7d16a 13 _AvrTimeSum = 0;
jocis 1:6eb686d7d16a 14 _AvrTimeCount = 0;
jocis 1:6eb686d7d16a 15 _Counter = counter;
jocis 0:ef402fb370c5 16 _Factor = 1.0f;
jocis 0:ef402fb370c5 17 _bFirst = true;
jocis 0:ef402fb370c5 18
jocis 0:ef402fb370c5 19 if ( timeout > 900 ) timeout = 900; // not more than 15 minutes
jocis 0:ef402fb370c5 20 _Timeout = timeout;
jocis 0:ef402fb370c5 21 _TimeoutCount = 0;
jocis 0:ef402fb370c5 22
jocis 1:6eb686d7d16a 23
jocis 0:ef402fb370c5 24 _type = type;
jocis 1:6eb686d7d16a 25 if ( type & RISE ) {
jocis 0:ef402fb370c5 26 _in.rise(this, &Pulses::callback_in);
jocis 1:6eb686d7d16a 27 _in.mode(PullDown);
jocis 1:6eb686d7d16a 28 }
jocis 1:6eb686d7d16a 29 if ( type & FALL ) {
jocis 0:ef402fb370c5 30 _in.fall(this, &Pulses::callback_in);
jocis 1:6eb686d7d16a 31 _in.mode(PullUp);
jocis 1:6eb686d7d16a 32 }
jocis 0:ef402fb370c5 33
jocis 0:ef402fb370c5 34 _timeout.attach(this, &Pulses::callback_timeout, 1);
jocis 0:ef402fb370c5 35 }
jocis 0:ef402fb370c5 36
jocis 0:ef402fb370c5 37 //////////////////////////////////////////////////////////////////////////////////
jocis 0:ef402fb370c5 38
jocis 0:ef402fb370c5 39 float Pulses::getAct() {
jocis 0:ef402fb370c5 40 if ( _ActTime == 0 ) return 0.0f;
jocis 0:ef402fb370c5 41
jocis 1:6eb686d7d16a 42 return 1000000.0f * _Factor / (float)_ActTime;
jocis 0:ef402fb370c5 43 }
jocis 0:ef402fb370c5 44
jocis 0:ef402fb370c5 45 //////////////////////////////////////////////////////////////////////////////////
jocis 0:ef402fb370c5 46
jocis 0:ef402fb370c5 47 float Pulses::getAverage() {
jocis 1:6eb686d7d16a 48 unsigned int avrTimeSum = 0;
jocis 1:6eb686d7d16a 49 unsigned int avrTimeCount = 0;
jocis 1:6eb686d7d16a 50
jocis 1:6eb686d7d16a 51 __disable_irq(); // Disable Interrupts for atomic copy
jocis 1:6eb686d7d16a 52 avrTimeSum = _AvrTimeSum;
jocis 1:6eb686d7d16a 53 avrTimeCount = _AvrTimeCount;
jocis 1:6eb686d7d16a 54 _AvrTimeSum = 0;
jocis 1:6eb686d7d16a 55 _AvrTimeCount = 0;
jocis 1:6eb686d7d16a 56 __enable_irq(); // Enable Interrupts
jocis 1:6eb686d7d16a 57
jocis 1:6eb686d7d16a 58 if ( avrTimeCount == 0 ) return -1.0f;
jocis 1:6eb686d7d16a 59
jocis 1:6eb686d7d16a 60 return 1000000.0f * _Factor / ( (float)avrTimeSum / (float)avrTimeCount );
jocis 1:6eb686d7d16a 61 }
jocis 1:6eb686d7d16a 62
jocis 1:6eb686d7d16a 63 //////////////////////////////////////////////////////////////////////////////////
jocis 1:6eb686d7d16a 64
jocis 1:6eb686d7d16a 65 void Pulses::get(float *pAverage, float *pMin, float *pMax, float *pSum) {
jocis 1:6eb686d7d16a 66 unsigned int minTime = 0;
jocis 1:6eb686d7d16a 67 unsigned int maxTime = 0;
jocis 1:6eb686d7d16a 68 unsigned int avrTimeSum = 0;
jocis 1:6eb686d7d16a 69 unsigned int avrTimeCount = 0;
jocis 0:ef402fb370c5 70
jocis 0:ef402fb370c5 71 __disable_irq(); // Disable Interrupts for atomic copy
jocis 1:6eb686d7d16a 72 minTime = _MinTime;
jocis 1:6eb686d7d16a 73 maxTime = _MaxTime;
jocis 1:6eb686d7d16a 74 avrTimeSum = _AvrTimeSum;
jocis 1:6eb686d7d16a 75 avrTimeCount = _AvrTimeCount;
jocis 1:6eb686d7d16a 76 _MinTime = 0;
jocis 1:6eb686d7d16a 77 _MaxTime = 0;
jocis 1:6eb686d7d16a 78 _AvrTimeSum = 0;
jocis 1:6eb686d7d16a 79 _AvrTimeCount = 0;
jocis 0:ef402fb370c5 80 __enable_irq(); // Enable Interrupts
jocis 0:ef402fb370c5 81
jocis 1:6eb686d7d16a 82 if ( pAverage ) {
jocis 1:6eb686d7d16a 83 if ( avrTimeCount == 0 )
jocis 1:6eb686d7d16a 84 *pAverage = -1.0f;
jocis 1:6eb686d7d16a 85 else
jocis 1:6eb686d7d16a 86 *pAverage = 1000000.0f * _Factor / ( (float)avrTimeSum / (float)avrTimeCount );
jocis 1:6eb686d7d16a 87 }
jocis 0:ef402fb370c5 88
jocis 1:6eb686d7d16a 89 if ( pMin ) {
jocis 1:6eb686d7d16a 90 if ( minTime == 0 )
jocis 1:6eb686d7d16a 91 *pMin = -1.0f;
jocis 1:6eb686d7d16a 92 else
jocis 1:6eb686d7d16a 93 *pMin = 1000000.0f * _Factor / (float)minTime;
jocis 1:6eb686d7d16a 94 }
jocis 1:6eb686d7d16a 95
jocis 1:6eb686d7d16a 96 if ( pMax ) {
jocis 1:6eb686d7d16a 97 if ( maxTime == 0 )
jocis 1:6eb686d7d16a 98 *pMax = -1.0f;
jocis 1:6eb686d7d16a 99 else
jocis 1:6eb686d7d16a 100 *pMax = 1000000.0f * _Factor / (float)maxTime;
jocis 1:6eb686d7d16a 101 }
jocis 1:6eb686d7d16a 102
jocis 1:6eb686d7d16a 103 if ( pSum ) {
jocis 1:6eb686d7d16a 104 *pSum = _Factor * (float)_Counter;
jocis 1:6eb686d7d16a 105 }
jocis 1:6eb686d7d16a 106
jocis 1:6eb686d7d16a 107 return;
jocis 0:ef402fb370c5 108 }
jocis 0:ef402fb370c5 109
jocis 0:ef402fb370c5 110 //////////////////////////////////////////////////////////////////////////////////
jocis 0:ef402fb370c5 111
jocis 0:ef402fb370c5 112 unsigned int Pulses::getCounter() {
jocis 0:ef402fb370c5 113 return _Counter;
jocis 0:ef402fb370c5 114 }
jocis 0:ef402fb370c5 115
jocis 0:ef402fb370c5 116 //////////////////////////////////////////////////////////////////////////////////
jocis 0:ef402fb370c5 117
jocis 0:ef402fb370c5 118 void Pulses::setFactor(float factor) {
jocis 1:6eb686d7d16a 119 _Factor = factor;
jocis 0:ef402fb370c5 120 }
jocis 0:ef402fb370c5 121
jocis 0:ef402fb370c5 122 //////////////////////////////////////////////////////////////////////////////////
jocis 0:ef402fb370c5 123
jocis 0:ef402fb370c5 124 void Pulses::callback_in() {
jocis 2:fc21262db17a 125 unsigned int act = _timer.read_us();
jocis 2:fc21262db17a 126 unsigned int diff;
jocis 2:fc21262db17a 127
jocis 2:fc21262db17a 128 diff = act - _lastTimer; // Note: overflow is handled correctly
jocis 2:fc21262db17a 129 _lastTimer = act;
jocis 0:ef402fb370c5 130
jocis 0:ef402fb370c5 131 _Counter++;
jocis 0:ef402fb370c5 132 _TimeoutCount = 0;
jocis 0:ef402fb370c5 133
jocis 0:ef402fb370c5 134 if ( _bFirst ) { // ignore first pulse to synchronize timer (maybe timer overflow)
jocis 0:ef402fb370c5 135 _bFirst = false;
jocis 0:ef402fb370c5 136 return;
jocis 0:ef402fb370c5 137 }
jocis 0:ef402fb370c5 138
jocis 0:ef402fb370c5 139 _ActTime = diff;
jocis 1:6eb686d7d16a 140 _AvrTimeSum += diff;
jocis 1:6eb686d7d16a 141 _AvrTimeCount++;
jocis 1:6eb686d7d16a 142
jocis 1:6eb686d7d16a 143 if ( _MinTime==0 || _MinTime<diff )
jocis 1:6eb686d7d16a 144 _MinTime = diff;
jocis 1:6eb686d7d16a 145 if ( _MaxTime==0 || _MaxTime>diff )
jocis 1:6eb686d7d16a 146 _MaxTime = diff;
jocis 0:ef402fb370c5 147 }
jocis 0:ef402fb370c5 148
jocis 0:ef402fb370c5 149 //////////////////////////////////////////////////////////////////////////////////
jocis 0:ef402fb370c5 150
jocis 0:ef402fb370c5 151 void Pulses::callback_timeout() {
jocis 0:ef402fb370c5 152 _TimeoutCount++;
jocis 0:ef402fb370c5 153 if ( _TimeoutCount >= _Timeout ) {
jocis 0:ef402fb370c5 154 _TimeoutCount = 0;
jocis 0:ef402fb370c5 155 _ActTime = 0;
jocis 0:ef402fb370c5 156 _bFirst = true;
jocis 0:ef402fb370c5 157 }
jocis 0:ef402fb370c5 158 }
jocis 0:ef402fb370c5 159
jocis 0:ef402fb370c5 160 //////////////////////////////////////////////////////////////////////////////////