Having Trouble with a flow meter and interrupts

Im trying to connect a Boron to a Seametrics AG3000 flowmeter. Ive connected to and AG2000 before, no problems, but I must be missing something on the new model.

I should be getting about 900gpm or 90 pulses a minute, but instead I am getting over 30,000 a minute

Ive tried changing every component from the boron to the wire that connect to the seametrics, nothing changes.

On the breadboard image it is on pin D7, but currently, I am using D5, since there is a status led tied to D7 and I thought that might be the issue.

Attached is the reference from the seametrics manual Link to Manual
unnamed

my breadboard

this is my code


int flowmeter = D5; //flowmeter pin
int pulses = 0; //total pulses
double timeMillis = 0; //time last calculated
int previousPulses = 0; //total pulses last time caluculated
int gpmMultiplier = 10;  //gallons per pulse
int reportInterval = 60000;
void flowinterrupt () {
   pulses++;
}

void setup() {
    
    pinMode(flowmeter, INPUT);
     timeMillis = 0;
    attachInterrupt(flowmeter, flowinterrupt, RISING);
    
}

void loop() {
    int timeDif = millis()-timeMillis;
if (timeDif >= reportInterval) {
    timeMillis = millis();
    int gpm = (pulses-previousPulses)/(timeDif/60000);
    //current pulses subtract last pulses gets pulses since last reported
    //time passes divided by one minute in milliseconds
    
    previousPulses=pulses;
    Particle.publish("GPM", String(gpm));
     Particle.publish("Gallons", String(pulses*gpmMultiplier));
}
}

I assume you have set the pulse rate per unit of volume correctly, but it never hurts to double check :wink:

BTW, instead of two publishes for your readings you can place all your data into one and save on data operations.

  char data[64];
  snprintf(data, sizeof(data), "%d gal/min, %d gal", gpm, pulses*gmpMultiplier);
  Particle.publish("flowData", data);

