Hey guys, my mini project is about pumping water from main container to another, i want the flow sensor to check whether there is water coming from the main container and if not to stop the pump, but since i am getting numbers with huge differences even after tinkering with the code, i ran out of ideas! i used this code:
And i understand everything happening in the code, but i don't know what the problem is, and it's not about calibration since the input from the sensor (Pulses) are varying a lot while the pump is functioning normally, any input would be great! Thanks guys.
Neither will anyone else unless you show your diagrams, hardware and YOUR code and the errors.
Use code tags and read follow instructions on how to post.
Can you tell us your electronics, programming, arduino, hardware experience?
Just looking the descructible project, they do activate the internal pullup resistor, but you may need to add an extra 10K resistor between 5V and pin2.
Must be something wrong with your code, or maybe your wiring.
Code on that instructable is also pretty poorly done: using detachInterrupt() is the wrong way of dealing with the problem of values being updated while being read. The pulses come in slow enough to not need an interrupt in the first place.
I wouldn't trust anything out of Instructables, but a glance shows it is similar to
The rate can vary quite a lot but the overall performance, judged by the total flow, is very accurate. I understand you are only interested in a go/no go situation and therefore really only need a switch. Nonetheless, I think you can get the same result by simply determining when flow = 0, and the fact that it varies when it does not = 0 is immaterial.
1- Pump is a submersible 5V connected like this :Link
2- The flow sensor's pw and gnd are connected to the uno( i tried a 5V power supply with a 9V battery, i thought maybe there isn't enough current for the flow sensor but no luck) and the sensor input is connected to digital pin 2 for interrupt.
3- The code:
/*
Measure the liquid/water flow rate using this code.
Connect Vcc and Gnd of sensor to arduino, and the
signal line to arduino digital pin 2.
*/
byte statusLed = 13;
byte sensorInterrupt = 0; // 0 = digital pin 2
byte sensorPin = 2;
// The hall-effect flow sensor outputs approximately 4.5 pulses per second per
// litre/minute of flow.
float calibrationFactor = 4.5;
volatile byte pulseCount;
float flowRate;
unsigned int flowMilliLitres;
unsigned long totalMilliLitres;
unsigned long oldTime;
void setup()
{
// Initialize a serial connection for reporting values to the host
Serial.begin(9600);
// Set up the status LED line as an output
pinMode(statusLed, OUTPUT);
digitalWrite(statusLed, HIGH); // We have an active-low LED attached
pinMode(sensorPin, INPUT);
digitalWrite(sensorPin, HIGH);
pulseCount = 0;
flowRate = 0.0;
flowMilliLitres = 0;
totalMilliLitres = 0;
oldTime = 0;
// The Hall-effect sensor is connected to pin 2 which uses interrupt 0.
// Configured to trigger on a FALLING state change (transition from HIGH
// state to LOW state)
attachInterrupt(sensorInterrupt, pulseCounter, FALLING);
}
/**
* Main program loop
*/
void loop()
{
if((millis() - oldTime) > 1000) // Only process counters once per second
{
// Disable the interrupt while calculating flow rate and sending the value to
// the host
detachInterrupt(sensorInterrupt);
// Because this loop may not complete in exactly 1 second intervals we calculate
// the number of milliseconds that have passed since the last execution and use
// that to scale the output. We also apply the calibrationFactor to scale the output
// based on the number of pulses per second per units of measure (litres/minute in
// this case) coming from the sensor.
flowRate = ((1000.0 / (millis() - oldTime)) * pulseCount) / calibrationFactor;
// Note the time this processing pass was executed. Note that because we've
// disabled interrupts the millis() function won't actually be incrementing right
// at this point, but it will still return the value it was set to just before
// interrupts went away.
oldTime = millis();
// Divide the flow rate in litres/minute by 60 to determine how many litres have
// passed through the sensor in this 1 second interval, then multiply by 1000 to
// convert to millilitres.
flowMilliLitres = (flowRate / 60) * 1000;
// Add the millilitres passed in this second to the cumulative total
totalMilliLitres += flowMilliLitres;
unsigned int frac;
// Print the flow rate for this second in litres / minute
Serial.print("Flow rate: ");
Serial.print(int(flowRate)); // Print the integer part of the variable
Serial.print("L/min");
Serial.print("\t"); // Print tab space
// Print the cumulative total of litres flowed since starting
Serial.print("Output Liquid Quantity: ");
Serial.print(totalMilliLitres);
Serial.println("mL");
Serial.print("\t"); // Print tab space
Serial.print(totalMilliLitres/1000);
Serial.print("L");
// Reset the pulse counter so we can start incrementing again
pulseCount = 0;
// Enable the interrupt again now that we've finished sending output
attachInterrupt(sensorInterrupt, pulseCounter, FALLING);
}
}
/*
Insterrupt Service Routine
*/
void pulseCounter()
{
// Increment the pulse counter
pulseCount++;
}
When checking the pulseCounter in serial monitor, i get distinct values (like 250 then suddenly 30 then 230 etc.) and since the pulseCounter is so darn wrong, the flowRate is as well (i am getting 30 L / min from a pump that is rated 90L/ h) and it doesn't stick to 30 its goes down to 3 then random values and that's while the pump is working normally with constant water flow. What i want to know what i am doing wrong? Hardware wise i can take a picture of the tubing and flow converter that is connected to the flow sensor since the pump has a small dispenser i had to get a converter. Thank you
Did you try to calibrate your flow sensor? Different types have different pulse counts per flow.
Start by printing the number of ticks you measure per second. That should be reasonably constant. Make sure all wires are connected properly, and that the Arduino has a proper power supply (preferably a regulated 5V supply to the Vcc/5V pin). Don't power your pump through the Arduino.
Bahij_mik:
with a 9V battery, i thought maybe there isn't enough current for the flow sensor
If, by 9v, you mean a 9v PP3 battery, you are dead right and should get rid of it immediately.
When checking the pulseCounter in serial monitor, i get distinct values (like 250 then suddenly 30 then 230 etc.) and since the pulseCounter is so darn wrong, the flowRate is as well (i am getting 30 L / min from a pump that is rated 90L/ h) and it doesn't stick to 30 its goes down to 3 then random values and that's while the pump is working normally with constant water flow.
Everything may well be pretty normal, the code may actually be quite kosher, and it never takes much to get a pump to deliver less than the data sheet tells you. Measure the quantity over a decent period of time, check the reality, and then start talking about it. You may find that the only thing you need is a minor tweak of the calculation factor, but it is not clear that you really need the RATE at all, yet that is where you are identifying a problem.
What i want to know what i am doing wrong?
In the light of what you have said, I suspect the problem is your refusal to understand what is going on.
Yes a 9V PP3 connected to a power supply module that gives 5V, the issue at hand isn't from the pump, its working fine, and i did some trial and error, the pump is actually delivering the advertised quantity, what i was thinking was that the issue is from the tubing and converter as posted above. Since if it was code wise, the input that is coming directly from flow sensor (Pulses) shouldn't vary that much when the water is flowing in a constant rate, correct me if i am wrong and thank you, i am not much of a hardware guy, i am a mobile developer that's helping his niece so please bear with me.
However, he procedure you use to detach and reattach the interrupt is not recommended and can lead to unintended interrupts. Better is to briefly disable global interrupts, transfer the data from the isr to a transfer variable, and re-enable global interrupts. Then perform all calculations with the transfer variable.
/*
Measure the liquid/water flow rate using this code.
Connect Vcc and Gnd of sensor to arduino, and the
signal line to arduino digital pin 2.
*/
byte statusLed = 13;
byte sensorInterrupt = 0; // 0 = digital pin 2
byte sensorPin = 2;
// The hall-effect flow sensor outputs approximately 4.5 pulses per second per
// litre/minute of flow.
float calibrationFactor = 4.5;
volatile byte pulseCount;
byte copy_pulseCount; //safe copy transfer variable
float flowRate;
unsigned int flowMilliLitres;
unsigned long totalMilliLitres;
unsigned long oldTime;
void setup()
{
// Initialize a serial connection for reporting values to the host
Serial.begin(9600);
// Set up the status LED line as an output
pinMode(statusLed, OUTPUT);
digitalWrite(statusLed, HIGH); // We have an active-low LED attached
pinMode(sensorPin, INPUT);
digitalWrite(sensorPin, HIGH);
pulseCount = 0;
flowRate = 0.0;
flowMilliLitres = 0;
totalMilliLitres = 0;
oldTime = 0;
// The Hall-effect sensor is connected to pin 2 which uses interrupt 0.
// Configured to trigger on a FALLING state change (transition from HIGH
// state to LOW state)
attachInterrupt(sensorInterrupt, pulseCounter, FALLING);
}
/**
* Main program loop
*/
void loop()
{
if((millis() - oldTime) > 1000) // Only process counters once per second
{
// Disable the interrupt while calculating flow rate and sending the value to
// the host
//detachInterrupt(sensorInterrupt);
noInterrupts();
copy_pulseCount = pulseCount;
pulseCount = 0;
interrupts();
// Because this loop may not complete in exactly 1 second intervals we calculate
// the number of milliseconds that have passed since the last execution and use
// that to scale the output. We also apply the calibrationFactor to scale the output
// based on the number of pulses per second per units of measure (litres/minute in
// this case) coming from the sensor.
flowRate = ((1000.0 / (millis() - oldTime)) * copy_pulseCount) / calibrationFactor;
// Note the time this processing pass was executed. Note that because we've
// disabled interrupts the millis() function won't actually be incrementing right
// at this point, but it will still return the value it was set to just before
// interrupts went away.
oldTime = millis();
// Divide the flow rate in litres/minute by 60 to determine how many litres have
// passed through the sensor in this 1 second interval, then multiply by 1000 to
// convert to millilitres.
flowMilliLitres = (flowRate / 60) * 1000;
// Add the millilitres passed in this second to the cumulative total
totalMilliLitres += flowMilliLitres;
unsigned int frac;
// Print the flow rate for this second in litres / minute
Serial.print("Flow rate: ");
Serial.print(int(flowRate)); // Print the integer part of the variable
Serial.print("L/min");
Serial.print("\t"); // Print tab space
// Print the cumulative total of litres flowed since starting
Serial.print("Output Liquid Quantity: ");
Serial.print(totalMilliLitres);
Serial.println("mL");
Serial.print("\t"); // Print tab space
Serial.print(totalMilliLitres/1000);
Serial.print("L");
// Reset the pulse counter so we can start incrementing again
//pulseCount = 0;
// Enable the interrupt again now that we've finished sending output
//attachInterrupt(sensorInterrupt, pulseCounter, FALLING);
}
}
/*
Insterrupt Service Routine
*/
void pulseCounter()
{
// Increment the pulse counter
pulseCount++;
}
Seeing that image I immediately noticed you're not giving us the full picture. There are two components that you did not mention: one that looks very much like an ultrasound sensor, another that looks very much like an LCD display. This is a very common fault of people seeking help, and why we're asking all those questions, and why you should answer all the questions posed - especially your circuit and power supply. Remember: the problem tends to be in the part you didn't post.
The pump looks like it's connected to 1/2" hose connectors; what is rating of the flow sensor? Another part you left out: which exact sensor you use. As your pump is rated 90 l/hr, so you're probably getting more like 60 l/hr or 1 l/min in real life, a very low flow. At the low end of their rated range these flow sensors are not reliable, drop below their rated minimum and all bets are off.
You're calculating every second - make that a longer period, to get more of an average. That may also smooth things out, especially as you're getting these low flow rates.
You can't run a pump from Arduino 5V pin, what is the part number of the 3 legged object with "N" on it? Where is the flow meter on that Fritz picture?
Bahij_mik:
Yes a 9V PP3 connected to a power supply module that gives 5V, the issue at hand isn't from the pump, its working fine, and i did some trial and error, the pump is actually delivering the advertised quantity, what i was thinking was that the issue is from the tubing and converter as posted above. Since if it was code wise, the input that is coming directly from flow sensor (Pulses) shouldn't vary that much when the water is flowing in a constant rate, correct me if i am wrong and thank you, i am not much of a hardware guy, i am a mobile developer that's helping his niece so please bear with me.
If you insist on using a PP3, you deserve all the grief you will surely get - later if not sooner. The pump is very small so you need a very small turbine, perhaps a Swissflow, which use a faster turbine. Dodgey or not, the code is probably not causing the variation, and you still haven't explained why you need rate rather than an event. Be that as it may you can be sure you will never get an even reading, but you might get something more comfortable if you use a longer time span, or average the readings you are taking now. Constant flow is not what you think it is and, I suspect hardly relevant anyway.
Hey guys, i would like to thank everyone for their input, i will be applying everything said(The interrupt and increasing time interval when interrupting) after i finish work, at the moment i need:
1- A website if available so that i can draw my diagram and show the whole thing.
2- What outer power source is recommended, as Nick_Pyner said the 9V PP3 battery is bad, what should i be using ?
3- Something came on my mind today, which is will the pump suck air when there is no water left causing the pinwheel on the flow sensor to spin giving wrong values (as if there is water passing through it), and therefore not stopping the pump?
4- The other parts used are: Ultrasonic sensor HC-SR04, a 16x2 LCD that prints if the pump is on or off and shows the level of the water, and a Bluetooth Module HC-05, i didn't mention these parts before since when i am debugging this flow issue i am not using any of the other parts, only the pump and flow meter are used.
Bahij_mik:
2- What outer power source is recommended, as Nick_Pyner said the 9V PP3 battery is bad, what should i be using ?
Battery power is an art in itself, and probably starts with using something other than a Uno. If you must stick with it, at least get a decent 5v regulator. You can then use virtually anything other than a 9v PP3, and convenient packages might be 6xAAs or 2x18650s, but sticking with a 9v wall wart to make sure things are right to start with, is a good idea.
3- Something came on my mind today, which is will the pump suck air when there is no water left causing the pinwheel on the flow sensor to spin giving wrong values (as if there is water passing through it), and therefore not stopping the pump?
Well, there's a good question, and I guess you will have to suck it and see. The pump is very weak bu, even if it is not positive displacement, it may actually blow some air and the sensors don't need much to show some flow. I'm sure the pump will displace a lot less air than water and the sensor sense a lot less air than water, so it shouldn't be too hard to get a go/no go situation.
Bahij_mik:
1- A website if available so that i can draw my diagram and show the whole thing.
EasyEDA or Circuitlab maybe?
Otherwise install KiCAD or EagleCAD. Both are free (though KiCAD is freer than EagleCAD) and both are great pieces of software for making schematic drawings.
2- What outer power source is recommended, as Nick_Pyner said the 9V PP3 battery is bad, what should i be using ?
A 5V regulated power source. Such as a mobile phone charger. Should be able to supply 1-1.5A, more is fine as well. Connect it to the 5V pin of the Arduino and a separate wire to the pump.
3- Something came on my mind today, which is will the pump suck air when there is no water left causing the pinwheel on the flow sensor to spin giving wrong values (as if there is water passing through it), and therefore not stopping the pump?
That's easy to test.
Almost certainly not. I suppose you're using an impeller type pump, they don't pump air at all. If you have such a pump running in air, then drop it (running) in the water, it may not even start pumping as there's air trapped in the pump.
Hey guys, can someone please give me a diagram how to connect a 5V pump to an outer source ( like a 9v wall wart) while controlling it through arduino Digital pin (HIGH LOW) ?