update Code
This commit is contained in:
parent
3c47103b39
commit
a641fad56c
119 changed files with 10997 additions and 5 deletions
7
libraries/FlowMeter-master/.github/CONTRIBUTING.md
vendored
Normal file
7
libraries/FlowMeter-master/.github/CONTRIBUTING.md
vendored
Normal file
|
@ -0,0 +1,7 @@
|
|||
## Contributing to the FlowMeter library
|
||||
|
||||
All pull requests are welcome.
|
||||
Please follow the pull request template.
|
||||
|
||||
If you have a question or suggestion, feel free to open an issue on Github.
|
||||
Please follow the issue template.
|
9
libraries/FlowMeter-master/.github/ISSUE_TEMPLATE.md
vendored
Normal file
9
libraries/FlowMeter-master/.github/ISSUE_TEMPLATE.md
vendored
Normal file
|
@ -0,0 +1,9 @@
|
|||
## Expected behavior
|
||||
|
||||
## Observed behavior.
|
||||
|
||||
## Steps to reproduce the problem.
|
||||
|
||||
## Arduino (or other IDE) version info
|
||||
|
||||
## Arduino (or compatible) hardware info
|
37
libraries/FlowMeter-master/.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
37
libraries/FlowMeter-master/.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
|
@ -0,0 +1,37 @@
|
|||
---
|
||||
name: Bug report
|
||||
about: Create a report to help us improve
|
||||
|
||||
---
|
||||
|
||||
**Description**
|
||||
A clear and concise description of what the bug is.
|
||||
|
||||
**Reproduction**
|
||||
Steps to reproduce the behavior:
|
||||
1. Connect '...'
|
||||
2. Measure '...'
|
||||
3. Error '...'
|
||||
|
||||
**Expected behavior**
|
||||
A clear and concise description of what you expected to happen.
|
||||
|
||||
**Screenshots**
|
||||
If applicable, add screenshots to help explain your problem.
|
||||
|
||||
**Hardware (please complete the following information):**
|
||||
- Board type
|
||||
- Sensor type
|
||||
- Pins used
|
||||
|
||||
**Software (please complete the following information):**
|
||||
- OS
|
||||
- IDE
|
||||
- Other libraries
|
||||
|
||||
**Minimal example to reproduce (please complete the following information):**
|
||||
- Code to reproduce
|
||||
- Wiring to reproduce
|
||||
|
||||
**Additional context**
|
||||
Add any other context about the problem here.
|
17
libraries/FlowMeter-master/.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
17
libraries/FlowMeter-master/.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
|
@ -0,0 +1,17 @@
|
|||
---
|
||||
name: Feature request
|
||||
about: Suggest an idea for this project
|
||||
|
||||
---
|
||||
|
||||
**Is your feature request related to a problem? Please describe.**
|
||||
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
||||
|
||||
**Describe the solution you'd like**
|
||||
A clear and concise description of what you want to happen.
|
||||
|
||||
**Describe alternatives you've considered**
|
||||
A clear and concise description of any alternative solutions or features you've considered.
|
||||
|
||||
**Additional context**
|
||||
Add any other context or screenshots about the feature request here.
|
11
libraries/FlowMeter-master/.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
11
libraries/FlowMeter-master/.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
|
@ -0,0 +1,11 @@
|
|||
## Tackles issue #
|
||||
|
||||
## changes being applied by this pull request
|
||||
|
||||
-
|
||||
-
|
||||
-
|
||||
|
||||
## people involved
|
||||
|
||||
@user/repository
|
22
libraries/FlowMeter-master/LICENSE
Normal file
22
libraries/FlowMeter-master/LICENSE
Normal file
|
@ -0,0 +1,22 @@
|
|||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 sekdiy
|
||||
|
||||
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.
|
||||
|
87
libraries/FlowMeter-master/README.md
Normal file
87
libraries/FlowMeter-master/README.md
Normal file
|
@ -0,0 +1,87 @@
|
|||
# FlowMeter Library [](https://github.com/sekdiy/FlowMeter) [](https://travis-ci.org/sekdiy/FlowMeter) []()
|
||||
|
||||
**FlowMeter** is an Arduino library that provides calibrated flow and volume measurement with flow sensors.
|
||||
|
||||
You can use it to count flow and volume of liquids and gases (although the documentation focuses on applications using liquids) and can support multiple flow sensors at the same time.
|
||||
|
||||
It also works as a totalizer, accumulating total volume and average flow rate over the run time of your project.
|
||||
|
||||
A provision for calibration helps you to get the most out of your sensor. You can even estimate the recent and overall error margin.
|
||||
|
||||
The library is intended for use with flow sensors that provide a frequency output signal proportional to flow, although other types of sensors could be made to work.
|
||||
|
||||
## A Simple Example
|
||||
|
||||
Getting started with **FlowMeter** is easy. Take a look at this simple example:
|
||||
|
||||
```c++
|
||||
void setup() {
|
||||
// prepare serial communication
|
||||
Serial.begin(9600);
|
||||
|
||||
// enable a call to a helper function on every rising edge
|
||||
attachInterrupt(INT0, MeterISR, RISING);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// wait between output updates
|
||||
delay(period);
|
||||
|
||||
// process the (possibly) counted ticks
|
||||
Meter.tick(period);
|
||||
|
||||
// output some measurement result
|
||||
Serial.print("Currently ");
|
||||
Serial.print(Meter.getCurrentFlowrate());
|
||||
Serial.print(" l/min, ");
|
||||
Serial.print(Meter.getTotalVolume());
|
||||
Serial.println(" l total.");
|
||||
|
||||
//
|
||||
// any other code can go here
|
||||
//
|
||||
}
|
||||
```
|
||||
|
||||
In the above example, a flow sensor is assumed to be connected to the `INT0` pin. The corresponding object `Meter` is updated every `period` (in milliseconds, e.g. 1000ms).
|
||||
|
||||
So after every measurement `period`, the current *flow rate* and the total *volume* are printed out.
|
||||
|
||||
Please read on in the [examples](https://github.com/sekdiy/FlowMeter/wiki/Examples) section of the library's [documentation pages](https://github.com/sekdiy/FlowMeter/wiki).
|
||||
|
||||
## Installing the library
|
||||
|
||||
Just check out the [**FlowMeter**](https://github.com/sekdiy/FlowMeter) Repository on GitHub (or download the ZIP archive) and copy it to your `libraries/` folder (usually within your Arduino sketchbook).
|
||||
|
||||
See the [installation](https://github.com/sekdiy/FlowMeter/wiki/Installation) section in the [documentation pages](https://github.com/sekdiy/FlowMeter/wiki) for more.
|
||||
|
||||
## Unit of measure
|
||||
|
||||
The **FlowMeter** library expresses flow in the unit **l/min**.
|
||||
Most units of measure can be derived by simple conversion (just try not to measure in [Sverdrups](https://en.wikipedia.org/wiki/Sverdrup)).
|
||||
|
||||
As an example, conversion between **l/min** and US **gal/min** can be done with a factor of *3.78541178*, conversion from **min** to **s** with a factor of *60*.
|
||||
|
||||
```math
|
||||
3.78541178 l/min ≈ 1 gal/min ≈ 0.0167 gal/s.
|
||||
```
|
||||
|
||||
Please make sure you consult the [documentation](https://github.com/sekdiy/FlowMeter/wiki/Properties) in order to further understand how the library works.
|
||||
|
||||
## Should you calibrate your own sensor?
|
||||
|
||||
The **FlowMeter** library can be used with many different flow sensors right away. Some [sensor examples](https://github.com/sekdiy/FlowMeter/wiki/Sensors) are listed in the documentation.
|
||||
|
||||
For many projects you don't need to worry about calibration. But it still makes sense to be aware of the limitations that come with an uncalibrated sensor in a metering application.
|
||||
|
||||
It's easy to calibrate yourself. Preferrably you'd do this after installing the sensor into your project. The flow meter then benefits from increased precision within the viscosity and flow range of your application.
|
||||
|
||||
There's a [complete how-to](https://github.com/sekdiy/FlowMeter/wiki/Calibration) in the documentation.
|
||||
|
||||

|
||||
|
||||
## Documentation
|
||||
|
||||
For further details please take a look at the **FlowMeter** [documentation pages](https://github.com/sekdiy/FlowMeter/wiki).
|
||||
|
||||
Also, the library source code (in the folder [`src/`](src/)) and the examples (in the folder [`examples/`](examples/)) are fully documented.
|
|
@ -0,0 +1,48 @@
|
|||
#include <FlowMeter.h> // https://github.com/sekdiy/FlowMeter
|
||||
|
||||
// enter your own sensor properties here, including calibration points
|
||||
FlowSensorProperties MySensor = {60.0f, 5.5f, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1}};
|
||||
FlowMeter Meter = FlowMeter(2, MySensor);
|
||||
|
||||
// timekeeping variables
|
||||
long period = 1000; // one second (in milliseconds)
|
||||
long lastTime = 0;
|
||||
|
||||
// define an 'interrupt service routine' (ISR)
|
||||
void MeterISR() {
|
||||
// let our flow meter count the pulses
|
||||
Meter.count();
|
||||
}
|
||||
|
||||
void setup() {
|
||||
// prepare serial communication
|
||||
Serial.begin(9600);
|
||||
|
||||
// enable a call to the 'interrupt service handler' (ISR) on every rising edge at the interrupt pin
|
||||
attachInterrupt(INT0, MeterISR, RISING);
|
||||
|
||||
// sometimes initializing the gear generates some pulses that we should ignore
|
||||
Meter.reset();
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// do some timekeeping
|
||||
long currentTime = millis();
|
||||
long duration = currentTime - lastTime;
|
||||
|
||||
// wait between display updates
|
||||
if (duration >= period) {
|
||||
|
||||
// process the counted ticks
|
||||
Meter.tick(duration);
|
||||
|
||||
// output some measurement result
|
||||
Serial.println("FlowMeter - current flow rate: " + String(Meter.getCurrentFlowrate()) + " l/min, " +
|
||||
"nominal volume: " + String(Meter.getTotalVolume()) + " l, " +
|
||||
"compensated error: " + String(Meter.getCurrentError()) + " %, " +
|
||||
"duration: " + String(Meter.getTotalDuration() / 1000) + " s.");
|
||||
|
||||
// prepare for next cycle
|
||||
lastTime = currentTime;
|
||||
}
|
||||
}
|
51
libraries/FlowMeter-master/examples/Multi/Multi.ino
Normal file
51
libraries/FlowMeter-master/examples/Multi/Multi.ino
Normal file
|
@ -0,0 +1,51 @@
|
|||
#include <FlowMeter.h> // https://github.com/sekdiy/FlowMeter
|
||||
|
||||
// connect a flow meter to an interrupt pin (see notes on your Arduino model for pin numbers)
|
||||
FlowMeter Meter1 = FlowMeter(2);
|
||||
FlowMeter Meter2 = FlowMeter(3);
|
||||
|
||||
// set the measurement update period to 1s (1000 ms)
|
||||
const unsigned long period = 1000;
|
||||
|
||||
// define an 'interrupt service handler' (ISR) for every interrupt pin you use
|
||||
void Meter1ISR() {
|
||||
// let our flow meter count the pulses
|
||||
Meter1.count();
|
||||
}
|
||||
|
||||
// define an 'interrupt service handler' (ISR) for every interrupt pin you use
|
||||
void Meter2ISR() {
|
||||
// let our flow meter count the pulses
|
||||
Meter2.count();
|
||||
}
|
||||
|
||||
void setup() {
|
||||
// prepare serial communication
|
||||
Serial.begin(9600);
|
||||
|
||||
// enable a call to the 'interrupt service handler' (ISR) on every rising edge at the interrupt pin
|
||||
// do this setup step for every ISR you have defined, depending on how many interrupts you use
|
||||
attachInterrupt(INT0, Meter1ISR, RISING);
|
||||
attachInterrupt(INT1, Meter2ISR, RISING);
|
||||
|
||||
// sometimes initializing the gear generates some pulses that we should ignore
|
||||
Meter1.reset();
|
||||
Meter2.reset();
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// wait between output updates
|
||||
delay(period);
|
||||
|
||||
// process the (possibly) counted ticks
|
||||
Meter1.tick(period);
|
||||
Meter2.tick(period);
|
||||
|
||||
// output some measurement result
|
||||
Serial.println("Meter 1 currently " + String(Meter1.getCurrentFlowrate()) + " l/min, " + String(Meter1.getTotalVolume())+ " l total.");
|
||||
Serial.println("Meter 2 currently " + String(Meter2.getCurrentFlowrate()) + " l/min, " + String(Meter2.getTotalVolume())+ " l total.");
|
||||
|
||||
//
|
||||
// any other code can go here
|
||||
//
|
||||
}
|
40
libraries/FlowMeter-master/examples/Simple/Simple.ino
Normal file
40
libraries/FlowMeter-master/examples/Simple/Simple.ino
Normal file
|
@ -0,0 +1,40 @@
|
|||
#include <FlowMeter.h> // https://github.com/sekdiy/FlowMeter
|
||||
|
||||
// connect a flow meter to an interrupt pin (see notes on your Arduino model for pin numbers)
|
||||
FlowMeter Meter = FlowMeter(2);
|
||||
|
||||
// set the measurement update period to 1s (1000 ms)
|
||||
const unsigned long period = 1000;
|
||||
|
||||
// define an 'interrupt service handler' (ISR) for every interrupt pin you use
|
||||
void MeterISR() {
|
||||
// let our flow meter count the pulses
|
||||
Meter.count();
|
||||
}
|
||||
|
||||
void setup() {
|
||||
// prepare serial communication
|
||||
Serial.begin(9600);
|
||||
|
||||
// enable a call to the 'interrupt service handler' (ISR) on every rising edge at the interrupt pin
|
||||
// do this setup step for every ISR you have defined, depending on how many interrupts you use
|
||||
attachInterrupt(INT0, MeterISR, RISING);
|
||||
|
||||
// sometimes initializing the gear generates some pulses that we should ignore
|
||||
Meter.reset();
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// wait between output updates
|
||||
delay(period);
|
||||
|
||||
// process the (possibly) counted ticks
|
||||
Meter.tick(period);
|
||||
|
||||
// output some measurement result
|
||||
Serial.println("Currently " + String(Meter.getCurrentFlowrate()) + " l/min, " + String(Meter.getTotalVolume())+ " l total.");
|
||||
|
||||
//
|
||||
// any other code can go here
|
||||
//
|
||||
}
|
43
libraries/FlowMeter-master/examples/Simulator/Simulator.ino
Normal file
43
libraries/FlowMeter-master/examples/Simulator/Simulator.ino
Normal file
|
@ -0,0 +1,43 @@
|
|||
#include <FlowMeter.h> // https://github.com/sekdiy/FlowMeter
|
||||
|
||||
// let's provide our own sensor properties, including calibration points for error correction
|
||||
FlowSensorProperties MySensor = {60.0f, 4.5f, {1.2, 1.1, 1.05, 1, 1, 1, 1, 0.95, 0.9, 0.8}};
|
||||
|
||||
// let's pretend there's a flow sensor connected to pin 3
|
||||
FlowMeter Meter = FlowMeter(3, MySensor);
|
||||
|
||||
void setup() {
|
||||
// prepare serial communication
|
||||
Serial.begin(9600);
|
||||
|
||||
// sometimes initializing the gear generates some pulses that we should ignore
|
||||
Meter.reset();
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// randomly change simulation period and pulse rate
|
||||
long frequency = random(MySensor.capacity * MySensor.kFactor); // Hz
|
||||
long period = random(3 * frequency, 5000); // ms
|
||||
|
||||
// simulate random flow meter pulses within a random period
|
||||
for (long i = 0; i < (long) ((float) period * (float) frequency / 1000.0f); i++) {
|
||||
Meter.count();
|
||||
}
|
||||
|
||||
// wait that random period
|
||||
delay(period);
|
||||
|
||||
// process the counted ticks
|
||||
Meter.tick(period);
|
||||
|
||||
// output some measurement result
|
||||
Serial.println("FlowMeter - period: " + String(Meter.getCurrentDuration() / 1000.0f, 3) + "s, " +
|
||||
"frequency: " + String(Meter.getCurrentFrequency(), 0) + "Hz, " +
|
||||
"volume: " + Meter.getCurrentVolume() + "l, " +
|
||||
"flow rate: " + Meter.getCurrentFlowrate() + "l/min, " +
|
||||
"error: " + Meter.getCurrentError() + "%, " +
|
||||
"total duration: " + Meter.getTotalDuration() / 1000.0f + "s, " +
|
||||
"total volume: " + Meter.getTotalVolume() + "l, " +
|
||||
"average flow rate: " + Meter.getTotalFlowrate() + "l/min, " +
|
||||
"average error: " + Meter.getTotalError() + "%.");
|
||||
}
|
19
libraries/FlowMeter-master/examples/platformio.ini
Normal file
19
libraries/FlowMeter-master/examples/platformio.ini
Normal file
|
@ -0,0 +1,19 @@
|
|||
#
|
||||
# Project Configuration File
|
||||
#
|
||||
# A detailed documentation with the EXAMPLES is located here:
|
||||
# http://docs.platformio.org/en/latest/projectconf.html
|
||||
#
|
||||
|
||||
[env:2009]
|
||||
platform = atmelavr
|
||||
framework = arduino
|
||||
board = diecimilaatmega328
|
||||
|
||||
[env:pro8]
|
||||
platform = atmelavr
|
||||
framework = arduino
|
||||
board = pro8MHzatmega328
|
||||
|
||||
# Automatic targets - enable auto-uploading
|
||||
targets = upload
|
120
libraries/FlowMeter-master/src/FlowMeter.cpp
Normal file
120
libraries/FlowMeter-master/src/FlowMeter.cpp
Normal file
|
@ -0,0 +1,120 @@
|
|||
/*
|
||||
* Flow Meter
|
||||
*/
|
||||
|
||||
#include "Arduino.h"
|
||||
#include "FlowMeter.h" // https://github.com/sekdiy/FlowMeter
|
||||
#include <math.h>
|
||||
|
||||
FlowMeter::FlowMeter(unsigned int pin, FlowSensorProperties prop) :
|
||||
_pin(pin), //!< store pin number
|
||||
_properties(prop) //!< store sensor properties
|
||||
{
|
||||
pinMode(pin, INPUT_PULLUP); //!< initialize interrupt pin as input with pullup
|
||||
}
|
||||
|
||||
double FlowMeter::getCurrentFlowrate() {
|
||||
return this->_currentFlowrate; //!< in l/min
|
||||
}
|
||||
|
||||
double FlowMeter::getCurrentVolume() {
|
||||
return this->_currentVolume; //!< in l
|
||||
}
|
||||
|
||||
double FlowMeter::getTotalFlowrate() {
|
||||
return this->_totalVolume / (this->_totalDuration / 1000.0f) * 60.0f; //!< in l/min
|
||||
}
|
||||
|
||||
double FlowMeter::getTotalVolume() {
|
||||
return this->_totalVolume; //!< in l
|
||||
}
|
||||
|
||||
void FlowMeter::tick(unsigned long duration) {
|
||||
/* sampling and normalisation */
|
||||
double seconds = duration / 1000.0f; //!< normalised duration (in s, i.e. per 1000ms)
|
||||
cli(); //!< going to change interrupt variable(s)
|
||||
double frequency = this->_currentPulses / seconds; //!< normalised frequency (in 1/s)
|
||||
this->_currentPulses = 0; //!< reset pulse counter after successfull sampling
|
||||
sei(); //!< done changing interrupt variable(s)
|
||||
|
||||
/* determine current correction factor (from sensor properties) */
|
||||
unsigned int decile = floor(10.0f * frequency / (this->_properties.capacity * this->_properties.kFactor)); //!< decile of current flow relative to sensor capacity
|
||||
unsigned int ceiling = 9; //!< highest possible decile index
|
||||
this->_currentCorrection = this->_properties.kFactor / this->_properties.mFactor[min(decile, ceiling)]; //!< combine constant k-factor and m-factor for decile
|
||||
|
||||
/* update current calculations: */
|
||||
this->_currentFlowrate = frequency / this->_currentCorrection; //!< get flow rate (in l/min) from normalised frequency and combined correction factor
|
||||
this->_currentVolume = this->_currentFlowrate / (60.0f/seconds); //!< get volume (in l) from normalised flow rate and normalised time
|
||||
|
||||
/* update statistics: */
|
||||
this->_currentDuration = duration; //!< store current tick duration (convenience, in ms)
|
||||
this->_currentFrequency = frequency; //!< store current pulses per second (convenience, in 1/s)
|
||||
this->_totalDuration += duration; //!< accumulate total duration (in ms)
|
||||
this->_totalVolume += this->_currentVolume; //!< accumulate total volume (in l)
|
||||
this->_totalCorrection += this->_currentCorrection * duration; //!< accumulate corrections over time
|
||||
}
|
||||
|
||||
void FlowMeter::count() {
|
||||
this->_currentPulses++; //!< this should be called from an interrupt service routine
|
||||
}
|
||||
|
||||
void FlowMeter::reset() {
|
||||
cli(); //!< going to change interrupt variable(s)
|
||||
this->_currentPulses = 0; //!< reset pulse counter
|
||||
sei(); //!< done changing interrupt variable(s)
|
||||
|
||||
this->_currentFrequency = 0.0f;
|
||||
this->_currentDuration = 0.0f;
|
||||
this->_currentFlowrate = 0.0f;
|
||||
this->_currentVolume = 0.0f;
|
||||
this->_currentCorrection = 0.0f;
|
||||
}
|
||||
|
||||
unsigned int FlowMeter::getPin() {
|
||||
return this->_pin;
|
||||
}
|
||||
|
||||
unsigned long FlowMeter::getCurrentDuration() {
|
||||
return this->_currentDuration; //!< in ms
|
||||
}
|
||||
|
||||
double FlowMeter::getCurrentFrequency() {
|
||||
return this->_currentFrequency; //!< in 1/s
|
||||
}
|
||||
|
||||
double FlowMeter::getCurrentError() {
|
||||
/// error (in %) = error * 100
|
||||
/// error = correction rate - 1
|
||||
/// correction rate = k-factor / correction
|
||||
return (this->_properties.kFactor / this->_currentCorrection - 1) * 100; //!< in %
|
||||
}
|
||||
|
||||
unsigned long FlowMeter::getTotalDuration() {
|
||||
return this->_totalDuration; //!< in ms
|
||||
}
|
||||
|
||||
double FlowMeter::getTotalError() {
|
||||
/// average error (in %) = average error * 100
|
||||
/// average error = average correction rate - 1
|
||||
/// average correction rate = k-factor / corrections over time * total time
|
||||
return (this->_properties.kFactor / this->_totalCorrection * this->_totalDuration - 1) * 100;
|
||||
}
|
||||
|
||||
FlowMeter* FlowMeter::setTotalDuration(unsigned long totalDuration) {
|
||||
this->_totalDuration = totalDuration;
|
||||
return this;
|
||||
}
|
||||
|
||||
FlowMeter* FlowMeter::setTotalVolume(double totalVolume) {
|
||||
this->_totalVolume = totalVolume;
|
||||
return this;
|
||||
}
|
||||
|
||||
FlowMeter* FlowMeter::setTotalCorrection(double totalCorrection) {
|
||||
this->_totalCorrection = totalCorrection;
|
||||
return this;
|
||||
}
|
||||
|
||||
FlowSensorProperties UncalibratedSensor = {60.0f, 5.0f, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1}};
|
||||
FlowSensorProperties FS300A = {60.0f, 5.5f, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1}};
|
||||
FlowSensorProperties FS400A = {60.0f, 4.8f, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1}};
|
171
libraries/FlowMeter-master/src/FlowMeter.h
Normal file
171
libraries/FlowMeter-master/src/FlowMeter.h
Normal file
|
@ -0,0 +1,171 @@
|
|||
/**
|
||||
* Flow Meter
|
||||
*
|
||||
* An Arduino flow meter library that provides calibrated liquid flow and volume measurement with flow sensors.
|
||||
*
|
||||
* @author sekdiy (https://github.com/sekdiy/FlowMeter)
|
||||
* @date 14.07.2015 Initial release.
|
||||
* @version See git comments for changes.
|
||||
*/
|
||||
|
||||
#ifndef FLOWMETER_H
|
||||
#define FLOWMETER_H
|
||||
|
||||
#include "Arduino.h"
|
||||
|
||||
/**
|
||||
* FlowSensorProperties
|
||||
*
|
||||
* Structure that holds essential information about a flow sensor.
|
||||
* Stores general sensor properties and calibration points.
|
||||
*
|
||||
* See file G34_Flow_rate_to_frequency.jpg for reference.
|
||||
*/
|
||||
typedef struct {
|
||||
double capacity; //!< capacity, upper limit of flow rate (in l/min)
|
||||
double kFactor; //!< "k-factor" (in (pulses/s) / (l/min)), e.g.: 1 pulse/s = kFactor * l/min
|
||||
double mFactor[10]; //!< multiplicative correction factor near unity, "meter factor" (per decile of flow)
|
||||
} FlowSensorProperties;
|
||||
|
||||
extern FlowSensorProperties UncalibratedSensor; //!< default sensor
|
||||
extern FlowSensorProperties FS300A; //!< see documentation about FS300A/SEN02141B
|
||||
extern FlowSensorProperties FS400A; //!< see documentation about FS400A/USN-HS10TA
|
||||
|
||||
/**
|
||||
* FlowMeter
|
||||
*/
|
||||
class FlowMeter {
|
||||
public:
|
||||
/**
|
||||
* Initializes a new flow meter object.
|
||||
*
|
||||
* @param pin The pin that the flow sensor is connected to (has to be interrupt capable, default: INT0).
|
||||
* @param prop The properties of the actual flow sensor being used (default: UncalibratedSensor).
|
||||
*/
|
||||
FlowMeter(unsigned int pin = 2, FlowSensorProperties prop = UncalibratedSensor);
|
||||
|
||||
double getCurrentFlowrate(); //!< Returns the current flow rate since last reset (in l/min).
|
||||
double getCurrentVolume(); //!< Returns the current volume since last reset (in l).
|
||||
|
||||
double getTotalFlowrate(); //!< Returns the (linear) average flow rate in this flow meter instance (in l/min).
|
||||
double getTotalVolume(); //!< Returns the total volume flown trough this flow meter instance (in l).
|
||||
|
||||
/**
|
||||
* The tick method updates all internal calculations at the end of a measurement period.
|
||||
*
|
||||
* We're calculating flow and volume data over time.
|
||||
* The actual pulses have to be sampled using the count method (i.e. via an interrupt service routine).
|
||||
*
|
||||
* Flow sensor formulae:
|
||||
*
|
||||
* Let K: pulses per second per unit of measure (i.e. (1/s)/(l/min)),
|
||||
* f: pulse frequency (1/s),
|
||||
* Q: flow rate (l/min),
|
||||
* p: sensor pulses (no dimension/unit),
|
||||
* t: time since last measurements (s).
|
||||
*
|
||||
* K = f / Q | units: (1/s) / (l/min) = (1/s) / (l/min)
|
||||
* <=> | Substitute p / t for f in order to allow for different measurement intervals
|
||||
* K = (p / t) / Q | units: ((1/s)/(l/min)) = (1/s) / (l/min)
|
||||
* <=> | Solve for Q:
|
||||
* Q = (p / t) / K | untis: l/min = 1/s / (1/s / (l/min))
|
||||
* <=> | Volume in l:
|
||||
* V = Q / 60 | units: l = (l/min) / (min)
|
||||
*
|
||||
* The property K is sometimes stated in pulses per liter or pulses per gallon.
|
||||
* In these cases the unit of measure has to be converted accordingly (e.g. from gal/s to l/min).
|
||||
* See file G34_Flow_rate_to_frequency.jpg for reference.
|
||||
*
|
||||
* @param duration The tick duration (in ms).
|
||||
*/
|
||||
void tick(unsigned long duration = 1000);
|
||||
void count(); //!< Increments the internal pulse counter. Serves as an interrupt callback routine.
|
||||
void reset(); //!< Prepares the flow meter for a fresh measurement. Resets all current values, but not the totals.
|
||||
|
||||
/*
|
||||
* setters enabling continued metering across power cycles
|
||||
*/
|
||||
FlowMeter* setTotalDuration(unsigned long totalDuration); //!< Sets the total (overall) duration (i.e. after power up).
|
||||
FlowMeter* setTotalVolume(double totalVolume); //!< Sets the total (overall) volume (i.e. after power up).
|
||||
FlowMeter* setTotalCorrection(double totalCorrection); //!< Sets the total (overall) correction factor (i.e. after power up).
|
||||
|
||||
/*
|
||||
* convenience methods and calibration helpers
|
||||
*/
|
||||
unsigned int getPin(); //!< Returns the Arduino pin number that the flow sensor is connected to.
|
||||
|
||||
unsigned long getCurrentDuration(); //!< Returns the duration of the current tick (in ms).
|
||||
double getCurrentFrequency(); //!< Returns the pulse rate in the current tick (in 1/s).
|
||||
double getCurrentError(); //!< Returns the error resulting from the current measurement (in %).
|
||||
|
||||
unsigned long getTotalDuration(); //!< Returns the total run time of this flow meter instance (in ms).
|
||||
double getTotalError(); //!< Returns the (linear) average error of this flow meter instance (in %).
|
||||
|
||||
protected:
|
||||
unsigned int _pin; //!< connection pin (has to be interrupt capable!)
|
||||
FlowSensorProperties _properties; //!< sensor properties (including calibration data)
|
||||
|
||||
unsigned long _currentDuration; //!< current tick duration (convenience, in ms)
|
||||
double _currentFrequency; //!< current pulses per second (convenience, in 1/s)
|
||||
double _currentFlowrate = 0.0f; //!< current flow rate (in l/tick), e.g.: 1 l / min = 1 pulse / s / (pulses / s / l / min)
|
||||
double _currentVolume = 0.0f; //!< current volume (in l), e.g.: 1 l = 1 (l / min) / (60 * s)
|
||||
double _currentCorrection; //!< currently applied correction factor
|
||||
|
||||
unsigned long _totalDuration = 0.0f; //!< total measured duration since begin of measurement (in ms)
|
||||
double _totalVolume = 0.0f; //!< total volume since begin of measurement (in l)
|
||||
double _totalCorrection = 0.0f; //!< accumulated correction factors
|
||||
|
||||
volatile unsigned long _currentPulses = 0; //!< pulses within current sample period
|
||||
};
|
||||
|
||||
/**
|
||||
* FlowSensorCalibration
|
||||
*
|
||||
* Convenience class for manipulating sensor properties.
|
||||
*/
|
||||
class FlowSensorCalibration {
|
||||
public:
|
||||
FlowSensorCalibration() {};
|
||||
FlowSensorCalibration(FlowSensorProperties properties): _properties(properties) {};
|
||||
|
||||
FlowSensorCalibration* setProperties(FlowSensorProperties properties) {
|
||||
this->_properties = properties;
|
||||
return this;
|
||||
};
|
||||
|
||||
FlowSensorCalibration* setCapacity(double capacity) {
|
||||
this->_properties.capacity = capacity;
|
||||
return this;
|
||||
}
|
||||
|
||||
FlowSensorCalibration* setKFactor(double kFactor) {
|
||||
this->_properties.kFactor = kFactor;
|
||||
return this;
|
||||
}
|
||||
|
||||
FlowSensorCalibration* setMeterFactorPerDecile(unsigned int decile, unsigned int mFactor) {
|
||||
this->_properties.mFactor[decile] = mFactor;
|
||||
return this;
|
||||
}
|
||||
|
||||
FlowSensorProperties getProperties() {
|
||||
return this->_properties;
|
||||
}
|
||||
|
||||
double getCapacity() {
|
||||
return this->_properties.capacity;
|
||||
}
|
||||
|
||||
double getKFactor() {
|
||||
return this->_properties.kFactor;
|
||||
}
|
||||
|
||||
unsigned int getMeterFactorPerDecile(unsigned int decile) {
|
||||
return this->_properties.mFactor[decile];
|
||||
}
|
||||
|
||||
protected:
|
||||
FlowSensorProperties _properties;
|
||||
};
|
||||
|
||||
#endif // FLOWMETER_H
|
Loading…
Add table
Add a link
Reference in a new issue