Using an LED Pulse Counter

Posted on
  • I'm trying to use an esprunio (pico) to interface some utility neter LED pulse counters (­roducts/WEB_LPS) these attach to the front of my electricity meter(s) over the LED which pules every 0.001 kWh of energy thats used.

    The idea is to count the pulses each minute then output this over the usb prot to a host raspi for logging the data.

    I've prototyped it with the button and the pulse counting works well, the issue I'm having is with the interfacing of the sensors to the digital input pins on the pico, I have the 2 wire passive sensors and according to their info Every time the LED on an energy meter pulses, the resistance between the signal and ground connections drops to around 2k ohm so if I connect the sensor across GND and D0 on the pico then use the internal pullup resistor I should get a 0 when the LED is on (or use the rising edge of the set watch to detect when the LED goes out. however I'm seeing very unreliable results.

    My code is below

    var count = {};
    const sensor =D0;
    pinMode(sensor, 'input_pullup');
    function printoutput(){
      for (var property in count) {
        if (count.hasOwnProperty(property)) {
          console.log(property + " - " + count[property]);
    function jsonoutput(){
    function reset(){
      count = {};
    setWatch(function() {
      var dta = new Date().toString().split(":");
      var dt = dta.join(":");
      if (count[dt]){
        count[dt] +=1;
      } else {
        count[dt] = 1;
    }, sensor, {edge:"rising", debounce:50, repeat:true});
  • Sat 2019.04.06

    Hello @sammachin sounds like a fun project.

    ' however I'm seeing very unreliable results'

    Interestingly, . . . we aren't seeing any!  ;-)
    Would you mind posting the current output?

    'the LED which pules every 0.001 kWh of energy thats used'

    Assumptions: So, if 1kW is used per hour, we should be seeing roughly three pulses a second? Based on my actual usage then, roughly one pulse per second perhaps? Have you tried just monitoring the pin with digitalRead() inside a loop to see if actual pulses are being detected by the Pico in order to separate whether this is a hardware or software issue?­bal_digitalRead

    or something like: (code untested)

    var intervalID = {};
    function ci() { clearInterval( intervalID ); }
    var delay = 500;
    var nTimes = 40;
    // Start Timer
    function st() {
      intervalID = setInterval(function () {
        console.log( "D0: " + digitalRead(D0) );
        // Flash onboard Red LED
        digitalWrite(LED1, digitalRead(D0));
      }, delay);

    Would you please post the output so we may verify hardware vs software. Although the version shouldn't be an issue here, would you post process.env also, thanks.

    Should the output appear reasonable based on the assumptions above, then it would make sense to then move on to the setWatch() function.

    Shouldn't line 30 and 32

    count[dt] +=1;
    ... be:
    count[dt++] +=1;
    ... or:
    count[count.length] += 1;

    as I don't see the element indexer 'dt' changing.

    Another thought: (from the passive section in link #1)

    'This means that if the pull-up resistor on the input of the data logger is around 10k, the voltage on the input is around 20% of the supply voltage'

    'The alignment of the passive LPS with the LED of the energy meter can be quite critical in order to achieve the lowest "on" resistance'

    'On' may not be close to 2K so 5% below could be much higher

    With the pin mode that is currently selected­global_pinMode
    'input_pullup - Digital input with internal ~40k pull-up resistor'

    It is still possible that ~5% (2K / 40K) of the supply voltage is still not close enough to be detected as a logic zero. Would changing to 'pulldown' and reversing the code logic allow a logic high to be detected instead?

    See: Table 46 doc page 86­2F103xC.pdf

    Don't forget to adjust for 3.3V vs 5V

  • @Robin

    Sorry I should have clarified I'm currently testing on my bench with the sensor hooked up to an LED an button that I can pulse manually to test the detection, thats the part thats unreliable,

    The code for counting and datetime works well if I use the button to trigger the function instead of my sensor.

    I think you might be onto somthing with the voltage levels though I'd not realised the pullup resistor is 40k I need to go and do my calculations properly :)

  • Sun 2019.04.07

    I see another possibility, Line 3

    const sensor =D0;

    Although I was unable to locate the definition of BTN, these references use BTN1 as a string.­b/master/scripts/­b/master/boards/

    Could sensor need the same? (e.g. is const sensor actually  0xD0  "D0"  or  D0)
    or is the substitution somehow corrupting setWatch()
    (e.g. const D0 is not a Pin() object)­p

    Didn't get much more from setWatch():­bal_setWatch
    pin - The pin to watch

    Not able to find a definition for 'pin' and what it's argument may contain.

    but a Pin() object constructor on the other hand,­Pin
    'value - A value to be converted to a pin. Can be a number, pin, or String'

  • Hi Sam!

    That's a great idea - I've been meaning to try something like that.

    If you really are using a Pico, D0 is not a valid pin ( Which pin did you think you were connecting to?

    If I'm reading your post right, it's really the setWatch that's not firing reliably? So you could remove all your code and just do

    const sensor =D0;
    pinMode(sensor, 'input_pullup');
    setWatch(function(e) {
    }, sensor, {edge:"both",  repeat:true});

    And see what happens? Having the debounce probably won't help you.

    The 40k internal vs 2k resistance sounds like it would be fine. Are you sure that you have your LED attached to the light sensor in such a way that no light from anywhere else is getting in? If it was, it could mean the light sensor always have a reading that there was light.

    @Robin :

    The pulses of LEDs in UK electricity meters are quite fast - polling every 0.5 seconds won't do it. You'd need to do it 1000 times a sec to be even remotely sure.

    Could sensor need the same? (e.g. is const sensor actually 0xD0 "D0" or D0)

    No, afraid not. Like in all of the Espruino examples, you just use a pin name as-is, eg D0 - not quoted or a hex number.

  • I just gave this a go on Puck.js with an LDR between D1 and D2:

    var counter = 0;
    function update() {
      var a = new Uint32Array([counter]);
        name: "ELEC",
        connectable : false,
        scannable : false,
        interval: 600 // default is 375 - save a bit of power
    setWatch(function(e) {
      digitalPulse(LED1,1,10); // show activity
    }, D2, { repeat:true, edge:"falling" });

    It works amazingly well - I'll try and stick a video/tutorial up soon.

  • Mon 2019.04.08

    'If you really are using a Pico, D0 is not a valid pin'

    Fantastic catch @Gordon, totally missed that. . . .

  • Here you go:

    Works great - miles better than the actual smart meter I have which never let me download any information and which stopped working as soon as we changed electricity providers.

  • Great project. Surprised that the LDR is obviously fast enough because when discussing use of it in a different project - Help for Newbie. LED lights for game board , @DrAzzy deemed them too slow - see post #12. Of curse, the spacial setup controlling influence of ambient light plays a great role for the reliable working of LDRs.

    Unfortunately most of the US meters for water, electricity and gas don't have such 'close access' - with good ambient light control - to the LED, if they even have a LED. A focusing photo diode or transistor could be the answer there, or a cheap scanner that goes after the dial(s) or display.

  • Post a reply
    • Bold
    • Italics
    • Link
    • Image
    • List
    • Quote
    • code
    • Preview

Using an LED Pulse Counter

Posted by Avatar for sammachin @sammachin