Thanks Nick Gammon for the link to the information on Hardware Timers, I have got it to read the RPM and work with the LED's. I took a look at the information on interrupts which was very useful and I have a much better understanding of the previous code I used.
I have inserted the swing code johnwasser recommended into the Timer code but I can't get that or my old servo loop to work with it, only the LED's.
With the original code it would work with "myservo.write(100);" command in the loop but the new code doesn't even move the servo which has led me to think I have put the servo commands in the wrong place?
The full code is below; any ideas where I have gone wrong are most welcome.
volatile unsigned long timerCounts;
volatile boolean counterReady;
// internal to counting routine
unsigned long overflowCount;
unsigned int timerTicks;
unsigned int timerPeriod;
int ledPin1 = 13;
int ledPin2 = 12;
int ledPin3 = 11;
int ledPin4 = 10;
#include <Servo.h>
Servo myservo;
int delayTimeF = 17;
int delayTimeM = 25;
int delayTimeS = 30;
int delayTimeVS = 40;
int i = 0; // variable to store the servo position
void startCounting (unsigned int ms)
{
counterReady = false; // time not up yet
timerPeriod = ms; // how many 1 mS counts to do
timerTicks = 0; // reset interrupt counter
overflowCount = 0; // no overflows yet
// reset Timer 1 and Timer 2
TCCR1A = 0;
TCCR1B = 0;
TCCR2A = 0;
TCCR2B = 0;
// Timer 1 - counts events on pin D5
TIMSK1 = _BV (TOIE1); // interrupt on Timer 1 overflow
// Timer 2 - gives us our 1 mS counting interval
// 16 MHz clock (62.5 nS per tick) - prescaled by 128
// counter increments every 8 uS.
// So we count 125 of them, giving exactly 1000 uS (1 mS)
TCCR2A = _BV (WGM21) ; // CTC mode
OCR2A = 124; // count up to 125 (zero relative!!!!)
// Timer 2 - interrupt on match (ie. every 1 mS)
TIMSK2 = _BV (OCIE2A); // enable Timer2 Interrupt
TCNT1 = 0; // Both counters to zero
TCNT2 = 0;
// Reset prescalers
GTCCR = _BV (PSRASY); // reset prescaler now
// start Timer 2
TCCR2B = _BV (CS20) | _BV (CS22) ; // prescaler of 128
// start Timer 1
// External clock source on T1 pin (D5). Clock on rising edge.
TCCR1B = _BV (CS10) | _BV (CS11) | _BV (CS12);
} // end of startCounting
ISR (TIMER1_OVF_vect)
{
++overflowCount; // count number of Counter1 overflows
} // end of TIMER1_OVF_vect
//******************************************************************
// Timer2 Interrupt Service is invoked by hardware Timer 2 every 1ms = 1000 Hz
// 16Mhz / 128 / 125 = 1000 Hz
ISR (TIMER2_COMPA_vect)
{
// grab counter value before it changes any more
unsigned int timer1CounterValue;
timer1CounterValue = TCNT1; // see datasheet, page 117 (accessing 16-bit registers)
// see if we have reached timing period
if (++timerTicks < timerPeriod)
return; // not yet
// if just missed an overflow
if (TIFR1 & TOV1)
overflowCount++;
// end of gate time, measurement ready
TCCR1A = 0; // stop timer 1
TCCR1B = 0;
TCCR2A = 0; // stop timer 2
TCCR2B = 0;
TIMSK1 = 0; // disable Timer1 Interrupt
TIMSK2 = 0; // disable Timer2 Interrupt
// calculate total count
timerCounts = (overflowCount << 16) + timer1CounterValue; // each overflow is 65536 more
counterReady = true; // set global flag for end count period
} // end of TIMER2_COMPA_vect
void setup () {
Serial.begin(115200);
Serial.println("Frequency Counter");
pinMode(ledPin1, OUTPUT);
pinMode(ledPin2, OUTPUT);
pinMode(ledPin3, OUTPUT);
pinMode(ledPin4, OUTPUT);
myservo.attach(9); // attaches the servo on pin 9 to the servo object
} // end of setup
void swing(int low, int high) {
for (i=low; i<=high; i++) {
myservo.write(i);
delay(delayTimeVS);
}
for (i=high; i>=low; i--) {
myservo.write(i);
delay(delayTimeVS);
}
}
void swing1(int low, int high) {
for (i=low; i<=high; i++) {
myservo.write(i);
delay(delayTimeF);
}
for (i=high; i>=low; i--) {
myservo.write(i);
delay(delayTimeF);
}
}
void loop () {
// stop Timer 0 interrupts from throwing the count out
byte oldTCCR0A = TCCR0A;
byte oldTCCR0B = TCCR0B;
TCCR0A = 0; // stop timer 0
TCCR0B = 0;
startCounting (500); // how many mS to count for
while (!counterReady)
{ } // loop until count over
// adjust counts by counting interval to give frequency in Hz
float frq = (timerCounts * 1000.0) / timerPeriod;
Serial.print ("Frequency: ");
Serial.println ((unsigned long) frq);
// restart timer 0
TCCR0A = oldTCCR0A;
TCCR0B = oldTCCR0B;
// let serial stuff finish
delay(200);
if((frq >=0) && (frq < 4)){
digitalWrite( ledPin1, LOW);
digitalWrite(ledPin2, LOW);
digitalWrite(ledPin3, LOW);
digitalWrite(ledPin4, LOW);
}
if((frq >= 5) && (frq < 10)){
digitalWrite( ledPin1, HIGH);
digitalWrite(ledPin2, LOW);
digitalWrite(ledPin3, LOW);
digitalWrite(ledPin4, LOW);
swing(100,120);
} // end of loop
if((frq >= 11) && (frq < 15)){
digitalWrite( ledPin1, LOW);
digitalWrite(ledPin2, HIGH);
digitalWrite(ledPin3, LOW);
digitalWrite(ledPin4, LOW);
swing(100,130);
}
if((frq >= 16) && (frq < 20)){
digitalWrite( ledPin1, LOW);
digitalWrite(ledPin2, LOW);
digitalWrite(ledPin3, HIGH);
digitalWrite(ledPin4, LOW);
swing1(100,140);
}
if((frq >= 21) && (frq < 80)){
digitalWrite( ledPin1, LOW);
digitalWrite(ledPin2, LOW);
digitalWrite(ledPin3, LOW);
digitalWrite(ledPin4, HIGH);
swing1(100,150);
}
}