Directly connecting to Optical Pulse Counter with RPi?

IrishLads, see this thread:

It doesn’t have all you need but it may have something usefull that might help you regarding using an rpi with pulse sensor. But as i dont understand programing neither eletronic, i can’t help you more.
Regards,
Celso

There’s a very recent response from Paul (pb66) citing the exact details here. But I can’t help with moving the data from one base to another. I’m guessing you need something like Nodered for that, but I know nothing about it, so I didn’t respond.

1 Like

I used surface mount Ethernet sockets and a few “jumper wires” with one end in the “punch down” connectors of the Ethernet socket box and the other loose ends I used a spot of super glue to make a 5pin header from the 5 single pole connectors to make the connection(s) more manageable when plugging onto the gpio.

Another “quick and dirty” method is to use rc.local, but this is less reliable and being phased out in Raspbian Stretch.

I think the basic settings would be

[[Pulse]]
        Type = EmonHubSocketInterfacer
        [[[init_settings]]]
                port_nb = 50012
        [[[runtimesettings]]]
                pubchannels = ToEmonCMS,
                timestamped = True

added to the interfacers section of emonhub and possibly an entry in the nodes section too, But I don’t use the same version of emonhub so I can’t easily define that off-the top of my head. Once you have the optical counter mounter and physically connected, with just the above settings in emonhub.conf and pulses.py running, you should get data appearing in emonhub.log and from there it should be easy to add a nodes definition and see the data arrive in emoncms.

An example would be something like

[[18]]
    nodename = pulsecounter
    [[[rx]]]
        names = pulsecnt1, pulsecnt2
        scales = 1, 1
        units = Wh, Wh

but I’m guessing a bit here and it will partially depend on any mods you make to pulses.py, the spec of your meter pulses and your choice of labels.

With regard to using multiple Pi’s you have options, although unless you have reason to do otherwise, I would recommend just changing the node id in one of the pulses.py scripts and use the same target host for both scripts to deposit their data into the same emonhub socket on the one device, just edit the host = "localhost" line to point the slave Pi’s pulses.py at the master Pi’s emonhub socket, using a fixed ip if needed.

As long as they are on the same LAN you need no other setting than possibly opening the “50012” port in the UFW firewall if it’s enabled on the master Pi.

??? I thought I was loosing my marbles, I couldn’t remember writing anything along these lines recently. That post was written a year ago! But thanks for linking, I had forgotten about that post and there are some useful links about gpio etc in there.

1 Like

No - a victim of editing. I’d linked to a recent link, then edited out the link to the link, leaving the original target.

I think this might usefully become a ‘Learn’ topic?

