Measurement of low frequencys based on timing between pulses

Dependents:   Energy_Meter_S0_Example

Pulses.h

Committer:
jocis
Date:
2012-11-08
Revision:
2:fc21262db17a
Parent:
1:6eb686d7d16a
Child:
3:36dd0d59fdc8

File content as of revision 2:fc21262db17a:

/* 
* @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: counter=%d act=%.3f average=%.3f\r\n", 
            , 
            pulses.getAct(), 
            pulses.getAverage(),
            pulses.getCounter() );
        
        wait(3.14);
    }
}
 * @endcode
 */
class Pulses {
public:

    /** Pulses type format */
    enum PulseType {
        RISE=1,
        FALL=2,
        CHANGE=3
    };

    /** 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.
     * @param timeout  Timeout in seconds to handle an offline 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 = RISE, 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 frequencey
     */
    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 occoured since last call
     */
    float getAverage();

    /** Gets the average, min, max and summ 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 occoured since last call.
     * @param pMin        Pointer to float value to return min. frequency. Use NULL to skip param. -1 if no new pulses occoured since last call.
     * @param pMax        Pointer to float value to return max. frequency. Use NULL to skip param. -1 if no new pulses occoured 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