Build a 12 input pulse counter - multiple input pulse counting
Last Update 3 November - by Trystan Lea
Pulse counting shield: includes a dedicated barebones arduino and pull down resistors (detailed below)
How it works
We cant use the interrupt method to measure 12 pulse inputs as there are only 2 interrupts on the Arduino. Instead we need to sample really fast and as continuously as possible in order to catch every pulse and measure the pulse rate accurately. To get best performance we need to:
- Read the digital input pins using fast low level digital input register commands
- Dedicate the pulse counting arduino to pulse counting only - no ethernet sending of data for example..
- Stream-line the code as much as possible - for example: no floating point math and minimal serial prints
Low level digital input registers
In version one I used digitalRead to read the state of the digital inputs and I also used the pulse counting arduino to do other things like sending data via ethernet. I started to do some accuracy tests, it became quickly apparent that the more inputs I read the worse the measurement accuracy got and the accuracy deteriorated quite rapidly!
Luckily it is possible to read digital Inputs much faster using direct port manipulation, its possible to read a register of 8 digital inputs in one command, although it actually drops to 6 inputs per register due to use of 2 for serial communication ( 0 and 1) and for the clock crystal (14 and 15).
Digital pins 2 to 13 occupy 2 registers, register D and B and by calling commands PIND and PINB which return a binary value of the digital pin states its possible to read 12 useful digital inputs pretty much simultaneously and much faster than using digital read although not as easy to understand when you look at the code!
With low level digital register access accuracy stopped dropping when reading from more inputs pins, result!
Dedicated Pulse Counting Arduino
The arduino used for pulse counting needs to be dedicated for pulse counting. As I mentioned above I used the same arduino for ethernet data sending to start with, problem is that ethernet data sending can take between 26ms and 1700ms+ and any pulses that occur in this time are lost, leading to really poor results. So for accurate results its best to keep the pulse counting arduino dedicated.
This means that a 12 input pulse counting arduino needs to be seen as an external input module, where we need a second arduino for doing the other tasks like ethernet data sending etc.
I decided to go for a configuration where the pulse counter arduino spits out its pulse times in microseconds and pulse counts of all 12 inputs via fast 115200 baud serial once every second. This string is then recieved and decoded by the main arduino and then send via ethernet to a web energy display:
The hardware for a pulse counter is mostly just the Arduino itself and then depending on your configuration:
Wired pulse counting
A pull down 10k resistor on each digital input to bring the digital signal to zero when the pulse output relay is in off/disconnected state.
LED Pulse counting
Create LED pulse sensors following this guide by AirSensor
No pull down resistor is required as the pulse / light sensor gives logic level 0 when the pulse is low. However if you build a pulse counting module with pull down resistors of around 10k up it still works with the light sensor, more info to come on this.
Dedicated pulse counting module sketch
Measures pulses from up to 12 pulse output meters, spits out a string to serial every given time interval (1s default) with pulse times and pulse counts. String is in semi-JSON form to keep it lightweight.
Base Arduino sketch
The following sketch decodes the semi-JSON string sent from the dedicated pulse counting arduino and calculates power and energy values from the pulse times and pulse counts.
Pulse Decoder + Ethernet
The above sketch, plus sending these values via a JSON string to the web using the official ethernet shield.
To read more about the web side of things have a look here: Energy Monitor + Simple Web Based graphing
Bench Testing - Pulse Generator
With the pulse counter build you may want to test that all 12 inputs are working correctly, Glyn Hudson has written a good sketch and documentation to do this here: Bench testing with a 12 output pulse generator