- The Pulse Output of all of our electric meters is a non-powered open/close switch (though solid state - not a mechanical relay). Electrically the Pulse Output is very similar to the closing of a dry contact switch, such as a Reed switch. Your device would need to put a low voltage on the line and sense when the circuit closes at the meter end, indicating one pulse.
Pulse Output Specs:
Impulse width: 90ms
Compatible voltage (the meter itself does not put out a voltage): 27V max
Current range the meter's pulse output can handle: ≤27mA
The EKM-25XDSE and older EKM-25IDS meters will produce 800 pulses per kWh
I have a Raspberry Pi Zero, so I decided to use that to read and count the pulses. After some trial-and-error, I came up with the following Python3 code that just prints out the same reading as displayed on the LCD each second. This is just proof-of-concept code to see if I could read the pulses and make it match the display. More work needs to be done to log the readings and read them remotely. I also provided an LED that is turned on by the code while the pulse is active and it flashes in sync with the Red LED on the meter. To start the Python Demo script you just open a terminal window and type :
python3 pulse2.py -k 1234.75
where the number 1234.75 is the current reading on the LCD
Code: Select all
# EKM-25IDS KWHr meter Pulse counter Demo Program
#
# 25IDS has an Isolated Optocoupler output.
# Collector is labeled (+)
# Emitter is labeled (-)
# The Pulse output supplies 800 pulses per KwHr
# The number on the 25IDS LCD display is total-counts / 800
# The LCD reads in 0.01, which is 8 cnts per .01
# The output pulse stays active for ~90mS (has a little jitter)
#
# Connections to Pi : https://pinout.xyz/
# 25IDS (+) to 3.3V on Raspberry Pi
# 25IDS (-) to GPIO24
# Add external 2K pulldown from GPIO24 to Gnd
# Internal Pulldown may work, not tested
#
# Added LED with series 680 ohm from GPIO25 to LED+, LED- to Gnd
# LED flashes on each pulse, in sync with the Red LED on meter
# Rising edge, turn on, Falling Off
#
#----------------------------------------------------------------------
# This program uses gpiozero module to interface with the R-pi I/O pins
# https://gpiozero.readthedocs.io/en/stable/index.html
# https://gpiozero.readthedocs.io/en/stable/recipes.html#pin-numbering
# To check if gpiozero is already on your Pi, type:
# pinout in a terminal window
# If you get a response, you have the library, if not, install it:
# sudo apt update
# sudo apt install python3-gpiozero
# We want to control 1 LED and read an input pin
from gpiozero import LED
from gpiozero import DigitalInputDevice
from time import sleep # for time delays
PULSE_PIN = 24 # Pulse input GPIO24. Header pin 18
LED_PIN = 25 # LED Output GPIO25. Header pin 22. '1' == ON
led = LED(LED_PIN)
#----------------------------------------------------------------------
# A variable to count pulses.
# The Max the LCD display is 99999.99, or 100,000 kwh
# 100,000 kwh * 800pls/kwh = 80,000,000 pulses
pulseCnt = 0
[ Read 123 lines ]
MAX_PULSE_CNT = 100000 * 800 # guess we should reset the pulse count here
def PulseRising(gpin): # Rising Pulse Callback function
global pulseCnt
global led
#print('Pin value = ', gpin.value )
led.on() # Turn on the LED
# Count the pulse, check for overflow
pulseCnt += 1
if pulseCnt >= MAX_PULSE_CNT :
pulseCnt = 0
print("Pulse count rollover!")
def PulseFalling(gpin) : # Falling Pulse Callback Function
led.off() # just turn off the LED
#----------------------------------------------------------------------
#Command line args, set default pulse count, etc
#https://docs.python.org/3/howto/argparse.html
import argparse
cmdparser = argparse.ArgumentParser()
cmdparser.add_argument("port", help="Specify HTTP port other than default port 80", nargs='?'$
cmdparser.add_argument("-kwhrs", "-k", help="Initial KwHours reading from LCD like 345.76")
args = cmdparser.parse_args()
print("\nStarting...")
print("Processing Command line args:", args)
if args.kwhrs : # Set initial pulse count to get R-Pi to match LCD
pulseCnt = int(800*float(args.kwhrs))
if pulseCnt >= MAX_PULSE_CNT :
pulseCnt = 0
print("Max KwHrs is 99999.99! Setting to 0 ")
#----------------------------------------------------------------------
# Setup Pulse input Pin
# Not sure how bounce time works, using something less that 90mS.
# Maybe a hold-off before another interrupt can occur?
# Once Callback function is registered, it starts counting
# https://gpiozero.readthedocs.io/en/stable/api_input.html#gpiozero.DigitalInputDevice
# Setup input Pin, we define Active as High (True)
# The EKM Opto output shouldn't bounce, but we have 90ms to spare so use 30mS bounce time
pulseInput = DigitalInputDevice(PULSE_PIN, pull_up=None, active_state=True, bounce_time=0.030)
# Assign call back functions (what to do on Pulse goes active (rising)
pulseInput.when_activated = PulseRising # do NOT use () PulseRising() NO NO NO
pulseInput.when_deactivated = PulseFalling
#----------------------------------------------------------------------
# Main loop - Print the Pulse count
try :
while True:
sleep(1)
print("PulseCnt = ", pulseCnt, pulseCnt/800 )
except : # trap Ctrl-C so I can do any cleanup
pass
# These are not necessary, but this is how you do it manually...
led.close()
pulseInput.close()
print("\nDone!")