Having Trouble with a flow meter and interrupts

no no no leave everything connected as is and then just bypass somehow the flow meter with some 3 way pipe connector and directional valve which will directed water flow through the bypass pipe just to omit the flow meter. I know that this can be pain in the a… but I guess is worth to try to eliminate all potential issues

I can divert the flow, into the standpipe, for a bit, should give us the test we are looking for.

At this point I’m thinking maybe somethings just wrong with the flow meter.

I’ll try this test and let you know

1 Like

Perfect :+1: even if you can disengage the motor from pump just to check if EMI from VFD didn’t apply any noises will be worth to check also honestly I can’t catch what the manual is taking about :crazy_face: regarding this section:


What is te frequency involved for ??? And pulse width??? Maybe it’s related to what @Rftop mentioned:

Seametrics manuals are the worst.

When I first set this up on an ag 2000, the instructions were one sentence, that it had pulse output… and that’s it

I can’t find any way to even check this. I just heard back from seametrics, finally, and its just a canned copy paste from their instruction manual. with nothing about this.

How do I check?

@peekay123 @ScruffR @rickkas7 @Rftop @robc coud you guys please give any advice/hint :pray:

Well…

I diverted the flow and the pulses increased.

Not really sure what to do with that.

I also connected my multimeter on the screw terminal while water was flowing, I can see the voltage dropping with each pulse. From 3.2 to somewhere between 2 and 2.6, I can count the pulses, and it seems correct. I’d upload the video but it’s not letting me.

So ok we got it :+1: some of VFD’s has embedded EMC filters which you can enable with just a one bolt (somewhere on side of VFD) if not you can use external one e.g:
https://www.digikey.ca/en/products/detail/kemet/FLLD4064ATHT5/7173831?utm_adgroup=Kemet&utm_source=google&utm_medium=cpc&utm_campaign=Smart%20Shopping_Supplier_Kemet&utm_term=&productid=7173831&gclid=EAIaIQobChMInvb_0fSS8QIVTgytBh1x2QGjEAQYASABEgJVHPD_BwE

Also I’ll recommended this kind of wire
From VFD to pump/motor
https://www.digikey.ca/en/products/detail/alpha-wire/1942%2F3F%20BK003/6030796?utm_adgroup=Cable%20%2C%20Wires&utm_source=google&utm_medium=cpc&utm_campaign=Shopping_Supplier_Alpha%20Wire_0216_Co-op&utm_term=&productid=6030796&gclid=EAIaIQobChMIxcK_5vSS8QIVMT2tBh0Y9wdPEAQYAiABEgKlgfD_BwE

And ground all as good as possible

You and @ShakerBreaker are doing a nice job together solving this puzzle.

Looks like noise is causing issues on D5 input. All I can suggest is to put the following info and/or statements in the code so we all know what we are dealing with as far as the Boron device goes:

What os? (2.1.0 for example)
Are you using the following statement:

SYSTEM_THREAD(ENABLED);

If you have not already tried it, use a different input pin, like D4 or D6.

Last, I would try installing a LiPo battery on the Boron device. My reasoning is only that I have never used a Boron without a battery attached.

1 Like

Hold up,

This thing is 25’ away from both the pump and vfd. It is stand alone and not connected to the vfd in any way.

Hey Rob,

Great minds think alike, today I tested it on d3 with battery attached, no change.

The os running is 3.0 r2

I’m not using that statement, should I?

I might try wrapping the whole thing in conduit… not sure what else to try if it’s from noise. There’s a lot of metal, and there’s a lot of noise.

I would. Here is where it goes before setup():

SYSTEM_THREAD(ENABLED);         //  uncomment to activate   

