Measurement of low frequencys based on timing between pulses

Dependents:   Energy_Meter_S0_Example

Revision:
1:6eb686d7d16a
Parent:
0:ef402fb370c5
Child:
2:fc21262db17a
--- a/Pulses.cpp	Wed Nov 07 18:38:59 2012 +0000
+++ b/Pulses.cpp	Thu Nov 08 07:25:41 2012 +0000
@@ -2,14 +2,16 @@
 
 //////////////////////////////////////////////////////////////////////////////////
 
-Pulses::Pulses(PinName inPin, PulseType type, unsigned int timeout) : _in(inPin) {
+Pulses::Pulses(PinName inPin, PulseType type, unsigned int timeout, unsigned int counter) : _in(inPin) {
     _timer.reset();
     _timer.start();
     
     _ActTime = 0;
-    _SumTime = 0;
-    _SumCount = 0;
-    _Counter = 0;
+    _MinTime = 0;
+    _MaxTime = 0;
+    _AvrTimeSum = 0;
+    _AvrTimeCount = 0;
+    _Counter = counter;
     _Factor = 1.0f;
     _bFirst = true;
     
@@ -17,13 +19,16 @@
     _Timeout = timeout;
     _TimeoutCount = 0;
     
-    _in.mode(PullUp);
-    
+   
     _type = type;
-    if ( type & RISE )
+    if ( type & RISE ) {
         _in.rise(this, &Pulses::callback_in);
-    if ( type & FALL )
+        _in.mode(PullDown);
+    }
+    if ( type & FALL ) {
         _in.fall(this, &Pulses::callback_in);
+        _in.mode(PullUp);
+    }
         
     _timeout.attach(this, &Pulses::callback_timeout, 1);
 }
@@ -33,26 +38,72 @@
 float Pulses::getAct() {
     if ( _ActTime == 0 ) return 0.0f;
     
-    return _Factor / (float)_ActTime;
+    return 1000000.0f * _Factor / (float)_ActTime;
 }
 
 //////////////////////////////////////////////////////////////////////////////////
 
 float Pulses::getAverage() {
-    unsigned int sumTime = 0;
-    unsigned int sumCount = 0;
+    unsigned int avrTimeSum = 0;
+    unsigned int avrTimeCount = 0;
+
+    __disable_irq();    // Disable Interrupts for atomic copy
+    avrTimeSum = _AvrTimeSum;
+    avrTimeCount = _AvrTimeCount;
+    _AvrTimeSum = 0;
+    _AvrTimeCount = 0;
+    __enable_irq();     // Enable Interrupts
+
+    if ( avrTimeCount == 0 ) return -1.0f;
+    
+    return 1000000.0f * _Factor / ( (float)avrTimeSum / (float)avrTimeCount );
+}
+
+//////////////////////////////////////////////////////////////////////////////////
+
+void Pulses::get(float *pAverage, float *pMin, float *pMax, float *pSum) {
+    unsigned int minTime = 0;
+    unsigned int maxTime = 0;
+    unsigned int avrTimeSum = 0;
+    unsigned int avrTimeCount = 0;
 
     __disable_irq();    // Disable Interrupts for atomic copy
-    sumTime = _SumTime;
-    sumCount = _SumCount;
-    _SumTime = 0;
-    _SumCount = 0;
+    minTime = _MinTime;
+    maxTime = _MaxTime;
+    avrTimeSum = _AvrTimeSum;
+    avrTimeCount = _AvrTimeCount;
+    _MinTime = 0;
+    _MaxTime = 0;
+    _AvrTimeSum = 0;
+    _AvrTimeCount = 0;
     __enable_irq();     // Enable Interrupts
 
-    if ( sumCount == 0 ) return -1.0f;
+    if ( pAverage ) {
+        if ( avrTimeCount == 0 ) 
+            *pAverage = -1.0f;
+        else
+            *pAverage = 1000000.0f * _Factor / ( (float)avrTimeSum / (float)avrTimeCount );
+    }
     
-    float average = _Factor / ( (float)sumTime / (float)sumCount );
-    return average;
+    if ( pMin ) {
+        if ( minTime == 0 ) 
+            *pMin = -1.0f;
+        else
+            *pMin = 1000000.0f * _Factor / (float)minTime;
+    }
+    
+    if ( pMax ) {
+        if ( maxTime == 0 ) 
+            *pMax = -1.0f;
+        else
+            *pMax = 1000000.0f * _Factor / (float)maxTime;
+    }
+    
+    if ( pSum ) {
+        *pSum = _Factor * (float)_Counter;
+    }
+    
+    return;
 }
 
 //////////////////////////////////////////////////////////////////////////////////
@@ -64,7 +115,7 @@
 //////////////////////////////////////////////////////////////////////////////////
     
 void Pulses::setFactor(float factor) {
-    _Factor = factor * 1000000.0f;
+    _Factor = factor;
 }
 
 //////////////////////////////////////////////////////////////////////////////////
@@ -81,8 +132,13 @@
     }
     
     _ActTime = diff;
-    _SumTime += diff;
-    _SumCount++;
+    _AvrTimeSum += diff;
+    _AvrTimeCount++;
+    
+    if ( _MinTime==0 || _MinTime<diff )
+        _MinTime = diff;
+    if ( _MaxTime==0 || _MaxTime>diff )
+        _MaxTime = diff;
 }
 
 //////////////////////////////////////////////////////////////////////////////////