Page 1 of 1

Double triggering/clocking/pulsing

Posted: Fri Mar 08, 2019 10:51 am
by bandtank
Similar to this thread, I am seeing multiple pulses per rotation with regularity. I'm using a custom solution that I designed (I'm a seasoned EE if it helps) through a Raspberry Pi Model 3B+, which works well with other pulse meters and pulse generating devices.

The physical connection is a direct connection between the Pi's IO pin and the meter's leads. The Pi has a pull-up enabled and there are no decoupling or filter capacitors at the moment. No equipment is nearby that would be causing noise spikes on the wires and the Pi has an isolated supply through a filtered UPS. Nearby meters do not have this issue, which is why I am speculating the internal mechanism of the EKM meter is causing the behavior.

The Python application instantiates threaded interrupt handlers for each I/O pin, which counts pulses and ultimately uploads the data to a database running in the cloud. None of that is malfunctioning. The issue is multiple triggers are captured by the I/O handler even with a debounce timeout of 20 ms, which I have verified with a scope on several occasions. Here's how it looks in the log (notice the timestamps):

Code: Select all

[2019-03-06 13:53:32.657] [INFO] [MeterMaster.py:27      ] ************************************
[2019-03-06 13:53:32.658] [INFO] [MeterMaster.py:28      ] * Starting MeterMaster Application *
[2019-03-06 13:53:32.659] [INFO] [MeterMaster.py:29      ] ************************************
[2019-03-06 13:53:32.659] [INFO] [MeterMaster.py:30      ] Using environment file: /home/tony/stuff/MeterMaster/.env
[2019-03-06 13:53:32.660] [INFO] [MeterMaster.py:32      ] Registering signal handlers
[2019-03-06 13:53:32.661] [INFO] [MeterMaster.py:35      ] Setting up GPIO in BCM mode
[2019-03-06 13:53:32.662] [INFO] [MeterMaster.py:39      ] Initializing water meter: MAIN_HOUSE
[2019-03-06 13:53:32.663] [DBUG] [WaterMeter.py:24       ] [Water Meter MAIN_HOUSE] Configuring GPIO 21 as an input with a pull-up
[2019-03-06 13:53:32.663] [INFO] [MeterMaster.py:42      ] Initializing API
[2019-03-06 13:53:32.664] [INFO] [MeterMaster.py:75      ] Starting meter thread(s)
[2019-03-06 16:24:51.763] [INFO] [WaterMeter.py:39       ] [Water Meter MAIN_HOUSE] Pulse: 1         Low Count: 0        High Count: 1       
[2019-03-06 16:24:52.580] [INFO] [WaterMeter.py:39       ] [Water Meter MAIN_HOUSE] Pulse: 1         Low Count: 0        High Count: 2       
[2019-03-06 16:24:54.787] [INFO] [WaterMeter.py:39       ] [Water Meter MAIN_HOUSE] Pulse: 0         Low Count: 1        High Count: 2       
[2019-03-06 16:24:56.246] [INFO] [WaterMeter.py:39       ] [Water Meter MAIN_HOUSE] Pulse: 1         Low Count: 1        High Count: 3       
[2019-03-06 16:57:38.154] [INFO] [WaterMeter.py:39       ] [Water Meter MAIN_HOUSE] Pulse: 0         Low Count: 2        High Count: 3       
[2019-03-06 16:57:40.434] [INFO] [WaterMeter.py:39       ] [Water Meter MAIN_HOUSE] Pulse: 1         Low Count: 2        High Count: 4       
[2019-03-06 16:57:41.725] [INFO] [WaterMeter.py:39       ] [Water Meter MAIN_HOUSE] Pulse: 1         Low Count: 2        High Count: 5       
[2019-03-06 16:57:52.823] [INFO] [WaterMeter.py:39       ] [Water Meter MAIN_HOUSE] Pulse: 0         Low Count: 3        High Count: 5       


Notice these lines:

Code: Select all

[2019-03-06 16:24:51.763] [INFO] [WaterMeter.py:39       ] [Water Meter MAIN_HOUSE] Pulse: 1         Low Count: 0        High Count: 1       
[2019-03-06 16:24:52.580] [INFO] [WaterMeter.py:39       ] [Water Meter MAIN_HOUSE] Pulse: 1         Low Count: 0        High Count: 2       
...
[2019-03-06 16:57:40.434] [INFO] [WaterMeter.py:39       ] [Water Meter MAIN_HOUSE] Pulse: 1         Low Count: 2        High Count: 4       
[2019-03-06 16:57:41.725] [INFO] [WaterMeter.py:39       ] [Water Meter MAIN_HOUSE] Pulse: 1         Low Count: 2        High Count: 5       

The code generating the counts is as follows:

Code: Select all

  def run(self):
    GPIO.setup(self.gpio, GPIO.IN, pull_up_down=GPIO.PUD_UP)
    while not self.stopped():

      if GPIO.wait_for_edge(self.gpio, GPIO.BOTH, timeout=self.timeout) is None:
        continue

      time.sleep(self.bounceTimeout)
      value = GPIO.input(self.gpio)
      if value:
        self.highCount = self.highCount + 1
      else:
        self.lowCount  = self.lowCount + 1
      logging.info(f"{self.logStr} Pulse: {value:<9} Low Count: {self.lowCount:<8} High Count: {self.highCount:<8}")

The issue appears to happen when the magnet is near the edge of the trigger range. It's exacerbated by a slow rotational rate, but it's not unique to that condition and it happens at both high and low levels.

Is the white wire available to use for a half cycle trigger? What does it do? I can't see the entirety of the pulse generating mechanism due to the blue shroud, so I'm not sure if the magnet hits a separate trigger on the other side, which could be used to build a state machine that would digitally filter this type of pulse noise.

Re: Double triggering/clocking/pulsing

Posted: Mon Mar 11, 2019 3:25 am
by Jameson
Thank you for sharing your code!

Have you tried looking at the pulse signal with an oscilloscope? This is a good way to see what signal you are dealing with, then the following step is how you want to correct it. If you have oscilloscope images, please post them here.

From your other post, you mentioned you have an SPWM-075-HD water meter. If your custom pulse counter is connected to the black and red wire now, I would switch to the black and white wire to see if you have the same result.

Get back to me and we will go from there.

Re: Double triggering/clocking/pulsing

Posted: Tue Sep 03, 2019 5:25 pm
by TechRanch
bandtank wrote: Fri Mar 08, 2019 10:51 am The issue appears to happen when the magnet is near the edge of the trigger range. It's exacerbated by a slow rotational rate, but it's not unique to that condition and it happens at both high and low levels.

Is the white wire available to use for a half cycle trigger? What does it do? I can't see the entirety of the pulse generating mechanism due to the blue shroud, so I'm not sure if the magnet hits a separate trigger on the other side, which could be used to build a state machine that would digitally filter this type of pulse noise.
I'm not sure if our problems are related, but seems likely. I was able to solve it by filtering out duplicate results within 5000 microseconds.

viewtopic.php?f=9&t=6128