LED pulse sensor with Arduino-like board

Hello,

 

I am trying to use the optical pulse sensor

http://openenergymonitor.org/emon/buildingblocks/opticalpulsesensor

​with Arduino-like module - sensebender -> http://www.mysensors.org/hardware/micro

I am having troubles making this sensor work with the sketch from MySensors:

/**
 * The MySensors Arduino library handles the wireless radio link and protocol
 * between your home built sensors/actuators and HA controller of choice.
 * The sensors forms a self healing radio network with optional repeaters. Each
 * repeater and gateway builds a routing tables in EEPROM which keeps track of the
 * network topology allowing messages to be routed to nodes.
 *
 * Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
 * Copyright (C) 2013-2015 Sensnology AB
 * Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors
 *
 * Documentation: http://www.mysensors.org
 * Support Forum: http://forum.mysensors.org
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * version 2 as published by the Free Software Foundation.
 *
 *******************************
 *
 * REVISION HISTORY
 * Version 1.0 - Henrik EKblad
 * 
 * DESCRIPTION
 * This sketch provides an example how to implement a distance sensor using HC-SR04 
 * Use this sensor to measure KWH and Watt of your house meeter
 * You need to set the correct pulsefactor of your meeter (blinks per KWH).
 * The sensor starts by fetching current KWH value from gateway.
 * Reports both KWH and Watt back to gateway.
 *
 * Unfortunately millis() won't increment when the Arduino is in 
 * sleepmode. So we cannot make this sensor sleep if we also want 
 * to calculate/report watt-number.
 * http://www.mysensors.org/build/pulse_power
 */

#include <SPI.h>
#include <MySensor.h>  

#define DIGITAL_INPUT_SENSOR 3  // The digital input you attached your light sensor.  (Only 2 and 3 generates interrupt!)
#define PULSE_FACTOR 1000       // Nummber of blinks per KWH of your meeter
#define SLEEP_MODE false        // Watt-value can only be reported when sleep mode is false.
#define MAX_WATT 10000          // Max watt value to report. This filetrs outliers.
#define INTERRUPT DIGITAL_INPUT_SENSOR-2 // Usually the interrupt = pin -2 (on uno/nano anyway)
#define CHILD_ID 1              // Id of the sensor child
unsigned long SEND_FREQUENCY = 20000; // Minimum time between send (in milliseconds). We don't wnat to spam the gateway.
MySensor gw;
double ppwh = ((double)PULSE_FACTOR)/1000; // Pulses per watt hour
boolean pcReceived = false;
volatile unsigned long pulseCount = 0;   
volatile unsigned long lastBlink = 0;
volatile unsigned long watt = 0;
unsigned long oldPulseCount = 0;   
unsigned long oldWatt = 0;
double oldKwh;
unsigned long lastSend;
MyMessage wattMsg(CHILD_ID,V_WATT);
MyMessage kwhMsg(CHILD_ID,V_KWH);
MyMessage pcMsg(CHILD_ID,V_VAR1);

void setup()  
{  
  gw.begin(incomingMessage);

  // Send the sketch version information to the gateway and Controller
  gw.sendSketchInfo("Energy Meter", "1.0");

  // Register this device as power sensor
  gw.present(CHILD_ID, S_POWER);

  // Fetch last known pulse count value from gw
  gw.request(CHILD_ID, V_VAR1);
  
  attachInterrupt(INTERRUPT, onPulse, RISING);
  lastSend=millis();
}