I`d also change the order of execution in your calculation to reduce “rounding” errors

  int gmp = 60000*(pulses-previousPulses) / timeDif;

and for the same reason: Why don’t you use float instead of int. Integer divisions are notoriously “problematic” when you aren’t fully aware of what they do under the hood :wink:

Hey Scruff,

The pulse rate is set to 10 gpm, the damp is set to 1.

Ive tried setting the pulse to 1 gpm, the damp to 30, 60, lots of things.

I’ll make those code changes, thanks!

I’m wondering if its a wire issue. The sensor is about 12-15 feet away, I’ve tried 22 awg, 14 awg, and even some 18 awg solid I had. Wondeing if I need to use shielded cable or try something twisted like Cat6, could noise be messing with the pulses to this extent?

Thanks

The gauge of the wire mainly impacts the voltage loss and maximum current you can transport but doesn’t change how susceptible the setup is for EMI (especially with a cell modem chattering next to it :wink: )
For your setup a shielded twisted pair cable would be more important than having a big gauge wire - you are not running loads of current across it.

However, having only 3.3V over that length may still be pushing it.

So I’d first see whether considerably shorter wires (a few centimetres) gets rid of the issue.
If so, you found the culprit and can search for the best solution.
If not, I’d have a look at the actual signal your controller receives (e.g. oscilloscope)

1 Like

What ScruffR said. Also, I would switch it to the second example - current sinking mode and using a pull-up resistor instead of a pull-down. The sensor datasheet recommends this for Rin > 30K and that’s what the Boron input is.

Also double-check the sensor polarity. That sensor is not a plain hall-effect switch. It’s an open-collector driver, so the + and - really make a difference. If you wire it backwards it definitely won’t read correctly.

3 Likes

Hey Rick,

I tried using the circuit from the second example. Same issues. Ive tried it with a 47k res pullup, a 1k pullup, and a 330 pull up, using a falling interrupt, same thing.

The pulse counts do increase and decrease with the waterflow, but, to an extreme high reading.

Ive checked the polairty a hundred times and even still tried running it in reverse just in case.

Ive been trying to avoid moving everything closer, I’m right next to power where i’m at. But Ive pretty much run out of other things to try.

Will powering the unit through the vusb pin possibly mess with the interrupts?

Try making the variable involved with the ISR volatile. Instead of

try

volatile int pulses = 0; //total pulses

Here is a link to the docs where volatile is discussed in the last paragraph:
https://docs.particle.io/cards/firmware/interrupts/attachinterrupt/

Give that a shot and see what happens.

I'll count on what @ScruffR said,

especially that T/S section of manual pointing the same :wink:

I took a look at your code and found

where the data type is a floating point. I think you meant to utilize the variable as an integer type. So, instead of double

try uint32_t or unsigned long

@Rftop has posted a Not tested, but this might get you started: example in another thread. It is not a solution for your particular question but I mention it because the example presented is easy to read and follow. While looking at it I discovered the data type issue above.
https://community.particle.io/t/having-trouble-with-flow-meter-still-showing-value-when-not-running/43578/5

I also agree with all the great comments.

I’d try shielded Cat5, only use 1 pair, and only connect the drain wire on 1 end.
Make sure to route the cable far away from the well motor if it’s nearby.
Can you check your cable run by leaving the flow meter unconnected to see if the Boron is registering a “flow” from noise ?

This is a long shot, but I’ve had a meter accidently set to Pulse Width (instead of Pulse Out) before, which was a pain to troubleshoot. I didn’t read your datasheet, but it might be worth a mention.

The good thing about Open Collector Pulse Meters is you can confirm operation with just a simple multimeter, since you are expecting a pulse every 1.5 seconds. Once you know the Open Collector output is working, it’s just a matter of Shielded Wiring to make sure the full 3.3V reaches the pin (for Sink Mode).
For Field Testing, it may help to temporarily change to Pulse value to something higher than 10 gallons, just to give you more time to confirm the Hi/Low of the Pulse Out at the Flow Meter with a Multimeter.

2 Likes

Hey Guys,

Still working on this, things picked up on the ranch so I had to take a small break from it.

I’ve tried all the things.

I even had a twisted pair of shielded 22awg made and delivered.

No change. The readings are extremely consistent, 0 when the pump is off, reporting 28571 gpm right now when is should be more like 550gpm, though when I increase or decrease the volume of water the readings move with the flow. I have another unit running with the AG2000 their older model, no issues, same code, circuit, but unshielded wire.

I am wondering right now if its an issue with voltage on the newer unit, maybe the 3.3v out on the particle doesn’t get enough there to fully activate the open collector? Its a little above my head at this point. I wrote to sea metrics to ask if the pulse on this unit really is the same as their older model.

Will the interrupt still work with a voltage divider? I can connect it to 5v power … …

Let's see your updated code. :slightly_smiling_face:

1 Like

There have been about 30 different variations of code to test this thing, here’s the most simplified one. None made a difference, and the fact that it works with the older model flow meter tells me its probably not the code at this point. Maybe more sensitive to interference, doesn’t like the low voltage, or something is different.

Trying to think of a way to test with higher voltage, outside of that, not sure.

int flowmeter = D5; //flowmeter pin
volatile int pulses = 0; //total pulses
double timeMillis = 0; //time last calculated
int previousPulses = 0; //total pulses last time caluculated
int gpmMultiplier = 10;  //gallons per pulse
int reportInterval = 60000;
void flowinterrupt () {
   pulses++;
}

void setup() {
    
    pinMode(flowmeter, INPUT);
     timeMillis = 0;
    attachInterrupt(flowmeter, flowinterrupt, RISING);
    
}

void loop() {
    int timeDif = millis()-timeMillis;
if (timeDif >= reportInterval) {
    timeMillis = millis();
    int gpm = (pulses-previousPulses)/(timeDif/60000);
    //int gpm = 60000*(pulses-previousPulses) / timeDif;
    //current pulses subtract last pulses gets pulses since last reported
    //time passes divided by one minute in milliseconds
    
    previousPulses=pulses;
    
     char data[64];
  snprintf(data, sizeof(data), "%d gal/min, %d gal", gpm, pulses*gpmMultiplier);
  Particle.publish("flowData", data);
  
    
}
}

@ShakerBreaker, do you have an external pull-up resistor connected to D5? If you do, what value is it?

An open-collector output will go to GND and float otherwise. This is why you need a pull-up. The longer the wire, the stronger the pull-up (lower value) you need typically, due to wire capacitance affecting the signal rise-time. So I assume you have a common ground connecting both the meter and the Boron. Knowing this, I would make the interrupt FALLING though either will work, but since the meter pulse is “active” when it goes low.

1 Like

Hey,

I’ve tried both circuit styles, the one for the posted code connects 3.3v to the positive, the ground to d5 with an external 47k pull down

When I tried using the other circuit style, I tried a 330 pull up since that was the smallest one recommended in the documentation, I also tried 1k, 10k, and 47k

Though I haven’t tried all of these with the shielded wire yet.

One you would recommend trying?

Thanks

you are mixing data types unsigned long (which is returned by millis())
millis_data_type

double

and int.

just try the suggestions from @robc

Ya, that wouldn't work if you grounded pin D5! I would recommend a 2.2K or 1K ohm pull-up close to D5, connected to the output of the meter. Also, what @dreamER said is VERY important!

1 Like

hey peaky, I misspoke, more precisely its the negative or return from the pulse that goes to d5 with the 47k pulldown.

it’s not the best way to do it, I am understanding, but it’s the recommended schematic from their manual, and it’s been working fine with both the electron and now the boron on their older model flow meter for over a year at my other pump.

I’ll try it out on the positive side with a 2.2k and a 1k with the shielded wire over my next irrigation.

Like so?

int flowmeter = D5; //flowmeter pin
volatile int pulses = 0; //total pulses
unsigned long timeMillis = 0; //time last calculated
int previousPulses = 0; //total pulses last time caluculated
int gpmMultiplier = 10;  //gallons per pulse
int reportInterval = 60000;
void flowinterrupt () {
   pulses++;
}

void setup() {
    
    pinMode(flowmeter, INPUT);
     timeMillis = 0;
    attachInterrupt(flowmeter, flowinterrupt, RISING);
    
}

void loop() {
    int timeDif = millis()-timeMillis;
if (timeDif >= reportInterval) {
    timeMillis = millis();
    int gpm = (pulses-previousPulses)/(timeDif/60000);
    //int gpm = 60000*(pulses-previousPulses) / timeDif;
    //current pulses subtract last pulses gets pulses since last reported
    //time passes divided by one minute in milliseconds
    
    previousPulses=pulses;
    
     char data[64];
  snprintf(data, sizeof(data), "%d gal/min, %d gal", gpm, pulses*gpmMultiplier);
  Particle.publish("flowData", data);
  
    
}
}