Serial.begin(115200);
This statement is executed twice: once in SetupTimer1(), and once in setup(). I'd delete one of them. They name different bitrates, too. I'm not sure whether you'll get the first one or the last one.
static float siPulseCounter=0;
siPulseCounter takes on only integer values. It shouldn't be a float. The Timer1 overflow ISR bumps this variable, and then compares it to 1. Both of those operations take a lot longer with float, with no added benefit. As long as siPulseCounter stays below 2^16, unsigned int will work. It should stay below that - 65536 Hz corresponds to almost a million RPM at 4 pulses/rev, which seems to be an unlikely speed for an auto engine. The attached ISR bumps this variable, and the Timer1 ISR examines it. It should be declared volatile; otherwise, the compiler may optimize it our of existence. I don't see any benefit from declaring it static, since it's already global; others may be able to illuminate a reason for doing it, though.
static float siSecondCount=0;
siSecondCount is either 0 or 1. It shouldn't be a float, either. char or unsigned char will work. The ISR bumps this variable; it should be declared volatile. The Timer1 ISR bumps and examines this variable, so it needs to be volatile, too. I don't think calling it static helps anything.
rpm = siPulseCounter*30; //Multiplier has to do with Reference Voltage this is at 5v ref.
I don't see any reference voltage in your description, and I particularly don't see any correlation between the RPM reading and any voltage. At 4 pulses/rev with a one-second counting window, the RPM is (60 sec/min)(1 sec)(1/4 rev/pulse) = 15 * pulse count. I don't know where 30 comes from. I don't see the point of declaring rpm as float, either, since it will only take on integer values.
Serial.println("RPM: ");
Serial.println(rpm);
You'll be better off to avoid using Serial.print() inside an ISR. I'll recommend that you set a flag in the ISR, and use it to trigger the main program to output the value.
CLSegraves:
... I'm trying to understand the timing of the timer ...
Here's a link to the ATmega328P datasheet: www.atmel.com/Images/doc8271.pdf. In the version dated 07/2012, the description of Timer1 operation is in chapter 16, starting on page 112. There's a lot to digest. Here's how I think the timer is used in your program:
- PWM outputs are disabled
- Waveform generation mode is "normal." That means that Timer1 counts up from its current value until it rolls over, and then starts over at zero.
- The input clock is the system frequency clock by 256 - 16000000 Hz/256 = 62500 Hz.
- The timer overflow interrupt is enabled. That happens when the timer rolls from 0xFFFF to 0.
- The initial value of the timer is set at 62500 ticks away from overflow.
Having said all that, I ran your code with a couple of modifications: Deleted Serial.begin(9600); set pin 5 to output; wrote an analog to pin 5; and added a jumper from pin 5 to pin 2. That gives me pulses on pin 2 at the default PWM frequency of about 977 Hz. I get readings of around 29280. I expected to see readings that bounce between 14640 and 14655, so what I got was pretty close to twice what I'd expect, and that's exactly what I'd expect with a multiplier of 30. So, maybe all that stuff above doesn't matter as much as I think.