A multifunctional and modular Firmware for Multitech's mDot based on ARM mBed provides a widerange of functionality for several Sensors such as MAX44009, BME280, MPU9250, SI1143 and uBlox. It allows you to quickly build a Sensornode that measures specific data with its sensors and sends it via LoRaWAN.

Dependencies:   mDot_LoRa_Sensornode_Flowmeter_impl mbed-rtos mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers FlowMeter.h Source File

FlowMeter.h

00001 /*
00002  * FlowMeter.h
00003  *
00004  *  Created on: 23.10.2018
00005  *      Author: Adrian
00006  */
00007 
00008 #ifndef DRIVERS_FLOWMETER_H_
00009 #define DRIVERS_FLOWMETER_H_
00010 #include "InterruptIn.h"
00011 #include "Ticker.h"
00012 #include "mbed.h"
00013 /**
00014  * FlowSensorProperties
00015  *
00016  * Structure that holds essential information about a flow sensor.
00017  * Stores general sensor properties and calibration points.
00018  *
00019  * See file G34_Flow_rate_to_frequency.jpg for reference.
00020  */
00021 typedef struct {
00022   double capacity;      //!< capacity, upper limit of flow rate (in l/min)
00023   double kFactor;       //!< "k-factor" (in (pulses/s) / (l/min)), e.g.: 1 pulse/s = kFactor * l/min
00024   double mFactor[10];   //!< multiplicative correction factor near unity, "meter factor" (per decile of flow)
00025 } FlowSensorProperties;
00026 
00027 extern FlowSensorProperties UncalibratedSensor; //!< default sensor
00028 extern FlowSensorProperties FS300A;             //!< see documentation about FS300A/SEN02141B
00029 extern FlowSensorProperties FS400A;             //!< see documentation about FS400A/USN-HS10TA
00030 
00031 /**
00032  * FlowMeter
00033  */
00034 class FlowMeter {
00035   public:
00036     /**
00037      * Initializes a new flow meter object.
00038      *
00039      * @param pin  The pin that the flow sensor is connected to (has to be interrupt capable, default: INT0).
00040      * @param prop The properties of the actual flow sensor being used (default: UncalibratedSensor).
00041      */
00042     FlowMeter(InterruptIn* pin, FlowSensorProperties prop = UncalibratedSensor);
00043 
00044     double getCurrentFlowrate();                 //!< Returns the current flow rate since last reset (in l/min).
00045     double getCurrentVolume();                   //!< Returns the current volume since last reset (in l).
00046 
00047     double getTotalFlowrate();                   //!< Returns the (linear) average flow rate in this flow meter instance (in l/min).
00048     double getTotalVolume();                     //!< Returns the total volume flown trough this flow meter instance (in l).
00049 
00050     /**
00051      * The tick method updates all internal calculations at the end of a measurement period.
00052      *
00053      * We're calculating flow and volume data over time.
00054      * The actual pulses have to be sampled using the count method (i.e. via an interrupt service routine).
00055      *
00056      * Flow sensor formulae:
00057      *
00058      * Let K: pulses per second per unit of measure (i.e. (1/s)/(l/min)),
00059      *     f: pulse frequency (1/s),
00060      *     Q: flow rate (l/min),
00061      *     p: sensor pulses (no dimension/unit),
00062      *     t: time since last measurements (s).
00063      *
00064      * K = f / Q             | units: (1/s) / (l/min) = (1/s) / (l/min)
00065      * <=>                   | Substitute p / t for f in order to allow for different measurement intervals
00066      * K = (p / t) / Q       | units: ((1/s)/(l/min)) = (1/s) / (l/min)
00067      * <=>                   | Solve for Q:
00068      * Q = (p / t) / K       | untis: l/min = 1/s / (1/s / (l/min))
00069      * <=>                   | Volume in l:
00070      * V = Q / 60            | units: l = (l/min) / (min)
00071      *
00072      * The property K is sometimes stated in pulses per liter or pulses per gallon.
00073      * In these cases the unit of measure has to be converted accordingly (e.g. from gal/s to l/min).
00074      * See file G34_Flow_rate_to_frequency.jpg for reference.
00075      *
00076      * @param duration The tick duration (in ms).
00077      */
00078     void tick();
00079     void count(void);                                //!< Increments the internal pulse counter. Serves as an interrupt callback routine.
00080     void reset();                                //!< Prepares the flow meter for a fresh measurement. Resets all current values, but not the totals.
00081 
00082     /*
00083      * setters enabling continued metering across power cycles
00084      */
00085     FlowMeter* setTotalDuration(unsigned long totalDuration); //!< Sets the total (overall) duration (i.e. after power up).
00086     FlowMeter* setTotalVolume(double totalVolume);            //!< Sets the total (overall) volume (i.e. after power up).
00087     FlowMeter* setTotalCorrection(double totalCorrection);    //!< Sets the total (overall) correction factor (i.e. after power up).
00088 
00089     /*
00090      * convenience methods and calibration helpers
00091      */
00092     InterruptIn* getPin();                       //!< Returns the Arduino pin number that the flow sensor is connected to.
00093 
00094     unsigned long getCurrentDuration();          //!< Returns the duration of the current tick (in ms).
00095     double getCurrentFrequency();                //!< Returns the pulse rate in the current tick (in 1/s).
00096     double getCurrentError();                    //!< Returns the error resulting from the current measurement (in %).
00097 
00098     unsigned long getTotalDuration();            //!< Returns the total run time of this flow meter instance (in ms).
00099     double getTotalError();                      //!< Returns the (linear) average error of this flow meter instance (in %).
00100 
00101   protected:
00102     InterruptIn* pulseInput;
00103     Ticker* ticker;
00104     unsigned long tickDuration_ms;
00105     //unsigned int _pin;                           //!< connection pin (has to be interrupt capable!)
00106     FlowSensorProperties _properties;            //!< sensor properties (including calibration data)
00107 
00108     unsigned long _currentDuration;              //!< current tick duration (convenience, in ms)
00109     double _currentFrequency;                    //!< current pulses per second (convenience, in 1/s)
00110     double _currentFlowrate;              //!< current flow rate (in l/tick), e.g.: 1 l / min = 1 pulse / s / (pulses / s / l / min)
00111     double _currentVolume;                //!< current volume (in l), e.g.: 1 l = 1 (l / min) / (60 * s)
00112     double _currentCorrection;                   //!< currently applied correction factor
00113 
00114     unsigned long _totalDuration;         //!< total measured duration since begin of measurement (in ms)
00115     double _totalVolume;                  //!< total volume since begin of measurement (in l)
00116     double _totalCorrection;              //!< accumulated correction factors
00117 
00118     volatile unsigned long _currentPulses;   //!< pulses within current sample period
00119 };
00120 
00121 /**
00122  * FlowSensorCalibration
00123  *
00124  * Convenience class for manipulating sensor properties.
00125  */
00126 class FlowSensorCalibration {
00127   public:
00128     FlowSensorCalibration() {};
00129     FlowSensorCalibration(FlowSensorProperties properties): _properties(properties) {};
00130 
00131     FlowSensorCalibration* setProperties(FlowSensorProperties properties) {
00132         this->_properties = properties;
00133         return this;
00134     };
00135 
00136     FlowSensorCalibration* setCapacity(double capacity) {
00137         this->_properties.capacity = capacity;
00138         return this;
00139     }
00140 
00141     FlowSensorCalibration* setKFactor(double kFactor) {
00142         this->_properties.kFactor = kFactor;
00143         return this;
00144     }
00145 
00146     FlowSensorCalibration* setMeterFactorPerDecile(unsigned int decile, unsigned int mFactor) {
00147         this->_properties.mFactor[decile] = mFactor;
00148         return this;
00149     }
00150 
00151     FlowSensorProperties getProperties() {
00152         return this->_properties;
00153     }
00154 
00155     double getCapacity() {
00156         return this->_properties.capacity;
00157     }
00158 
00159     double getKFactor() {
00160         return this->_properties.kFactor;
00161     }
00162 
00163     unsigned int getMeterFactorPerDecile(unsigned int decile) {
00164         return this->_properties.mFactor[decile];
00165     }
00166 
00167   protected:
00168     FlowSensorProperties _properties;
00169 };
00170 
00171 #endif /* DRIVERS_FLOWMETER_H_ */