void setup() {   
...

Perfect length for antenna :grin:
I remember long time ago I played with some scale amplifier with Modbus
They sent data to PLC and the PLC controlls dumping motors via VFD’s and some PID implementation so when all was off and I put some knowledge weight on scale the PLC registered pefect values but just when I turned on the motors the harmonic EMI symphony starts and weight jump from 0 to 800g and then -200g etc.
As soon as I used EMC filters and shield cables from motors to VFD then grounded all possible metall parts
All starts working!

@ShakerBreaker I got gently s... up advice :man_shrugging:t3: so I’ll love to see others idea

Hey Dream,

I understand, thanks for all your help.

That pump won’t be running again for at least a week, so I have some time to plan things out before the next test.

I’m super nervous about touching anything on the vfd… not sure if I can risk it, I just don’t know enough about it.

I might try mounting a box right to the outlet on the meter and wrapping the whole thing in some kind of shielding, then use a different board to collect the pulse and send it to the boron…

There's your problem.
That's going to cause havoc with erroneous interrupts.

Hey Rf,

How do I address this? Do you think it’s pulling too much power from the 3.3 pin causing the voltage to drop? The power supply is 5v 3A through the usb

Are you seeing these pulses on your multimeter about every 1.5 seconds? That seems about right.

I am thinking there is a huge interrupt queue at startup and that queue is overwhelming or flooding the loop(). It will take a little bit of time but I want to change your code to implement this additional statement:

detachInterrupt(flowmeter);     //  turn off low-level interrupts for the pin

in addition, when we startup the interrupt process, we need to burn or kill the first interrupt ISR result just to be sure we are at the true beginning of input interrupts:

attachInterrupt(flowmeter, flowinterrupt, FALLING);
flowPulseDetected = LOW;  //  kill any processing of interrupts occuring JUST NOW from above statement

then process the interrupts normally.

Hey Rob,

In a 27 second video there are 17 pulses.

I have tested the pulses of interrupts a few times by having the unit running counting 0 while the water comes on and also by turning it on after the fact, I’ve also previously run code that purged everything after the first minute cycle, no change.

I will test these again, but it sounds like it might be 2 weeks or so before that pump is run again.

Hey, @ShakerBreaker
Here is your modified program you can try next time you get a chance. I hope it works for you. Let me know if I made a mistake or if you have any questions. I apologize for not thinking of this sooner. After @dreamER 's shout-out for assistance it finally dawned on me I have dealt with a similar interrupt issue before.

Thanks to all the contributors in this thread. I want to install a flow meter someday. I think I learned quite a bit. :wink:

To make a long story short, I believe a low-level interrupt, for the pin, was never cleared in the original code. Thus, causing another almost instant hit on the ISR even though we thought we had cleared the interrupt. This may be why there were so many calls of the ISR (in the tens of thousands per minute).

//  device: Particle Boron LTE    os: 3.0.0-rc.2
//  Meter:  Seametrics AG3000       https://www.seametrics.com/wp-content/uploads/LT-14259r7.3-20190108-AG3000-Instr.pdf
//    Power:                Battery (AG3000 only):  One lithium 7.2V ‘D’ size battery pack, replaceable.
//    Scaled Pulse Output:  Signal:                 Current sinking pulse, isolated, 36 Vdc at 10 mA max
//                          Pulse Rates:            User-scalable from 0.1 to 99,999.9 volume units/pulse. Pulse width is one-half of 
//                                                  pulse period with minimum pulse width of 2.5 ms, 200 pulses/sec max. For battery 
//                                                  option meters, pulse width varies with frequency, 150 pulses/sec max.
//    Wiring Diagram:       Battery Power with Pulse (BXX):   White (C1) Pulse-  
//                                                            Green (C1) Pulse+   
//    Standard Menu:    T UNIT: GALLONS     R UNIT: GALLONS/MIN     SET P: 00010.0 GALLONS     DAMP: 1     
//    Special SUBMENU:  SAMP: ???   Sample periods of 1/5, 1/3, 1, 3, 5, 15, 30, and 60 seconds can be selected. 
//                                  (A sample period of 5 seconds—5 year battery life—is the default.)
int flowCompletedStartup = LOW;        //  detector may need time to completely setup before use (like a PIR sensor)
unsigned long tmsBeginFlowStartup = 0; //  start time when flow device was turned ON (in this project, already running)
int flowmeter = D5; //flowmeter pin
int pulses = 0;     //total pulses
volatile int pulseDetected; //  interrupt allows reporting of pulse immediately - must be volatile
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++;
//}

// Interrupt Service Routine (ISR)  ******
void flowISR()  {                   
  pulseDetected = HIGH; //  flow meter digital out signal detected
}

SYSTEM_THREAD(ENABLED); // https://docs.particle.io/reference/device-os/firmware/#system-thread

void setup() {
    pinMode(flowmeter, INPUT); //  external pull-up 2.2K Ω
    timeMillis = 0;
    detachInterrupt(flowmeter); //  remove all low-level interrupts for this pin, if they exist    https://gammon.com.au/interrupts
    //attachInterrupt(flowmeter, flowinterrupt, FALLING);
    pulseDetected = LOW;        //  init ISR flag
}

void loop() {
    
    if (pulseDetected) { //  process pulse detected by interrupt (ISR)  ******
        pulses ++;             
        pulseDetected = LOW; //  turn off flag
    }
    
    if (!flowCompletedStartup) {
        if (millis() - tmsBeginFlowStartup >= 30000) { //  waited long enough for flow sensor startup to complete
          flowCompletedStartup = HIGH;                 //  flag startup as done
          attachInterrupt(flowmeter, flowISR, FALLING); //  now, begin the interrupts
          pulseDetected = LOW;      //  kill any processing of interrupts occuring (RIGHT NOW) from above statement
            // here, the interrupt queue should be clear and ready to process the next pulse from the flow meter
        }
    }

    unsigned long timeDif = millis()-timeMillis;
    if (timeDif >= reportInterval) {
        timeMillis = millis();
        unsigned long 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);
    }
}

No, when operating in Sink mode your Positive wire will be at 3.3V from the Pullup.
The Negative wire will be at 0V.

During a Pulse Event, the flow meter connects the two wires momentarily, which "should" drop the voltage of your Positive wire to near 0V, causing the interrupt to fire.
Note that multimeters don't respond very quickly. That's why I've mentioned temporarily increasing the Pulse Value for field testing, so things move slower.

I would concentrate on getting an accurate Pulse with a Multimeter first.
Something is causing your Pulse Event to only drop the Voltage Potential to 2V -2.6V according to your MM, instead of near 0V. The Boron and Flow Meter are likely doing exactly what they are supposed to do. If you were to watch this signal on a scope, I bet you'd see many falling edges during the Pulse, and the Boron is counting them all, as it's being instructed to do.

With Pulse Output, you are monitoring an Analog signal, which is sensitive to outside interference.
Think of your 25' wire as an antenna, as previously discussed.

Are you using a shielded twisted pair ?

Once your wiring allows for a clearly defined Pulse Event down to "near" 0V, you shouldn't have any problems. One trick I use to avoid misfires is to apply a de-bounce delay in the ISR:


void flowinterrupt () {
  if (millis() - lastIntTime >=  DEBOUNCE_DELAY) {   // 100 ms , depending on your expected Pulse Width
   pulses++;
   lastIntTime =  millis();
  }
}
1 Like