Measurement of low frequencys based on timing between pulses

Dependents:   Energy_Meter_S0_Example

Revision:
0:ef402fb370c5
Child:
1:6eb686d7d16a
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Pulses.cpp	Wed Nov 07 18:38:59 2012 +0000
@@ -0,0 +1,99 @@
+#include "Pulses.h"
+
+//////////////////////////////////////////////////////////////////////////////////
+
+Pulses::Pulses(PinName inPin, PulseType type, unsigned int timeout) : _in(inPin) {
+    _timer.reset();
+    _timer.start();
+    
+    _ActTime = 0;
+    _SumTime = 0;
+    _SumCount = 0;
+    _Counter = 0;
+    _Factor = 1.0f;
+    _bFirst = true;
+    
+    if ( timeout > 900 ) timeout = 900;   // not more than 15 minutes
+    _Timeout = timeout;
+    _TimeoutCount = 0;
+    
+    _in.mode(PullUp);
+    
+    _type = type;
+    if ( type & RISE )
+        _in.rise(this, &Pulses::callback_in);
+    if ( type & FALL )
+        _in.fall(this, &Pulses::callback_in);
+        
+    _timeout.attach(this, &Pulses::callback_timeout, 1);
+}
+
+//////////////////////////////////////////////////////////////////////////////////
+
+float Pulses::getAct() {
+    if ( _ActTime == 0 ) return 0.0f;
+    
+    return _Factor / (float)_ActTime;
+}
+
+//////////////////////////////////////////////////////////////////////////////////
+
+float Pulses::getAverage() {
+    unsigned int sumTime = 0;
+    unsigned int sumCount = 0;
+
+    __disable_irq();    // Disable Interrupts for atomic copy
+    sumTime = _SumTime;
+    sumCount = _SumCount;
+    _SumTime = 0;
+    _SumCount = 0;
+    __enable_irq();     // Enable Interrupts
+
+    if ( sumCount == 0 ) return -1.0f;
+    
+    float average = _Factor / ( (float)sumTime / (float)sumCount );
+    return average;
+}
+
+//////////////////////////////////////////////////////////////////////////////////
+
+unsigned int Pulses::getCounter() {
+    return _Counter;
+}
+
+//////////////////////////////////////////////////////////////////////////////////
+    
+void Pulses::setFactor(float factor) {
+    _Factor = factor * 1000000.0f;
+}
+
+//////////////////////////////////////////////////////////////////////////////////
+
+void Pulses::callback_in() {
+    unsigned int diff = _timer.readDiff_us();
+
+    _Counter++;
+    _TimeoutCount = 0;
+
+    if ( _bFirst ) {   // ignore first pulse to synchronize timer (maybe timer overflow)
+        _bFirst = false;
+        return;
+    }
+    
+    _ActTime = diff;
+    _SumTime += diff;
+    _SumCount++;
+}
+
+//////////////////////////////////////////////////////////////////////////////////
+
+void Pulses::callback_timeout() {
+    _TimeoutCount++;
+    if ( _TimeoutCount >= _Timeout ) {
+        _TimeoutCount = 0;
+        _ActTime = 0;
+        _bFirst = true;
+        }
+}
+
+//////////////////////////////////////////////////////////////////////////////////