In a recent comment, you posted a link to a forum thread with the
code for reading the sensor. You should have provided this information
up front, because it completely changes the problem. It appears that the
flow meter sends pulses at a frequency proportional to the volume flow,
and the code uses an interrupt to count the pulses over a specified
time.
TisteAndii's answer suggests you integrate the flow readings to get a
volume. And that suggestion makes perfect sense given the limited
information he had available at the time. Now that we know how the flow
meter is read, it makes no sense anymore:
- the interrupt service routine counts a number of pulses that is
proportional to the total volume that has gone through the meter
- the linked code differentiates that reading in order to get the flow
- you are now integrating that flow in order to get the total volume.
Instead of doing an integration on top of a differentiation, you could
just convert the raw reading into a volume. Then you do not have to
worry about any approximations done while differentiating or
integrating.
In the forum thread it is stated:
Pulse frequency (Hz) in Horizontal Test= 7.5Q, Q is flow rate in L/min.
Writing this in a more mathematically accurate form (i.e. with
unit-correctness) gives:
f/Hz = 7.5 Q/(L/min)
where f is the frequency and Q the volume flow.
Given that 7.5 Hz⋅min = 450 pulses, the above equation can be rewritten as
f = 450 pulses/L × Q
or, in terms of integrated quantities:
volume = (pulse count) / (450 pulses/L)
Here is an example code that just convert the pulse count to a volume:
// Calibration constant of the flow meter.
const float calibration = 1/450.0; // 450 pulses per liter
// How often to print the measured volume.
const uint32_t print_interval = 1000; // once per second
// Number of pulses counted so far.
volatile uint32_t pulse_count;
// Count the pulses inside an ISR.
void count_pulse() { pulse_count++; }
// Return volume reading, optinally resetting the count to zero.
float totalVolume(bool reset = false)
{
noInterrupts();
uint32_t pulse_count_copy = pulse_count;
if (reset) pulse_count = 0;
interrupts();
return pulse_count_copy * calibration;
}
void setup()
{
pinMode(2, INPUT_PULLUP);
attachInterrupt(0, count_pulse, RISING);
Serial.begin(9600);
}
void loop()
{
static uint32_t last_print;
if (millis() - last_print >= print_interval) {
last_print += print_interval;
Serial.println(totalVolume());
}
}
Note that you may want to reset the count from time to time. I added an
optional parameter to totalVolume()
for this purpose. If you never
reset the counter, it will overflow after approximately
9544 m3.