Measure puls over long period but show often the changes

Hello,

the subject I think is not really good chosen but it describes a bit my problem.

What shall be done:

The point is that I have a flow sensor which gives about 1 puls per 7 ml. approx 125 pulses per liter.

Now what I would like to do is to measure & calculate the average flow and send it over a can likely bus.
So far no problem. But the point is that the flow can vary from around 2-3 liter/hour to 70 liters/hour or even some more. The high flow rate does not generate any problem but the low once does as the flow sensor have so low pulses per second down there.

If I need now to send this updated value more often then, for example, every 10 second like every 3 seconds the problem is that I do not have accurate enough measurements from the flow sensor.

So for more accuracy, I could measure and calculate the time between two pulses and use this as the base for the calculation of the flow volume. Still, this is too bad accuracy as a difference of 1 puls per second would result in a very high change already.

So What I thought todo is now to start several measurements with may a second delay, let's say 5 and each measurement runs for 5 seconds. Now after for example 10 seconds, at this point all measurement jobs completed once, I could take the result and average them.

So far so good. Now I was looking for how to do this with the technically best way.

The main question is now for me how to store the values I get from each measurement. I read about circular buffer and arrays. From my logic, a circular buffer would fit here since the measurements should continuously update the variables I would use for averaging the results from the counters. If I understood the function of a circular buffer right every new value which will be store is causing that the first value which was stored will be dropped. This would be then already some kind of averaging.

What kind of technics could I use here?

THX

the problem is that I do not have accurate enough measurements from the flow sensor.

There is NOTHING you can do in the code to make the sensor more accurate. You need better hardware.

So What I thought todo is now to start several measurements with may a second delay, let's say 5 and each measurement runs for 5 seconds. Now after for example 10 seconds, at this point all measurement jobs completed once, I could take the result and average them.

I do not understand this. Perhaps if I saw the code... Measurement job?

What kind of technics could I use here?

You seem to have already chosen a solution.

PaulS:
There is NOTHING you can do in the code to make the sensor more accurate. You need better hardware.

The sensor is accurate enough and I need to use what I have. Also, it is hard to find a flow sensor which works in a so huge range from very low until 70/80 litres per hour. So to get a precise result you need to measure over a longer period. This is always like that, longer period = more precise especially using averaging.
The only point here is to have shorter update periods then every 5 seconds.

However...

Have you read up on moving averages?

Is it closer to 1 pulse per 7 ml (143 pulses per liter) or 125 pulses per liter (1 pulse per 8 ml)? You should probably measure it if you don't want to be 20% off.

At 1 lph you will be getting a pulse about every 25 seconds (assuming 143/l). If the rate goes to 10 lph you will get a new pulse in about 2.5 seconds. Do you really need updates faster than that? At 70 lph you get about 3 pulses per second. The Arduino can handle that very easily. You could get a new sensor with 10 or 100 times the resolution (1500 to 15000 pulses per liter) if you want more frequent updates.

You need a running average of the pulses/second value. Every pulse calculate the current pulses/sec
from the time difference since the last pulse, push that into a running average (which is a simple digital
filter) on a regular basis (every second?).

So for handling a pulse:

unsigned long last_us = 0L;
float current_flow = 0.0;
float averaged_flow = 0.0;

void handle_pulse()
{
  current_us = micros() ;
  long diff_us = current_us - last_us ;
  last_us = current_us ;

  current_flow = 1e6 / diff_us ;
}

Then in loop you can drive the averaging:

unsigned long last_filter = 0L ;

void loop()
{
  if (millis () - last_filter >= 1000)
  {
    last_filter += 1000 ; // set for next time

    averaged_flow += 0.1 * (current_flow - averaged_flow) ;  // single pole low pass digital filter, time constant 10s
  }
  ...
}

johnwasser:
Is it closer to 1 pulse per 7 ml (143 pulses per liter) or 125 pulses per liter (1 pulse per 8 ml)? You should probably measure it if you don't want to be 20% off.

At 1 lph you will be getting a pulse about every 25 seconds (assuming 143/l). If the rate goes to 10 lph you will get a new pulse in about 2.5 seconds. Do you really need updates faster than that? At 70 lph you get about 3 pulses per second. The Arduino can handle that very easily. You could get a new sensor with 10 or 100 times the resolution (1500 to 15000 pulses per liter) if you want more frequent updates.

I did measured the exact value per pulse by 10 times 2 liters flow through. There came out an average of 7.13 ml/puls.

MarkT:
You need a running average of the pulses/second value. Every pulse calculate the current pulses/sec
from the time difference since the last pulse, push that into a running average (which is a simple digital
filter) on a regular basis (every second?).

So for handling a pulse:

unsigned long last_us = 0L;

float current_flow = 0.0;
float averaged_flow = 0.0;

void handle_pulse()
{
  current_us = micros() ;
  long diff_us = current_us - last_us ;
  last_us = current_us ;

current_flow = 1e6 / diff_us ;
}



Then in loop you can drive the averaging:


unsigned long last_filter = 0L ;

void loop()
{
  if (millis () - last_filter >= 1000)
  {
    last_filter += 1000 ; // set for next time

averaged_flow += 0.1 * (current_flow - averaged_flow) ;  // single pole low pass digital filter, time constant 10s
  }
  ...
}

thank you for the start point.
I just did some calculations and I came to the point that the measurement period needs to be much longer than 5 seconds. The point is that an elapsed time between to pulses of 5000 ms will be a volume of approx 5 litres/hour. this will be than 1 pulse per 5 seconds?! This is almost not possible to use for an accurate result as the volume could go down to 2-3 litres/hour. Otherway around could the highest volume be something like 50 litres/hour or even some more.

So now I could say that this is the wrong flow sensor then, but like I mentioned in the second post that it is almost impossible to find a flow sensor based on pulses which is accurate down at 1 or 2 litres/hour as well at 50 litres per hour. Approx 140 pulses per hours for 1 litre (1 puls every 25 seconds), calculated up to 50 l/hr would be 7000 pulses and 514 ms/pulse.

I found one sensor going down to 0,01 L/min up to 1L/min. This nice flow sensor cost about 400 USD. Much too expensive my device!

Any Idea?

autopilotNOR:
If I need now to send this updated value more often then, for example, every 10 second like every 3 seconds the problem is that I do not have accurate enough measurements from the flow sensor.

The only data you have is the most recent pulse from the sensor. You cannot assume that there will another pulse ever, or at any particular future moment.

You can calculate the flow rate based on the most recent pulse (or an average of the N most recent pulses) and you can repeat that value as frequently as you want. But it make no sense at all to anticipate the next pulse.

...R