Simultaneous pulse counter inputs

How many pulse counter inputs does an Arduino w/Atmega328P support? The ATmega328P spec. sheet mentions two 8-bit and one 16-bit counter. To a novice like me, this implies 3 counters. Can these 3 counters be used simultaneously to count the pulses from three different sensors? I've read reports online that only 2 counters are supported in this fashion, but I am confused by the spec. sheet's claim. I recall a few sources mentioning there being only two "interrupt-based counters". I'm very new to the Arduino, so any clarification on this would be much appreciated. I am assuming that these interrupt counters are hardware controlled counters. Can software controlled counters be used? I've seen many different functions in which users have performed pulse counting, but I am lacking a general overview of the benefits and disadvantages of each method. Can somebody enlighten me?

As for my application, I am working on a BTU meter for hot water heating (production) and consumption. The hot water in this case is for home heating, not personal consumption (like from the shower tap). I need to collect flow rate data from 3 flow meters (1 flow meter is for the produced BTUs, the other 2 are for spent heat BTUs). I also need to collect data from 6 temperature sensors (thermistors in this case). It is fairly straight-forward to read thermistor data from the ADC of the Arduino, and as such, I am more concerned with the number of pulse counter inputs.

I expect the frequency of pulses to be between 50 and 300 Hz. I will be logging data to the embedded microSD card (using an EtherTen), and eventually uploading the data to the network at the end of each day. The data logging doesn't need to be fast, perhaps every 1 min, but I would like data from each flow meter to be read at about the same time, perhaps within 5 s or less of each other. Can this be done with the available digital pins on the Arduino, or do I need to multiplex a single counter input and grab data in a more serialised fashion? Given the low frequency of pulses, I may need to sample pulses for up to 5 seconds to increase resolution, after which time the counter could be reset.

Since flow rate meters are utilised, I'll be dividing by time. It seems like the millis() function holds the time value. Will this function consume one of the counter/timer slots? I was planning on adding an RTC to timestamp the data (DS1302), if that makes any difference towards freeing up a counter. I've run across cases online of people using low-level hardware language to use a dedicated Arduino for a 12-input pulse counter, but this is a little out of my scope, and perhaps a bit overkill for this application.

In advance, please excuse the rookie questions; I have had trouble finding discrete answers to these seemingly basic questions. Any advice on how to tackle this is greatly appreciated.

You can use a combination of hardware (Interrupts) and software counting for your project. Arduino provides two versatile interrupt handlers but you can detect pin pulses on more pins with the right software Have a look at the library here:

i have not used it but the examples seem to provide a good basis for detecting and counting pulses on three pins

Have fun

There are 3 timers, timer0, timer1 and timer2. timer0 and timer2 are 8-bit. timer1 is 16-bit.

timer0 is used to provide millis(), micros(), delay() and delayMicroseconds(), so you'd probably want to leave that alone.

timer0 can be clocked from Arduino pin 4 (also called T0 in datasheet) if programmed to do so. timer1 can be clocked from Arduino pin 5 (also called T1 in datasheet) if programmed to do so.

timer2 cannot be clocked from external pin, but can, if the crystal oscillator is disabled, clock a 32768Hz watch crystal on the pins normally used for the main CPU oscillator (this is independent of the CPU clock which would be the internal RC oscillator in this case).

By using pin-change interrupts you can respond to changes on any pin in a matter of microseconds, so if you don't need ultra-fast counting this is the best solution I think as mentioned above.

The ultimate source of all information is the 328p datasheet (all 550 pages of it!) and the Arduino source code.

Thank you for this informative reply. So it seems that for the least amount of hardware changes, I can only use timer1 for pulse counting -- timer0 is taken up by the millisecond timer needed to convert pulses to a flow rate and timer2 requires some hardware changes for use as an input.

If changing the counter interrupt pins is only a mater of micro-seconds, then this sounds satisfactory for my application. The term "software counting" was brought up. Is this refering to this interrupt pin change method, or is there also another software-based method to count pulses from the digital I/O lines? What is this other method and does it have significant error, i.e. between loop iterations?

Your software could poll the pins for changes - this risks losing pulses if the software spends too long doing other stuff in-between polls.

Adding pin-change interrupts means not missing a change (but can still miss stuff if the software takes too long per change).

I am okay to miss pulse changes between pin changes. I do not need to have pulse counts from sensor A be matched up or even in-line with sensor B. It seems the data will be recorded serially for ease of implementation. I haven't programmed in C/C++ in a few years, but the logic might be as follows:

1) Grab all pulse counts from Flow Meter A for ~5 seconds. Record how many pulses, grab the time duration of pulse acquisition, divide. This is Flow Rate A. Write to variable; the counter section of the loop is finished.

2) Grab two voltages from ADC, divide, these are your temperatures for Flow Meter A. Write to variables. Multiply... This is your BTU/hr for A. Write to variable.

So we have surpassed 5 seconds plus ADC, multiply, and variable write times.

3) Change interrupt to different flow sensor. Count, repeat 1 & 2 for B sensors.

4) Change interrupt, Repeat 1 & 2 for C sensors.

5) Add all 12 variables of data to an array with a single time-stamp from the RTC (1 row) at current time. There will, of course, be a 15s+ discrepancy in the real time between the values, but this is not terribly important. Write to MicroSD card.

The other possibility is to log data per variable with it's own unique RTC time-stamp, but that will yield a 12x12 array per set of data that is uglier and larger, and perhaps with a NULL in the voided data locations.

6) Wait 1 minute, then repeat 1 thru 5.

7) Record BTU data for several months.

The logic here is probably over-simplified a bit. Please let me know if there are any serious show-stoppers in this scheme. Thanks all!