Hi guys,
I am trying to partially adapt the code found here for my project. I am only using PPM generation (which are just some lines of code).
The PPM generation on Timer1 works great:
RCJoystick.ino
int pulseMin = 700, pulseMid = 1200, pulseMax = 1700; // PPM Pulse widths in uS
int InvertPPM = 0; // 0 = Non-invert, 1 = Inverted PPM output
unsigned char outPinPPM = 10; // PPM output pin (do not change)
int PPM_array[9];
int PPMFreq_uS = 22500; // PPM frame length total in uS
int Fixed_uS = 300; // PPM frame padding LOW phase in uS
void setup() {
pinMode(outPinPPM, OUTPUT); // set as output
// Initialize PPM channel array
char i=0;
for(i=0; i<8; i++) { PPM_array[i] = pulseMax; }
PPM_array[i] = -1; // Mark end
TCCR1A = B00110001; // Compare register B used in mode 3
TCCR1B = B00010010; // WGM13 & CS11 set to 1
TCCR1C = B00000000; // All set to 0
TIMSK1 = B00000010; // Interrupt on compare B
TIFR1 = B00000010; // Interrupt on compare B
OCR1A = PPMFreq_uS; // PPM frequency
OCR1B = Fixed_uS; // PPM off time (lo padding)
if (InvertPPM == 1) { TCCR1A = B00100001; }
}
void loop() {
}
InterruptTimer.ino
int ACC_PPM_length = 0; // Pulse length current total, used to calculate sync pulse
int *PPM_pointer = PPM_array;
int PPM_len;
// *********************** TIMER 1 **************************
ISR(TIMER1_COMPA_vect) {
PPM_len = *(PPM_pointer++);
if(PPM_len > -1) {
OCR1A = PPM_len; // Set pulse length
ACC_PPM_length += PPM_len; // Add pulse length to accumulator
} else {
PPM_pointer = PPM_array; // Reset table position pointer
OCR1A = PPMFreq_uS - ACC_PPM_length; // Calculate final sync pulse length
ACC_PPM_length = 0; // Reset accumulator
}
}
But because I want to use Timer1 (D9/D10) for other purpose, I need to move this to Timer2 which seems to be tricky.
I tried:
RCJoystick.ino
int pulseMin = 700, pulseMid = 1200, pulseMax = 1700; // PPM Pulse widths in uS
int InvertPPM = 0; // 0 = Non-invert, 1 = Inverted PPM output
unsigned char outPinPPM = 3; // PPM output pin (do not change)
int PPM_array[9];
int PPMFreq_uS = 22500; // PPM frame length total in uS
int Fixed_uS = 300; // PPM frame padding LOW phase in uS
void setup() {
pinMode(outPinPPM, OUTPUT); // set as output
// Initialize PPM channel array
char i=0;
for(i=0; i<8; i++) { PPM_array[i] = pulseMax; }
PPM_array[i] = -1; // Mark end
TCCR2A = B00110001; // Compare register B used in mode 3
TCCR2B = B00010010; // WGM13 & CS11 set to 1
TCCR2C = B00000000; // All set to 0
TIMSK2 = B00000010; // Interrupt on compare B
TIFR2 = B00000010; // Interrupt on compare B
OCR2A = PPMFreq_uS; // PPM frequency
OCR2B = Fixed_uS; // PPM off time (lo padding)
if (InvertPPM == 1) { TCCR1A = B00100001; }
}
void loop() {
}
InterruptTimer.ino
int ACC_PPM_length = 0; // Pulse length current total, used to calculate sync pulse
int *PPM_pointer = PPM_array;
int PPM_len;
// *********************** TIMER 1 **************************
ISR(TIMER2_COMPA_vect) {
PPM_len = *(PPM_pointer++);
if(PPM_len > -1) {
OCR2A = PPM_len; // Set pulse length
ACC_PPM_length += PPM_len; // Add pulse length to accumulator
} else {
PPM_pointer = PPM_array; // Reset table position pointer
OCR2A = PPMFreq_uS - ACC_PPM_length; // Calculate final sync pulse length
ACC_PPM_length = 0; // Reset accumulator
}
}
First problem is, that TCCR2C doesnt exist.. When I uncomment it, compiling is ok, but it doesnt work anymore.
I tried to find out how to solve it reading datasheet of Atmega and Googling about Timers and interrupts, but got no solution.
Maybe the problem is, that Timer2 is 8bit and therefore can only count to 255? (and we are counting up to 1700?)
Can someone of you help me out?
Thank you!
Kai