Measurement of low frequencys based on timing between pulses

Dependents:   Energy_Meter_S0_Example

Pulses.h

Committer:
jocis
Date:
2012-11-08
Revision:
3:36dd0d59fdc8
Parent:
2:fc21262db17a

File content as of revision 3:36dd0d59fdc8:

/* 
* @author Jochen Krapf
*
* @section LICENSE
*
* Copyright (c) 2012 Jochen Krapf, MIT License
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or
* substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* @section DESCRIPTION
* mbed Pulses Library, for measurement of low frequencys based on timing between pulses
*
* Use cases:
* - Frequency counter for frequ. about or below sample rate (Hz)
* - Motor rotations (rpm)
* - Energy meter with SO interface
*
*
*/

#ifndef MBED_PULSES_H
#define MBED_PULSES_H

#include "mbed.h"

/** A class to calculate frequencys based on timing between pulses. Pulse-frequency can be about or slower than loop/aquisition time
*
* Example:
*
* @code
#include "mbed.h"
#include "Pulses.h"

Pulses pulses(p8, Pulses::FALL);
Serial pc(USBTX, USBRX); // tx, rx

int main() {
    // choose on of the following unit scales
    pulses.setFactor(1.0f);   // Hz
    pulses.setFactor(60.0f);   // rpm
    pulses.setFactor(3600.0f/2000.0f);   // kWh; energy meter with SO interface - 2000 pulses per kWh
    
    while(1) {
        pc.printf ( "Pulses: act=%.3f average=%.3f   counter=%d \r\n", 
            pulses.getAct(), 
            pulses.getAverage(),
            pulses.getCounter() );
        
        wait(3.14);
    }
}
* @endcode
*/
class Pulses {
public:

    /** Pulses type format */
    enum PulseType {
        RISE=1,     //< Trigger on rising edge
        FALL=2,     //< Trigger on falling edge
        CHANGE=3    //< Trigger on both edges. On symmetrical pulses you can improve precision by 2
    };

    /** constructor of Pulses object
    *
    * @param inPin    Pin number of input pin. All port pins are possible except p19 and p20
    * @param type     Type of edge detection. RISE, FALL, CHANGE
    * @param timeout  Timeout in seconds to handle a stopped pulse-generator (standing motor). Max 15 minutes.
    * @param counter  Start value of the internal pulses counter to offset pSum (in get()) e.g. after reboot
    */
    explicit Pulses(PinName inPin, PulseType type=FALL, unsigned int timeout=600, unsigned int counter=0);

    /** Gets the frequency based on the last 2 pulses. It's only a snapshot and its not representative.
    *
    * @return        Actual frequency
    */
    float getAct();

    /** Gets the average of frequency based on all pulses since last call of this function
    *
    * @return        Average frequency. -1 if no new pulses occurred since last call
    */
    float getAverage();

    /** Gets the average, min, max and sum of frequency based on all pulses since last call of this function
    *
    * @param pAverage    Pointer to float value to return average frequency. Use NULL to skip param. -1 if no new pulses occurred since last call.
    * @param pMin        Pointer to float value to return min. frequency. Use NULL to skip param. -1 if no new pulses occurred since last call.
    * @param pMax        Pointer to float value to return max. frequency. Use NULL to skip param. -1 if no new pulses occurred since last call.
    * @param pSum        Pointer to float value to return the accumulated average values. Use NULL to skip param.
    */
    void get(float *pAverage, float *pMin, float *pMax, float *pSum=NULL);

    /** Gets the number of pulses from the input pin since start
    *
    * @return        Number of pulses
    */
    unsigned int getCounter();

    /** Sets the factor for the getter-functions to convert in another unit (1.0=Hz, 60.0=rpm, ...)
    *
    * @param factor  Factor to scale from Hz to user unit
    */
    void setFactor(float factor);


protected:
    // ISR
    void callback_in();
    void callback_timeout();

    InterruptIn _in;
    Timer _timer;
    Ticker _timeout;

    PulseType _type;

    unsigned int _lastTimer;
    unsigned int _ActTime;
    unsigned int _MinTime;
    unsigned int _MaxTime;
    unsigned int _AvrTimeSum;
    unsigned int _AvrTimeCount;
    unsigned int _Counter;
    float _Factor;
    bool _bFirst;
    unsigned int _Timeout;
    unsigned int _TimeoutCount;

};

#endif