void loop()     

  gw.process();
  unsigned long now = millis();
  // Only send values at a maximum frequency or woken up from sleep
  bool sendTime = now - lastSend > SEND_FREQUENCY;
  if (pcReceived && (SLEEP_MODE || sendTime)) {
    // New watt value has been calculated  
    if (!SLEEP_MODE && watt != oldWatt) {
      // Check that we dont get unresonable large watt value. 
      // could hapen when long wraps or false interrupt triggered
      if (watt<((unsigned long)MAX_WATT)) {
        gw.send(wattMsg.set(watt));  // Send watt value to gw 
      }  
      Serial.print("Watt:");
      Serial.println(watt);
      oldWatt = watt;
    }
  
    // Pulse cout has changed
    if (pulseCount != oldPulseCount) {
      gw.send(pcMsg.set(pulseCount));  // Send pulse count value to gw 
      double kwh = ((double)pulseCount/((double)PULSE_FACTOR));     
      oldPulseCount = pulseCount;
      if (kwh != oldKwh) {
        gw.send(kwhMsg.set(kwh, 4));  // Send kwh value to gw 
        oldKwh = kwh;
      }
    }    
    lastSend = now;
  } else if (sendTime && !pcReceived) {
    // No count received. Try requesting it again
    gw.request(CHILD_ID, V_VAR1);
    lastSend=now;
  }
  
  if (SLEEP_MODE) {
    gw.sleep(SEND_FREQUENCY);
  }
}

void incomingMessage(const MyMessage &message) {
  if (message.type==V_VAR1) {  
    pulseCount = oldPulseCount = message.getLong();
    Serial.print("Received last pulse count from gw:");
    Serial.println(pulseCount);
    pcReceived = true;
  }
}

void onPulse()     

  if (!SLEEP_MODE) {
    unsigned long newBlink = micros();  
    unsigned long interval = newBlink-lastBlink;
    if (interval<10000L) { // Sometimes we get interrupt on RISING
      return;
    }
    watt = (3600000000.0 /interval) / ppwh;
    lastBlink = newBlink;
  } 
  pulseCount++;
}

 

 

The sensor is not indicating pulse reception (green LED) and Arduino is not receiving anything. 
I tried to use 3.3V from USB throught the voltage regulator as well as batteries, but no luck.

Any suggestions please? How do I test that the sensor is not dead?
 

EDIT: Forgot to mention. The wiring is simple:

LED Pulse Sensor               Sensebender
Pin 2  -----------------------------> 3.3V

Pin 5 ------------------------------  GND
Pin 6 ------------------------------  D3

 

Robert Wall's picture

Re: LED pulse sensor with Arduino-like board

Is the sensor drawing any current? Is the LED it is looking at bright enough and close enough? Have you tried the emonTx sketch (extract the appropriate sections with appropriate pin number changes)?

alexsh1's picture

Re: LED pulse sensor with Arduino-like board

Thanks for a prompt reply. Do you think I'd need a pull-up resistor? - it is powered by two AA batteries

I have not measured the current - will try to do it today.

i tried using a torch (4000lm) to emulate the LED pulse - I think this is bright enough.

No, I have not tried using emonTX sketch - I would have to change it completely as I'm trying to set it up on MySensors board using one of nodes.

Robert Wall's picture

Re: LED pulse sensor with Arduino-like board

The shop page says the sensor output is TTL. If that is indeed the case, then the output is actively driven both high and low, and no pull-up should be necessary.
Again, if the output is TTL and you're using a torch (and the spectral response of the sensor is compatible), you should be able to see any output with a multimeter, even though a multimeter might miss a genuine energy meter pulse at only 100 ms long or so.
The reason I'm being cautious is genuine TTL runs off 5 V, this claims to work down to 3.3 V so it's not strictly TTL at all at that voltage.

I suggested the emonTx sketch as a cross-check. You might like to compare the relevant parts just in case there's a significant difference.

alexsh1's picture

Re: LED pulse sensor with Arduino-like board

Ok, let's go back to the basic. TTL - it must be connected to the digital  pin, which is what I have. I cannot see any current drawn by the LED. It is zero. In other words, I am not sure if the sensor is working at all.

Additionally, I connect the optical sensor to D3 as per the wiring diagram above:

#define DIGITAL_INPUT_SENSOR 3 // The digital input you attached your sensor. (Only 2 and 3 generates interrupt!)
#define SENSOR_INTERRUPT DIGITAL_INPUT_SENSOR-2 // Usually the interrupt = pin -2 (on uno/nano anyway)

 

I do get the following output:

send: 3-3-0-0 s=255,c=0,t=17,pt=0,l=3,sg=0,st=ok:1.5
send: 3-3-0-0 s=255,c=3,t=6,pt=1,l=1,sg=0,st=ok:0
sensor started, id=3, parent=0, distance=1
send: 3-3-0-0 s=255,c=3,t=11,pt=0,l=12,sg=0,st=ok:Energy Meter
send: 3-3-0-0 s=255,c=3,t=12,pt=0,l=3,sg=0,st=ok:1.0
send: 3-3-0-0 s=4,c=0,t=13,pt=0,l=0,sg=0,st=ok:
send: 3-3-0-0 s=4,c=2,t=24,pt=0,l=0,sg=0,st=ok:
send: 3-3-0-0 s=4,c=2,t=24,pt=0,l=0,sg=0,st=ok:
send: 3-3-0-0 s=4,c=2,t=24,pt=0,l=0,sg=0,st=ok:
send: 3-3-0-0 s=4,c=2,t=24,pt=0,l=0,sg=0,st=ok:
read: 0-0-3 s=4,c=2,t=24,pt=0,l=5,sg=0:12169
Received last pulse count from gw:12169
Watt:178855
send: 3-3-0-0 s=4,c=1,t=24,pt=5,l=4,sg=0,st=ok:13162
send: 3-3-0-0 s=4,c=1,t=18,pt=7,l=5,sg=0,st=ok:13.1620
send: 3-3-0-0 s=4,c=1,t=24,pt=5,l=4,sg=0,st=ok:14156
send: 3-3-0-0 s=4,c=1,t=18,pt=7,l=5,sg=0,st=ok:14.1570
Watt:179354
send: 3-3-0-0 s=4,c=1,t=24,pt=5,l=4,sg=0,st=ok:15151
send: 3-3-0-0 s=4,c=1,t=18,pt=7,l=5,sg=0,st=ok:15.1510
Watt:178997
send: 3-3-0-0 s=4,c=1,t=24,pt=5,l=4,sg=0,st=ok:16145
send: 3-3-0-0 s=4,c=1,t=18,pt=7,l=5,sg=0,st=ok:16.1460
Watt:179140
send: 3-3-0-0 s=4,c=1,t=24,pt=5,l=4,sg=0,st=ok:17140
send: 3-3-0-0 s=4,c=1,t=18,pt=7,l=5,sg=0,st=ok:17.1400
send: 3-3-0-0 s=4,c=1,t=24,pt=5,l=4,sg=0,st=ok:18137
send: 3-3-0-0 s=4,c=1,t=18,pt=7,l=5,sg=0,st=ok:18.1370
Watt:179068
send: 3-3-0-0 s=4,c=1,t=24,pt=5,l=4,sg=0,st=ok:19132
send: 3-3-0-0 s=4,c=1,t=18,pt=7,l=5,sg=0,st=ok:19.1320
Watt:179140
send: 3-3-0-0 s=4,c=1,t=24,pt=5,l=4,sg=0,st=ok:20127
send: 3-3-0-0 s=4,c=1,t=18,pt=7,l=5,sg=0,st=ok:20.1270
Watt:178713
send: 3-3-0-0 s=4,c=1,t=24,pt=5,l=4,sg=0,st=ok:21122
send: 3-3-0-0 s=4,c=1,t=18,pt=7,l=5,sg=0,st=ok:21.1220
Watt:178926
send: 3-3-0-0 s=4,c=1,t=24,pt=5,l=4,sg=0,st=ok:22116
send: 3-3-0-0 s=4,c=1,t=18,pt=7,l=5,sg=0,st=ok:22.1170
Watt:179068
send: 3-3-0-0 s=4,c=1,t=24,pt=5,l=4,sg=0,st=ok:23110
send: 3-3-0-0 s=4,c=1,t=18,pt=7,l=5,sg=0,st=ok:23.1110
send: 3-3-0-0 s=4,c=1,t=24,pt=5,l=4,sg=0,st=ok:24105
send: 3-3-0-0 s=4,c=1,t=18,pt=7,l=5,sg=0,st=ok:24.1060
send: 3-3-0-0 s=4,c=1,t=24,pt=5,l=4,sg=0,st=ok:25100
send: 3-3-0-0 s=4,c=1,t=18,pt=7,l=5,sg=0,st=ok:25.1010
Watt:179282
send: 3-3-0-0 s=4,c=1,t=24,pt=5,l=4,sg=0,st=ok:26095
send: 3-3-0-0 s=4,c=1,t=18,pt=7,l=5,sg=0,st=ok:26.0960

 

