I currently have a PWM generator plugged into pin 2 on my Arduino and I am attempting to read the value of the PWM signal and output a value of the same duty cycle out to a servo motor.
Currently I have an interrupt for when the signal of the PWM generator goes high, I then read the value from TCNT1 and wait till the signal goes low, then read the value of TCNT1 again to get the high time of the PWM wave. I have calculated the 100% duty cycle value and the 0% duty cycle value and use that to calculate the current % duty cycle.
This code currently works and smoothly sweeps, but every 17 seconds on the nose, it freezes for a few seconds and then jumps to the current value. At first I thought maybe it was something interrupting but I disable all interrupts after the PWM interrupt triggers. I'm guessing it has to do somehow with the way my functions are working together (there isnt anything in my loop). Any help will be awesome, here is my interrupt function:
#include "mavlink.h"
#include <Servo.h>
Servo ServoOUT;
//PWM variables
volatile float start_time = 0;
volatile float final_time = 0;
volatile double duty_cycle = 0;
void setup() {
TCCR1A = 0;//timer1 in normal mode
TCCR1B = 0;//timer1 in normal mode
TCCR1B |= (1<< CS10);//start the timer with no prescaler, running at system speed of 16MHz
pinMode(2, INPUT);
ServoOUT.attach(11,900,2100);
attachInterrupt(0, servoDriver, RISING); // attachInterrupt allows rising signal from pin 2 to cause an interrupt in the processor, this allows the PWM signal to be read
}
void loop() {
}
void servoDriver() {
cli(); //disable all interrupts
start_time = TCNT1; //read high start
while(digitalRead(2)); //wait till PWM goes LOW
final_time = TCNT1; // read high end
duty_cycle = final_time - start_time; // calc high time
duty_cycle = (duty_cycle - 14342)/(33580-14342); // calc duty cycle %
if (duty_cycle < 0){} //filter out bad values
else if ( duty_cycle > 100){} // filter out bad values
else {
ServoOUT.writeMicroseconds(duty_cycle * 1000 + 1000); //write to servo
}
TCNT1 = 0x0000; //reset timer
sei(); //enable interrupts
}