I'm using a Gems flow sensor (173940-C) to measure the amount of water flowing through a drinking fountain
I'm using 10k pull up resistor between the signal pin and the 5v pin
The according to the data sheet 1 pulse = 1 ml of water for this particular model
I have confirmed the sensor is working by simply displaying the digital pin's state and saving the data using Cool term which I later then counted in excel and for a 500ml bottle I get approx 500 pulses
The issue is, when i try to count the pulses using a rising edge Interrupt within Arduino, I dont get the same amount of pulses, its always a lot higher, I suspect that the interrupt is being triggered too often or incorrectly, does anyone know why this could be?
Thanks in advance
#define debugSerial Serial
const int flowPin = 2; //This is the input pin on the Arduino
volatile unsigned int PulseCount = 0; //This integer needs to be set as volatile to ensure it updates correctly during the interrupt process.
unsigned long currentTime ;
unsigned long StartTime = 0;
void setup() {
// initialize digital pin LED_BUILTIN as an output.
pinMode(LED_BUILTIN, OUTPUT);
pinMode(flowPin, INPUT); //Sets the pin as an input
Serial.begin(9600);
attachInterrupt(digitalPinToInterrupt(2), Flow, FALLING); //Configures interrupt 0 (pin 2 on the Arduino Uno) to run the function "Flow"
}
void loop() {
currentTime = millis();
if (currentTime >= (StartTime + 1000)) //occurs every 1 seconds - take a reading
{
Serial.print ("Pulse Count: ");
Serial.println (PulseCount);
StartTime = millis();
}
}
void Flow() {
PulseCount++; //Every time this function is called, increment "PulseCount" by 1
}
I have noticed that the method described in the original post:
"I have confirmed the sensor is working by simply displaying the digital pin's state and saving the data using Cool term which I later then counted in excel and for a 500ml bottle I get approx 500 pulses"
is polling as I'm simply using digitalread(2) to constantly print the pin state
whereas the method I'm trying to implement is ISR, why would polling give me the correct value but not ISR?
I'm attempting to read the output of a flow sensor, when I use an interrupt to detect a pulse and increment a variable, the output isnt giving the expected answer however when I poll the pin , export the data using cool term and count the pulses, I get the correct value why would this be??
code for interrupt:
#define debugSerial Serial
const int flowPin = 2; //This is the input pin on the Arduino
volatile unsigned int PulseCount = 0; //This integer needs to be set as volatile to ensure it updates correctly during the interrupt process.
unsigned long currentTime ;
unsigned long StartTime = 0;
void setup() {
// initialize digital pin LED_BUILTIN as an output.
pinMode(LED_BUILTIN, OUTPUT);
pinMode(flowPin, INPUT); //Sets the pin as an input
Serial.begin(9600);
attachInterrupt(digitalPinToInterrupt(2), Flow, FALLING); //Configures interrupt 0 (pin 2 on the Arduino Uno) to run the function "Flow"
}
void loop() {
currentTime = millis();
if (currentTime >= (StartTime + 1000)) //occurs every 1 seconds - take a reading
{
Serial.print ("Pulse Count: ");
Serial.println (PulseCount);
StartTime = millis();
}
}
void Flow() {
PulseCount++; //Every time this function is called, increment "PulseCount" by 1
}
code for polling:
void setup() {
pinMode(2, INPUT); //Sets the pin as an input
Serial.begin(9600);
}
void loop() {
Serial.println(digitalRead(2));
}
If you were polling and printing every pulse, depending on how much text, it's possible that your slow Serial speed may have interfered with your initial test results. Running at 115200 would be safer. Better yet, just count the pulses and print them periodically as you did above.
Have you verified that the part you have is actually a 73940-C?
Delta_G:
Switch might be bouncing. You don't really give any information on how the one is wrong, is it too many or too few. But I bet it is too many. The serial print in the second probably slows things down enough that the switch bounce gets missed.
if (currentTime >= (StartTime + 1000))
That's a bug. You should rewrite that with subtraction the way it is in the Blink Without Delay example.
Sorry I forgot to add more context,
I've got a 10k pull up resistor between the signal pin and the 5v pin which I assume eliminated the floating/debounce issue but maybe I've misunderstood how it works
When I use ISR method, I get too many pulses, near double what I'm expecting
In terms of "if (currentTime >= (StartTime + 1000))" being a bug, could you elaborate a bit more please? I'm happy to switch it to subtraction but I just want to know why.
I didnt use the internal pull up resistor as I originally thought that it was the culprit for my bad readings but I'm starting to realise that this is not the case now
Ok I understand bouncing and how it affects a switch or button but my input is a hall effect flow sensor (Gems flow sensor 173940-C) which from my understanding wouldn't be subject to the same issue but I'll look into that now and implement one of the fixes suggested
Thanks for the clarification on the timings, I never even considered roll over
wildbill:
If you were polling and printing every pulse, depending on how much text, it's possible that your slow Serial speed may have interfered with your initial test results. Running at 115200 would be safer. Better yet, just count the pulses and print them periodically as you did above.
Have you verified that the part you have is actually a 73940-C?
I'm confident that the results obtained by polling are accurate as they align with the datasheet (1ml = 1 pulse) and I've been using bottles and cups with known volumes to conduct tests.
I'd rather not use polling because there are other processes I want to run and ultimately I would like to make this a battery powered device and from my understanding, polling is quite power inefficient compared to using an ISR
I can confirm that the sensor is the 73940-C model
Someone suggested that this could be a bounce issue however I thought that was only applicable to buttons and switches, I'm using a hall effect flow sensor so I will have to go away and research some more
whizz5:
I'm using 10k pull up resistor between the signal pin and the 5v pin
I'm not familiar with this type but, apart from the price, it seems like any other hall effect flow sensor, and they usually connect to Arduino pin 2 via a 10k series resistor - no pull up, no pull down.
I have tested your interrupt driven original program using a ~54Hz (555-based) oscillator. You can see the the output of your program in the following screenshot (Fig-1). Why is the output getting count added in every second? It should always be close to ~54 (Fig-2).
Figure-1: Output of the incorrect program
Figure-2: Output after correcting the mistakes of the program
Not too sure what you've done but I've run the code and didnt have the same issue (see attached screenshot), there's nothing within the code that adds the pulse count to itself so could you please explain what it is that you've "corrected"
Just to clarify I'm running this on a TTN UNO board (based on an Arduino Leonardo)
Delta_G:
Not sure what he did in the program, but you could accomplish that by simply setting pulseCount back to 0 when you print it (in a critical section of course).
Exactly, this is what I have added with OP's program.
You can place the images on line by following these tips:
1. After attaching the image file, save the post.
2. Right Click on the attached file name and copy the link address.
3. Open the post in modify mode.
4. Place the cursor where you want to place the image.
5. Click on the Insert an image icon of the Tools bar. A window will appear and place the cursor in the input box. Press button cntrl+V on the keyboard. The link will appear in the input box. Click on OK button of the window. Save the post. Check that the image has appeared online.
Firstly thanks for taking the time to help with this issue and apologies for not giving all the information.
What I want to do is measure the volume of water coming from a water dispenser using a flow sensor (Gems flow sensor 173940-C) and an arduino (TTN UNO based on the Arduino Leonardo)
The flow sensor outputs pulses and according to the data sheet 1 pulse = 1 ml of water so from my understanding no calibration factor is needed
The issue I'm having is that when I try to count the amount of pulses using an ISR I get a value thats approx double what I'm expecting (for a 200ml cup I'm getting around 400 pulses)
When I constantly poll the the pin and manually count the pulses I get a value of approx 200 pulses (I say approx because I dont always fill the cup to exactly 200ml)
What I wanted to know is why the ISR is miss-firing/detecting additional pulses.
I havent done PulseCount = 0 purely because it makes reading the total amount of water easier ( seeing that I've just filled 200ml rather than seeing and having to add 54ml ,32 ,76 and 38ml etc) at a later stage I will implement PulseCount = 0 after storing the value elsewhere but for now I just want to get the correct value using ISR if possible
I would like to get the ISR method working as from my understanding, constantly polling the input is not an efficient method and I also would like to have other processes occurring at a later stage in the project
When I am polling the output of my ~54 Hz oscillator, I am getting exactly the same value that I was getting in the interrupt driven process.
The Codes (Polling Process)
//#define debugSerial Serial
const int flowPin = 2; //This is the input pin on the Arduino
volatile unsigned int PulseCount = 0; //This integer needs to be set as volatile to ensure it updates correctly during the interrupt process.
unsigned long currentTime ;
unsigned long StartTime = 0;
bool flag1 = LOW;
void setup()
{
// initialize digital pin LED_BUILTIN as an output.
pinMode(LED_BUILTIN, OUTPUT);
pinMode(flowPin, INPUT_PULLUP); //Sets the pin as an input
Serial.begin(9600);
// attachInterrupt(digitalPinToInterrupt(2), Flow, FALLING); //Configures interrupt 0 (pin 2 on the Arduino Uno) to run the function "Flow"
}
void loop()
{
if (flag1 != HIGH)
{
if (digitalRead(2) == LOW)
{
PulseCount++;
flag1 = HIGH;
}
}
if (digitalRead(2) == HIGH)
{
flag1 = LOW;
}
if (millis() - StartTime == 1000)
{
Serial.print ("Pulse Count: ");
Serial.println (PulseCount);
StartTime = millis();
PulseCount = 0;
}
}