I think there are several topics in here that could be useful

  • using the emonhub socket interfacer
    • setting one up, the options etc
    • using one across the LAN (ie handling UFW rules and using hostnames/IP addresses and ports
    • creating a simple script that posts data to an emonhub interfacer
  • Using the Pi’s GPIO
    • Physical conns
    • Addressing the gpio pins
    • catching pulses
    • hooking up surface mount Ethernet sockets to expand the Pi’s gpio to connect pulse counters and temp sensors with rj45 plugs
  • Writing a simple systemd unit to manage a bespoke script

but I wouldn’t know where to begin, that’s why I just tend to post stuff on the forum.

When i try to run pulses.py on a raspberry pi 3 running the latest emoncms image, I’m getting the following:

pi@emonpi(ro):~$ python pulses.py 
 Traceback (most recent call last):
 File "pulses.py", line 118, in <module>
  main()
 File "pulses.py", line 103, in main
  GPIO.add_event_detect(pulse_pin1, GPIO.BOTH, callback=eventHandler1, bouncetime=bounce)
 RuntimeError: Failed to add edge detection

Seems like the script is not able to communicate with the GPIO?

I get a similar result when using this gpio test script gpiotest.py

Thinking that this might be a case of the gpio not being accessible, I edited my conf to comment out the [[RFM2Pi]] interfacer since it looked like that was potentially tying up the gpio board. No change.

Anything I’m missing?

Sorry, I’ve not seen that before. I have just done a quick internet search and most (but far from all) discussions around that error seem to point to permissions or incorrect pin refs.

I’m afraid it’s going to be a while before I can get to checking this and it was quite a long time ago I wrote that script, I put it into service and it’s worked ever since, I’ve not had any cause to look at it again since, so off-hand I can’t really think of anything to try beyond checking the pin references are ok, perhaps even try running the script as sudo???

Ah,yeah, permissions issue apparently - running it as sudo worked; will have to make sure I figure out how to run with elevated permissions in systemd / startup.

Now however I’m getting an socket error:

socket.error [Errno 111] Connection refused

I have opened up 50012 using the command in the script

sudo ufw allow 50012

and
sudo ufw -f enable

I’ll look around the forums to see if this is seen by others.

Nevermind, Ok, I had the:

[[Pulse]]
    Type = EmonHubSocketInterfacer
    [[[init_settings]]]
            port_nb = 50012
    [[[runtimesettings]]]
            pubchannels = ToEmonCMS,
            timestamped = True

In the wrong section. ( I had it at the end of the conf so it was under the nodes section)

Now when i touch pin 13, i’m getting a pulse detection and it is writing to the node 18 pulsecnt1 as expected

Now that I have that working, I need to set up a wH Accumulator, right?

Personally I’ve never had much joy with the whaccumulator process, I use the “total pulse count to pulse increment” process.

If you search “total pulse count to pulse increment” here on the forum you can find more info, in particular the “Wh accumulator - strange behavior” thread discusses the issues you could have.

Thanks Paul,

If I want to sync to my current meter reading, say its 40644 kwH, would I set pulse_id =

{1:40644000,2:0}

My node is configured as:

[[18]]
nodename = pulsecounter
[[[rx]]]
    names = pulsecnt1, pulsecnt2
    scales = 1, 1
    units = Wh, Wh

I’m testing the script right now and it doesn’t always increment the pulse_id value:

1520357220.42 18 40664020 0
1520357277.69 18 40664020 0

I can understand why you might want to do this, but if you must, then consider trying a virtual feed, the data storage in emoncms is in 32bit floats, this equates to around 7 digits of accuracy so the next increment to 40664020 0 will be 40664030 0 and depending on how your processing is set up, you may need to see that whole jump in one update, it maybe that every update that doesn’t reach that increment is ignored/lost, so effectively it might only be registering use that is over 10 Wh in any one interval, that could be a large portion of your usage.

I want to track the actual meter reading as closely as possible (i need to report it monthly manually to earn my solar renewable energy credits for generation).

Is there a better way to do this?

Basically the datatype you are using (phpfina or phptimeseries) cannot offer you the scope and resolution to do what you want. You need to store the change in pulsecount and then add the starting meter reading back in afterwards, either by manually calculating it each month or by setting up a virtual feeds so that you are recording the “change in pulse count” but displaying the “meter tracking” because the virtual feed adds the starting reading to every value when graphed or displayed.

Alternatively you could look at other storage engines, but there may be other consequences, eg the apps module only works with phpfina (without hacking).

TBH, if you need to be submitting “meter readings” then that’s what you should be doing “reading the meter”, I’m pretty familiar with all this stuff to the point it’s pretty predictable, but if I submit a meter reading, I read the meter.

If the meter isn’t electronically “readable” eg registers accessible via modbus or infrared etc, and it’s not easily accessed, maybe you should be looking at a remote camera or cctv so you can remotely take a peek at the meter once an month.

Hi Paul, I’m struggling to find more info on the connections between the optical sensors and the GPIO pins. I’ve made my own surface mount ethernet sockets with jumper wires connected to each punch down. Looking at the RJ45 on the optical sensor it looks like there are connections to Pins 1,2, 5 and 6.

Sorry to be a pain, could you please advise what GPIO you have connected 1,2,5 and 6 to?
I’ve searched through other posts and the archive and can’t seem to find any schematics or guides for this.

Thanks

Mike

There are in fact only 3 active connections to the optical sensor. 2 & 5 are +5V & GND respectively, 6 is the output. It is not in fact a pulse, in that there is no control of the shape of the output using (say) a Schmitt trigger. I am measuring pin 6 at within 3 mV of GND in darkness and 35 mV of VCC in reasonably bright light. The output goes to an acceptable ‘high’ state long before the LED on the rear of the sensor lights up.

As Robert explains there is only really one “interesting” connection per optical sensor, that one wire can be connected to almost any gpio pin as long as you edit the sketch to use that gpio pin.

In my example script there are 2 gpio pins defined as this script happened to be used with 2 optical sensors.

The pins I used were as follows (physical pin numbers used rather than BCM/GPIO numbering for RPI GPIO)

optical sensor RPi
1 (nc)
2 (vcc) Pin 17 (vcc)
3 (nc)
4 (nc)
5 (gnd) Pin 9 (gnd)
6 (output) Pin 13 or 15
7 (nc)
8 (nc)

Note I used 3.3V rather than 5V to power the sensor as the Pi gpio input pins are not 5V tolerant and the sensor is designed to work at both 3.3V and 5V.

I’ve recently found this script and put it to use. I’ve also been on a mission to reduce CPU use and found the script uses 100% CPU. The problem was the way the while loop was working.

The while loop at the end is the main difference.

import RPi.GPIO as GPIO
import time
import socket

# a "pulse" is 1 unit of measurement use emonHub scales and unit to define
# eg if 100 pulses is 1m3, ie 0.01m3 each then emonHub should use scale = 0.01 and unit = m3
# Therefore "pulse_id" becomes an accumulating "total used" and should follow the meter reading

nodeid = 18
valueid = 1
bounce = 1
interval = 5
lastsend = 0
host = "localhost" #emonbase1"
port = 50012
pulse_pin1 = 21
pulse_pin2 = 15

pulse_id = {1:0,2:0}

def eventHandler1(channel):
    processpulse(1,GPIO.input(channel))
def eventHandler2(channel):
    processpulse(2,GPIO.input(channel))


#    print("event")

def processpulse(channel,status):
    global pulse_id
    global frame
    global lastsend
    if status: #GPIO.input(channel):
        pulse_id[channel] += 1
        print("Channel "+ str(channel) + "  on : " + str(pulse_id[channel]))
    else:
        print("Channel "+ str(channel) + " off : " + str(pulse_id[channel]))

    t = time.time()
    f = ' '.join((str(t), str(nodeid), str(pulse_id[1]), str(pulse_id[2])))
    if t > (lastsend + interval):
        lastsend = t
        print f
        send(f)


def send(f):
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.connect((host, port))
    f = f + '\r\n'
    s.send(f)
    s.close()


if rpi:
    GPIO.setmode(GPIO.BOARD)
    GPIO.setup(pulse_pin1, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
    GPIO.add_event_detect(pulse_pin1, GPIO.BOTH, callback=eventHandler1, bouncetime=bounce)
    GPIO.setup(pulse_pin2, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
    GPIO.add_event_detect(pulse_pin2, GPIO.BOTH, callback=eventHandler2, bouncetime=bounce)


try: # CTRL+C to break - requires graceful exit
    while True:
        time.sleep(5) # the value doesn't matter.
except KeyboardInterrupt:
    GPIO.cleanup() # clean up GPIO on CTRL+C exit
    exit()

GPIO.cleanup() # just in case

time.sleep() could be a millisecond, one second, 5000 seconds, makes no difference, as long as the program is running the interrupts will happen and callbacks are initiated immediately.
I hope that helps.

1 Like

Hi guys

Is there a summary of this?

I’m using the Lechacal boards on top of my RPi’s. They don’t know/understand the pulse sensor (and don’t have input points, they are however only using pins 1-10, thus there are open pins, so can hard wire the RG45 pins used to open GPIO pins + modify the above script to use the then selected pin,
(is this script going to flat line my CPU… cause problems for emonPi)?

(thinking I might connect a camera also, and take a photo once a day which can be used down the line as a sanity check against values stored/recorded by the pulse sensor.

optical sensor RPi
1 (nc)
2 (vcc) Pin 17 (vcc)
3 (nc)
4 (nc)
5 (gnd) Pin 9 (gnd)
6 (output) Pin 13 or 15
7 (nc)
8 (nc)

is there a how too, considering this seems to be a long running thread by now ?
seen some comments re the auto start of the script, and rc.local being phased out, so whats the preferred method.

G

My personal motivation for making a how-to is to get an item in the OEM shop alongside.
It’s somewhere around the top of the OEM related to-do list I have… to design an RJ45 pi hat for the optical sensors.

I think it’s now systemd? I used a guide online without much trouble.

Perhaps chop the optical lead and make up something like this for a simple plug into the Pi:

image
That image is actually a little misleading, the crimpy things go into the housing the other way around.

I’m pretty sure it helps to have a small ceramic cap on the signal line to GND for countering noise or flickering ambient light.

1 Like