Measurement of low frequencys based on timing between pulses

Dependents:   Energy_Meter_S0_Example

Pulses.cpp

Committer:
jocis
Date:
2012-11-07
Revision:
0:ef402fb370c5
Child:
1:6eb686d7d16a

File content as of revision 0:ef402fb370c5:

#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;
        }
}

//////////////////////////////////////////////////////////////////////////////////