Since posting I adapted my code to use timer/counter 3, interrupt 3 and Attach/DetachInterrupt 5, and it works perfectly on my MEGA2560. So my listing of the numbering mismatch above seems to be correct.
If anyone is interested, here is the code:
#define CJ_ID "Wavelength2560 version:C"
/* Frequency counter using Timer 3 to work out the interval (i.e wavelength)
by counting between two consecutive rising interrupts (leading edge) on pin D18 (int3).
Based on Nick Gammon's similar program for Atmel 328P processor, here:
http://www.gammon.com.au/forum/?id=11504
Adapted for MEGA2560 by Chris Jennings, 8 May 2014.
Timer 3 is a high-precision 16-bit timer. By using no prescaler the timer counts
every clock cycle (62.5nS at 16 MHz). We deduce the frequency by multiplying the
counts between the leading edges by 62.5.
An advantage of this method is the quick calculation. e.g. at 10kHz the period
is 1/10000sec (100µS) so we get our result in just 100µS.
Note: Beware the mismatch in interrupt numbers used on MEGA2560 versus the Arduino
Attach/DetachInterrupt commands, as follows:
Arduino MEGA2560
int.0 pin D2 interrupt/counter 4
int.1 pin D3 interrupt/counter 5
int.2 pin D21 interrupt/counter 0
int.3 pin D20 interrupt/counter 1
int.4 pin D19 interrupt/counter 2
int.5 pin D18 interrupt/counter 3 (THIS IS WHAT IS USED BELOW) */
volatile boolean first;
volatile boolean triggered;
volatile unsigned long overflowCount;
volatile unsigned long startTime;
volatile unsigned long finishTime;
void isr () { // here on rising edge
unsigned int counter = TCNT3; // quickly save it
if (triggered) return; // wait until we noticed last one
if (first) {
startTime = (overflowCount << 16) + counter;
first = false;
return;
}
finishTime = (overflowCount << 16) + counter;
triggered = true;
detachInterrupt(5); // interrupt 3 off
}
ISR (TIMER3_OVF_vect) {overflowCount++;}// timer overflows (every 65536 counts)
void prepareForInterrupts (){ // get ready for next time
EIFR = bit (INTF3); // clear flag for interrupt 3
first = true;
triggered = false; // re-arm for next time
attachInterrupt(5, isr, RISING); // initialise interrupt 3
}
void setup () {
Serial.begin(115200); Serial.println(CJ_ID);
Serial.println("Calculate frequency on pin D18 from wavelength");
TCCR3A = 0; // reset Timer 3
TCCR3B = 0;
TIMSK3 = bit (TOIE3); // Timer 3 - enable interrupt on overflow
TCNT3 = 0; // zero it
overflowCount = 0;
TCCR3B = bit (CS30); // start Timer 3, no prescaling
prepareForInterrupts (); // set up for interrupts
}
void loop (){
if (!triggered) return;
unsigned long elapsedTime = finishTime - startTime;
float freq = F_CPU / float (elapsedTime); // each tick is 62.5 nS at 16 MHz
Serial.print ("Counts: "); Serial.print (elapsedTime);
Serial.print (" Freq: "); Serial.print (freq); Serial.println ("Hz. ");
delay (500);
prepareForInterrupts ();
}