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.