Measurement of low frequencys based on timing between pulses

Dependents:   Energy_Meter_S0_Example

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers Pulses.cpp Source File

Pulses.cpp

00001 #include "Pulses.h"
00002 
00003 //////////////////////////////////////////////////////////////////////////////////
00004 
00005 Pulses::Pulses(PinName inPin, PulseType type, unsigned int timeout, unsigned int counter) : _in(inPin) {
00006     _timer.reset();
00007     _timer.start();
00008     
00009     _lastTimer = 0;
00010     _ActTime = 0;
00011     _MinTime = 0;
00012     _MaxTime = 0;
00013     _AvrTimeSum = 0;
00014     _AvrTimeCount = 0;
00015     _Counter = counter;
00016     _Factor = 1.0f;
00017     _bFirst = true;
00018     
00019     if ( timeout > 900 ) timeout = 900;   // not more than 15 minutes
00020     _Timeout = timeout;
00021     _TimeoutCount = 0;
00022     
00023    
00024     _type = type;
00025     if ( type & RISE ) {
00026         _in.rise(this, &Pulses::callback_in);
00027         _in.mode(PullDown);
00028     }
00029     if ( type & FALL ) {
00030         _in.fall(this, &Pulses::callback_in);
00031         _in.mode(PullUp);
00032     }
00033         
00034     _timeout.attach(this, &Pulses::callback_timeout, 1);
00035 }
00036 
00037 //////////////////////////////////////////////////////////////////////////////////
00038 
00039 float Pulses::getAct() {
00040     if ( _ActTime == 0 ) return 0.0f;
00041     
00042     return 1000000.0f * _Factor / (float)_ActTime;
00043 }
00044 
00045 //////////////////////////////////////////////////////////////////////////////////
00046 
00047 float Pulses::getAverage() {
00048     unsigned int avrTimeSum = 0;
00049     unsigned int avrTimeCount = 0;
00050 
00051     __disable_irq();    // Disable Interrupts for atomic copy
00052     avrTimeSum = _AvrTimeSum;
00053     avrTimeCount = _AvrTimeCount;
00054     _AvrTimeSum = 0;
00055     _AvrTimeCount = 0;
00056     __enable_irq();     // Enable Interrupts
00057 
00058     if ( avrTimeCount == 0 ) return -1.0f;
00059     
00060     return 1000000.0f * _Factor / ( (float)avrTimeSum / (float)avrTimeCount );
00061 }
00062 
00063 //////////////////////////////////////////////////////////////////////////////////
00064 
00065 void Pulses::get(float *pAverage, float *pMin, float *pMax, float *pSum) {
00066     unsigned int minTime = 0;
00067     unsigned int maxTime = 0;
00068     unsigned int avrTimeSum = 0;
00069     unsigned int avrTimeCount = 0;
00070 
00071     __disable_irq();    // Disable Interrupts for atomic copy
00072     minTime = _MinTime;
00073     maxTime = _MaxTime;
00074     avrTimeSum = _AvrTimeSum;
00075     avrTimeCount = _AvrTimeCount;
00076     _MinTime = 0;
00077     _MaxTime = 0;
00078     _AvrTimeSum = 0;
00079     _AvrTimeCount = 0;
00080     __enable_irq();     // Enable Interrupts
00081 
00082     if ( pAverage ) {
00083         if ( avrTimeCount == 0 ) 
00084             *pAverage = -1.0f;
00085         else
00086             *pAverage = 1000000.0f * _Factor / ( (float)avrTimeSum / (float)avrTimeCount );
00087     }
00088     
00089     if ( pMin ) {
00090         if ( minTime == 0 ) 
00091             *pMin = -1.0f;
00092         else
00093             *pMin = 1000000.0f * _Factor / (float)minTime;
00094     }
00095     
00096     if ( pMax ) {
00097         if ( maxTime == 0 ) 
00098             *pMax = -1.0f;
00099         else
00100             *pMax = 1000000.0f * _Factor / (float)maxTime;
00101     }
00102     
00103     if ( pSum ) {
00104         *pSum = _Factor * (float)_Counter;
00105     }
00106     
00107     return;
00108 }
00109 
00110 //////////////////////////////////////////////////////////////////////////////////
00111 
00112 unsigned int Pulses::getCounter() {
00113     return _Counter;
00114 }
00115 
00116 //////////////////////////////////////////////////////////////////////////////////
00117     
00118 void Pulses::setFactor(float factor) {
00119     _Factor = factor;
00120 }
00121 
00122 //////////////////////////////////////////////////////////////////////////////////
00123 
00124 void Pulses::callback_in() {
00125     unsigned int act = _timer.read_us();
00126     unsigned int diff;
00127         
00128     diff = act - _lastTimer;   // Note: overflow is handled correctly
00129     _lastTimer = act;
00130 
00131     _Counter++;
00132     _TimeoutCount = 0;
00133 
00134     if ( _bFirst ) {   // ignore first pulse to synchronize timer (maybe timer overflow)
00135         _bFirst = false;
00136         return;
00137     }
00138     
00139     _ActTime = diff;
00140     _AvrTimeSum += diff;
00141     _AvrTimeCount++;
00142     
00143     if ( _MinTime==0 || _MinTime<diff )
00144         _MinTime = diff;
00145     if ( _MaxTime==0 || _MaxTime>diff )
00146         _MaxTime = diff;
00147 }
00148 
00149 //////////////////////////////////////////////////////////////////////////////////
00150 
00151 void Pulses::callback_timeout() {
00152     _TimeoutCount++;
00153     if ( _TimeoutCount >= _Timeout ) {
00154         _TimeoutCount = 0;
00155         _ActTime = 0;
00156         _bFirst = true;
00157         }
00158 }
00159 
00160 //////////////////////////////////////////////////////////////////////////////////