Aus FHEMWiki
Wechseln zu: Navigation, Suche
Zweck / Funktion
Count pulses, calculate time between pulses and convert this to readings for e.g. power consumption of Energy meters
Typ Contrib
Dokumentation Thema
Support (Forum) Sonstiges
Ersteller StefanStrobel (Forum / Wiki)
Wichtig: sofern vorhanden, gilt im Zweifel immer die (englische) Beschreibung in der commandref!

This module implements an Interface to an Arduino based counter for pulses on any input pin of an Arduino Uno, Nano or similar device like a Jeenode. The typical use case is an S0-Interface on an energy meter or water meter.

Counters are configured with attributes that define which Arduino pins should count pulses and in which intervals the Arduino board should report the current counts.

The Arduino sketch that works with this module uses pin change interrupts so it can efficiently count pulses on all available input pins. The module creates readings for pulse counts, consumption and optionally also a pulse history with pulse lengths and gaps of the last 20 pulses.


The module has been checked in to the FHEM svn. The corresponding arduino sketch can also be found under contrib in the subdirectory arduino/.


This module requires Device::SerialPort or Win32::SerialPort module as well as an arduino uno, nano, jeenode or similar device that runs the ArduCounter sketch.


define <name> ArduCounter <device>

<device> specifies the serial port to communicate with the Arduino.

The name of the serial-device depends on your distribution. You can also specify a baudrate if the device name contains the @ character, e.g.: /dev/ttyUSB0@9600 The default baudrate of the firmware is 38400 since Version 1.4 of the sketch.


define AC ArduCounter /dev/ttyUSB2

Configuration of the module

Specify the pins where impulses should be counted e.g. as

attr AC pinX falling pullup 30

The X in pinX can be an Arduino pin number with or without the letter D e.g. pin4, pinD5, pin6, pinD7 ...

After the pin you can define if the signals to be counted start with rising or falling edges. The optional keyword pullup activates the pullup resistor for the given Arduino Pin.

The last argument is also optional and specifies a minimal pulse length in milliseconds. In this case the first argument (e.g. falling) means that an impulse starts with a falling edge from 1 to 0 and ends when the signal changes back from 0 to 1.


define AC ArduCounter /dev/ttyUSB2
attr AC factor 1000
attr AC interval 60 300
attr AC pinD4 falling pullup 5
attr AC pinD5 falling pullup 30
attr AC verboseReadings5
attr AC pinD6 rising

This defines three counters connected to the pins D4, D5 and D5.

D4 and D5 have their pullup resistors activated and the impulse draws the pins to zero.

For D4 and D5 the arduino measures the time in milliseconds between the falling edge and the rising edge. If this time is longer than the specified 5 or 30 milliseconds then the impulse is counted. If the time is shorter then this impulse is regarded as noise and added to a separate reject counter.

verboseReadings5 causes the module to create additional readings like the pulse history which shows length and gaps between the last pulses.

For pin D6 the arduino does not check pulse lengths and counts every time when the signal changes from 0 to 1.

The ArduCounter sketch which must be loaded on the Arduino implements this using pin change interrupts, so all avilable input pins can be used, not only the ones that support normal interrupts.

The module has been tested with 14 inputs of an Arduino Uno counting in parallel and pulses as short as 3 milliseconds.


send a command to the Arduino board to get current counts.
This is not needed for normal operation but might be useful sometimes for debugging.


send the value to the Arduino board so you can directly talk to the sketch using its commands.
This is not needed for normal operation but might be useful sometimes for debugging
flashes the ArduCounter firmware ArduCounter.hex from the fhem subdirectory FHEM/firmware
onto the device. This command needs avrdude to be installed.
The attribute flashCommand specifies how avrdude is called.
If it is not modifed then the module sets it to
avrdude -p atmega328P -c arduino -P [PORT] -D -U flash:w:[HEXFILE] 2>[LOGFILE]
This setting should work for a standard installation and the placeholders are automatically replaced when the command is used. So normally there is no need to modify this attribute.
Depending on your specific Arduino board however, you might need to insert -b 57600 in the flash Command.
reopens the arduino device and sends a command to it which causes a reinitialize and reset of the counters.
Then the module resends the attribute configuration / definition of the pins to the device.

