Volatile.
Essentially any variable declared within global scope (anything you declare before you get to setup()
) MUST have the volatile
qualifier if you want to use it within an interrupt service routine otherwise it will not be correctly utilised/implemented/instantiated.
As your code stands, you need to add voltatile
to all four of your global variables:
volatile int counter = 0; // if you're stopping at 470, int is all you need
volatile long rpm = 0;
volatile long z = 0; // this isn't necessary, see below!
volatile long ini_time = 0;
voltaile long end_time = 0;
Your ISR includes some wasteful instructions, which will increase the time it takes for the routine to complete. As @jfpoilpret suggested, you may be constantly interrupting loop()
. Cutting the time down may solve this:
Firstly, z = counter; rpm_counter(z);
. Pointless, if I'm honest. Why not just call rpm_counter with counter?
Secondly, rpm_counter()
function... it doesn't use the arguement you sent! "x
" is not used anywhere within the function, so why are you sending it?
Thirdly, even if my second point wasn't valid rpm_counter()
doesn't really need to be a function in its own right. Unless you're going to be calling it from lots of different places, just inline the contents of the function to into A_RISE()
:
else if (counter>470)
{ //470 is ticks per revolution
end_time = micros() - ini_time;
rpm = (60*10^6) / end_time;
counter = 0;
}
That could save a great deal of execute cycles.
setup()
to firstSerial.begin(...)
, that would give time for serial init before triggering encoder interrupts. – jfpoilpret May 31 at 6:56