Counting Pulses

Hello,
My project is to count pulses that occur in pin D5 from a water pulse meter which uses Hall effect sensor. I use Arduino Uno R3. And I want this count to be done completely in hardware, I use example code from Arduino Cookbook 2nd Ed, By. Michael Margolis. I use a push button attach to Pin D5 to "simulate" the pulses, but the counting didn't work smoothly (not in sequence).

/*
* Hardware Counting sketch
* uses pin 5 on 168/328
*/
const int hardwareCounterPin = 5; // input pin fixed to internal Timer1
const int ledPin = 13; 
const int samplePeriod = 100; // the sample period in milliseconds
unsigned int count;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  pinMode(ledPin,OUTPUT);
  digitalWrite(hardwareCounterPin, HIGH);

  // hardware counter setup (see ATmega data sheet for details)
  TCCR1A=0; // reset timer/counter control register A
} 
void loop() {
  // put your main code here, to run repeatedly: 
  digitalWrite(ledPin, LOW);
  delay(samplePeriod);
  digitalWrite(ledPin, HIGH); 
  
  // start the counting
  bitSet(TCCR1B ,CS12); // Counter Clock source is external pin
  bitSet(TCCR1B ,CS11); // 
  bitSet(TCCR1B ,CS10); // Clock on rising edge 
  delay(samplePeriod);
  count = TCNT1; // store the count value in TCNT1 register (16-bit register)
  delay(samplePeriod);
   Serial.println(count);
}

at the first run the Serial monitor show 25021, which I suppose to be 0. So I change the line :
count = TCNT1 - 25021; then the serial monitor shows 0. (are this wrong?)
what will happen when the count reach more than 65535 which is the maximum capacity of TCNT1 ? because I've already subtract it with 25021. When I push the push button the counting rise in numbers but not in series (I expect this because of the push button is debouncing). Should I build a code that handles the debouncing?
Thank you for help. God Bless
Regards,
Handy M

Without understanding your problem completely...

Can you use an interrupt pin and increment a counter each time your sensor is FALLING or RISING?

As far as your sketch goes, what if you declare:
unsigned long count = 0;

handy_mosey:

  count = TCNT1; // store the count value in TCNT1 register (16-bit register)

This does the opposite of what you say it does.

Should I build a code that handles the debouncing?

Either that or use a hardware debounce.

CarlW:
Can you use an interrupt pin and increment a counter each time your sensor is FALLING or RISING?

I'm not using an interrupt to increment the count, because I'll use the two of them for another purpose, so I use the pin D5 for the input.

As stated in a previous post you will get debounce problems using a button (and maybe a hall sensor) but I think the main reason for the count starting at 25021 is your zeroing the timer count in setup but don't set it to use D5 as a counting source until loop (and after some delay) so it will have incremented using the default clk until then.
Try moving the code that sets the clock source into setup before the line that zeros the timer count and get rid of delay out of loop as this will make button presses less responsive. Alter the count printing code so it only prints when the value changes and this will reduce/stop the runaway results in the serial monitor.

hello, I'm sorry its been a late reply from me
I've been try to understand the use of timer/counter.
now i've come up with this code

unsigned int count;
unsigned long lastCount;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  noInterrupts(); // disable all interrupts
  TCCR1A = 0; // Normal Mode
  TCCR1B = 0; // Reset Register TCCR1B
  TCNT1 = 0; // Reset Timer/Counter1
  OCR1A = 3; // Set the value to be compare with TCNT1 register
  bitSet(TCCR1B,WGM12); // set as CTC mode
  bitSet(TCCR1B, CS12); // Setup register TCCR1B
  bitSet(TCCR1B, CS11); //
  bitSet(TCCR1B, CS10); // Clock Source from external clock
  bitSet(TIMSK1, OCIE1A); // enable timer compare interrupt
  bitSet(TIFR1, OCF1A); // enable timer1 flag compare A
  interrupts(); // enable all interrupts
}

ISR(TIMER1_COMPA_vect){ // interrupt Service Routine
  count = TCNT1;
  TCNT1 = 0; // is this necesary??
  lastCount = count + lastCount;
  Serial.println(lastCount);
}
void loop() {
  // put your main code here, to run repeatedly:
//  Serial.print(count);
//  Serial.print("     ");
//  Serial.println(lastCount);
////  delay(1000);
}

Im using Hall effect sensor.

what can I do so I didn't missed one pulse from the sensor ?

I program my Arduino Promini based ATmega328 with Arduino Nightly version
still i cant see anything in my serial monitor.
please help me to correct my mistake. sorry for my english. :cold_sweat:
Thank you in advance
Regards,
Handy

Any variables you write to from an ISR need to be volatile... like this...

volatile unsigned int count;
volatile unsigned long lastCount;

You shouldn't use the serial port from an ISR. Try this instead...

void loop() {
  delay(2000);
  Serial.println(lastCount);
}

How often do the pulses come from the water meter? What is the shortest interval between them (in millisecs or microsecs)?

To save me having to spend ages studying your code what are you trying to make happen with all the TCCR1A stuff?

You said earlier that you are saving the external interrupt pins for something else - what?

...R

CarlW:
Without understanding your problem completely.

And there is the problem.

CarlW:
Can you use an interrupt pin and increment a counter each time your sensor is FALLING or RISING?

Unless you understand why you are using interrupts instead of polling - and counting pulses is a bad reason - you should not be using interrupts.

handy_mosey:
I'm not using an interrupt to increment the count, because I'll use the two of them for another purpose, so I use the pin D5 for the input.

And again - for what do you propose to use interrupts?

Does this only work on pin 5?
can it work on the other PWM pins?
What about doing this on multiple pins on the same project? - is that possible?