not sure where watts are coming from as the sensor is not pulsing...

 

PS What sketch from openenergymonitor shall I go through please? I am complete new to openenergymonitor.

Thanks for your help

Robert Wall's picture

Re: LED pulse sensor with Arduino-like board

If your sensor is drawing absolutely zero current - not even microamps - then I can't say for certain that the sensor is dead (as I don't have one to test and I haven't seen a data sheet) but I would be highly suspicious.

It would take me some time to work through that third party sketch to find out how it works and to interpret what the print-out is trying to tell you - that's why I suggested the emonTx sketch. But all you want at present is something to test the sensor, so I suggest looking at the very simple example in Building Blocks: http://openenergymonitor.org/emon/buildingblocks/interrupt-based-pulse-c.... Even that is too complicated, all you need to print is the pulse count itself. You'll also need to change it to get the correct input pin (attach interrupt). You can test the sketch using a bit of wire to connect the input to 5 V, you might need the pull-down resistor it mentions for this. If it sees anything from 1 to many tens of pulses each time you dab the wire on - the sketch is working. Then substitute your sensor for the wire.

alexsh1's picture

Re: LED pulse sensor with Arduino-like board

Robert,

 

The sensor is working. I re-assemled everything on Arduino Uno and the green LED is on when the pulse is detected. However, now I have a problem that such pulse is not registered by Arduino or registered incorrectly. I found this:

https://github.com/openenergymonitor/emonTxFirmware

Which firmware would you recommend me to use to take a working optical sensor example to compare with?
I'll insert a few println to debug the code.

Thanks

Alex

Robert Wall's picture

Re: LED pulse sensor with Arduino-like board

Have you tried the Building Blocks code that I linked to above? That has the absolute minimum needed, so should be easy to work on.

The only thing that can go wrong is the "1" in attachInterrupt(1, onPulse, FALLING);
When you've got that right, you should see (if you Print it) pulseCount rising with every pulse detected. You can also see if changing FALLING to RISING makes any difference, as this is what your original sketch used.

alexsh1's picture

Re: LED pulse sensor with Arduino-like board

Thanks very much for the link. It really did help to troubleshoot the issue.

The following modification to the Building Blocks code worked in my setup:

int pin = 3;

void setup 

{

pinMode (pin, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(pin), onPulse, FALLING);

}

 

Thanks
Alex

 

PS For those using Arduino Nano, only D2/D3 can be used with attachInterrupt

Robert Wall's picture

Re: LED pulse sensor with Arduino-like board

That should give you a good guide to the changes you need to make in your original sketch to configure it correctly.

dBC's picture

Re: LED pulse sensor with Arduino-like board

Good to hear you got it sorted.  I think there may be other more subtle issues awaiting you with the original sketch as posted.  All of those volatile variables manipulated by the pulse ISR are larger than  one byte, which means accessing them is non-atomic.  In order to guarantee reading them in a consistent state from within loop(), you'll need to protect those accesses from interruption.

glyn.hudson's picture

Re: LED pulse sensor with Arduino-like board

Good work getting up and running using the sensor. For reference I have just measured the power consumption of the sensor, it reports 0mA when no pulse is detected and 5.3mA when a pulse is detected, most of this power consumption will be going to the green on-board LED. 

alexsh1's picture

Re: LED pulse sensor with Arduino-like board

Did anyone observe a battery life on the emonTx V3 (latest) using only a pulse meter? (Real-time and combined)
I am interested to know for how long it can run autonomously. Unfortunately, I do not have 240V socket close to my meter so a pulse reader on batteries is the only option. 

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.