guys need help about this code on flow sensor how can i achieve the accuracy and precision? And i dont understand the code well is anyone there can explain to me about the this and i would like to ask how to calibrate this code actually i already made it but when i measure the water flow it has great error i mean the output seems to double i dont know how to do this the code is in this bloghttps://www.homemadecircuitsprojects.com/2017/10/simple-digital-water-flow-meter.html?m=1#comment-form :
I was helped by the forum with a flow meter code, this is what we came up with:
const int flowPin = 2;
unsigned long pulseTime = 0;
volatile unsigned long pulses = 0;
volatile unsigned long time = 0;
volatile float seconds = 0.00;
volatile float gallons = 0.00;
volatile float gpm = 0.00;
void pulseCount()
{
pulses++;
time = millis();
}
void setup()
{
pinMode(flowPin, INPUT_PULLUP);
Serial.begin(9600);
attachInterrupt(0, pulseCount, RISING); // interrupt on pin 2
}
void loop()
{
pulseTime = pulseIn(flowPin, LOW);
if (pulseTime != 0) // when flow is active
{
seconds = (float)time / 1000;
Serial.print("Seconds: ");
Serial.println(seconds);
gallons = (float)pulses / 5000.00;
Serial.print("Gallons: ");
Serial.println(gallons);
gpm = (float)gallons * 60.000 / (float)seconds;
Serial.print("GPM: ");
Serial.println(gpm);
Serial.println();
}
}
As far as calibration (that's the pulses if you're using a hall-effect sensor or something similar), I'd piggyback on the other replies - except have something in your code to display the pulses counted. That way, when you have dispensed your fluid and calculated the volume you can correlate it to the pulses in the flow meter. You would basically add [Serial.print(pulses);] somewhere in the code.
For calculating volume - I'd just run the thing into a bucket and weigh it (lbs), divide by 8.33 to get your gallons, do whatever conversions to get the unit you'll be using.
I realized I didn't fully answer the calibration question. Once you have your volume and the un-calibrated pulses displayed, you'll do some math, example for say, 20 lbs and 2000 pulses.
Is the sensor using an impeller that is sensed by a hall sensor? Such flow meaters are higly nonlinear depending on the flow rate but that can be improved.
The flow meter on the web page she listed in the OP says it’s a hall effect sensor, but you’re right about them not being super accurate. You have to have a pretty steady flow rate for them to have consistent readouts. If the application is to see how flow varies over time that might present difficulties.
Here is another example of flow meter code where the pulses are called out at the top instead of mid-code - this one I did not write myself, I don’t remember the name of the guy that helped me with it:
this is the code guys tnx for your replies my application is to get the flow of water per minute and the total water that past the sensor but seems i couldnt understand this well
//-----Program Developed by R.Girish-----// #include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
int X;
int Y;
float Time = 0;
float frequency = 0;
float waterFlow = 0;
float total = 0;
float LS = 0;
const int input = A0;
const int test = 9;
void setup()
{
Serial.begin(9600);
lcd.begin(16, 2);
lcd.clear();
lcd.setCursor(0,0);
lcd.print(“Water Flow Meter”);
lcd.setCursor(0,1);
lcd.print("****************");
delay(2000);
pinMode(input,INPUT);
pinMode(test, OUTPUT);
analogWrite(test,100);
}
void loop()
{
X = pulseIn(input, HIGH);
Y = pulseIn(input, LOW);
Time = X + Y;
frequency = 1000000/Time;
waterFlow = frequency/7.5;
LS = waterFlow/60;
if(frequency >= 0)
{
if(isinf(frequency))
{
lcd.clear();
lcd.setCursor(0,0);
lcd.print(“L/Min: 0.00”);
lcd.setCursor(0,1);
lcd.print(“Total: “);
lcd.print(total);
lcd.print(” L”);
}
else
{
total = total + LS;
Serial.println(frequency);
lcd.clear();
lcd.setCursor(0,0);
lcd.print("L/Min: ");
lcd.print(waterFlow);
lcd.setCursor(0,1);
lcd.print(“Total: “);
lcd.print(total);
lcd.print(” L”);
}
}
delay(1000);
}
Code looks pretty crappy to me. It may work but I believe it is normal practice to use interrupt for this sort of thing. There are times when using a delay to control a loop is legitimate, but I don't think this is one of them, and that may go some way to explain the grief you are having. Even the LCD commands suggest slack practice.
which is where I started with the original code I posted. The problem with my first attempt is that it would display the results in a constant stream, which is why the [if (pulseTime != 0)] part was added, as suggested by another forum member.
The idea behind interrupts is that it gets rid of delays and can count every change (pulse) as it happens.
This part of your code:
void loop()
{
X = pulseIn(input, HIGH);
Y = pulseIn(input, LOW);
Time = X + Y;
frequency = 1000000/Time;
waterFlow = frequency/7.5;
LS = waterFlow/60;
if(frequency >= 0)
{
is really the messy part. You can keep track of time with the internal clock [millis()], instead of doing math to come up with the time. Just use math to convert the pulses to volume, and then use the time to convert to flow rate.
If you have a scale that would be the easiest way to determine the volume that went through the flow meter. Metric is even easier than gallons: 1L = 1kg (roughly). You can either dispense exactly 1kg of water (tricky) and count those pulses, or convert whatever the mass is to volume (should be roughly the same in metric), and then divide pulses by that to get pulses/volume. Definitely want to display the pulses somewhere for that though.
Being a newbie is tricky. I've found the forum a great way to get started, but some of the responses may be pretty blunt.
We all learn. The code I linked to is common practice, there being other versions around of the same thing. It works well, and I just used it in a stripped-down form. The problem with reading the rate is just a human thing and has nothing to do with actual accuracy. The accuracy of these devices can indeed be remarkably good, and this is borne out by the quantity readings.