Supported readings

the counted total of impulses for pin X
the result of (delta count) / (delta time) * factor.
the number of pulses counted during the last reporting interval diveded by the time between the first pulse and the last pulse in the interval, multiplied by a configurabe factor.
long count which keeps on counting up after fhem restarts whereas the pin.* count is only a temporary internal count that starts at 0 when the arduino board starts.
like long.* but when the Arduino restarts the potentially missed pulses are interpolated based on the pulse rate before the restart and after the restart.
counts rejected pulses that are shorter than the specified minimal pulse length.
shows detailed information of the last pulses. This is only available when a minimal pulse length is specified for this pin.
Also the total number of impulses recorded here is limited to 20 for all pins together.
The output looks like -36/7:0C, -29/7:1G, -22/8:0C, -14/7:1G, -7/7:0C, 0/7:1G
The first number is the relative time in milliseconds when the input level changed, followed by the length in milliseconds, the level and the internal action.
-36/7:0C for example means that 36 milliseconds before the reporting started, the input changed to 0V, stayed there for 7 milliseconds and this was counted.


Define a pin of the Arduino board as input. This attribute expects either rising, falling or change, followed by an optional pullup and an optional number as value.
If a number is specified, the arduino will track rising and falling edges of each impulse and measure the length of a pulse in milliseconds.
The number specified here is the minimal length of a pulse and a pause before a pulse. If one is too small, the pulse is not counted but added to a separate reject counter.
interval normal max min mincout
Defines the parameters that affect the way counting and reporting works.
This Attribute expects at least two and a maximum of four numbers as value.
The first is the normal interval, the second the maximal interval, the third is a minimal interval and the fourth is a minimal pulse count.
In the usual operation mode (when the normal interval is smaller than the maximum interval), the Arduino board just counts and remembers the time between the first impulse and the last impulse for each pin.
After the normal interval is elapsed the Arduino board reports the count and time for those pins where impulses were encountered.
This means that even though the normal interval might be 10 seconds, the reported time difference can be something different because it observed impulses as starting and ending point.
The Power (e.g. for energy meters) is the calculated based of the counted impulses and the time between the first and the last impulse.
For the next interval, the starting time will be the time of the last impulse in the previous reporting period and the time difference will be taken up to the last impulse before the reporting interval has elapsed.
The second, third and fourth numbers (maximum, minimal interval and minimal count) exist for the special case when the pulse frequency is very low and the reporting time is comparatively short.
For example if the normal interval (first number) is 60 seconds and the device counts only one impulse in 90 seconds, the the calculated power reading will jump up and down and will give ugly numbers.
By adjusting the other numbers of this attribute this can be avoided.
In case in the normal interval the observed impulses are encountered in a time difference that is smaller than the third number (minimal interval) or if the number of impulses counted is smaller than the fourth number (minimal count) then the reporting is delayed until the maximum interval has elapsed or the above conditions have changed after another normal interval.
This way the counter will report a higher number of pulses counted and a larger time difference back to fhem.
If this is seems too complicated and you prefer a simple and constant reporting interval, then you can set the normal interval and the mximum interval to the same number. This changes the operation mode of the counter to just count during this normal and maximum interval and report the count. In this case the reported time difference is always the reporting interval and not the measured time between the real impulses.
Define a multiplicator for calculating the power from the impulse count and the time between the first and the last impulse
Change the name of the counter reading pinX to something more meaningful.
Change the name of the counter reading longX to something more meaningful.
Change the name of the counter reading InterpolatedLongX to something more meaningful.
Change the name of the power reading powerX to something more meaningful.
Override the factor attribute for this individual pin.
Allow the reading time stamp to be set to the beginning of measuring intervals
create additional readings: timeDiff, countDiff and lastMsg for each pin