Pages: [1]   Go Down
Author Topic: PPM encoder on Arduino Uno: Move from Timer1 to Timer2  (Read 1715 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 3
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Code:
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
Code:
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
Code:
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
Code:
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
« Last Edit: September 15, 2012, 01:38:53 pm by KaiDK » Logged

0
Offline Offline
Shannon Member
****
Karma: 159
Posts: 10409
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Maybe the problem is, that Timer2 is 8bit and therefore can only count to 255? (and we are counting up to 1700?)

Sounds highly likely - can you reformulate the timer1 code to work with counting to 255 or less first, then try porting to timer2.  That breaks down the task into two smaller subtasks via a working intermediate step (always a good approach).

Also I note you use pin 9 for timer 1, pin 3 for timer2 - sounds wrong to me, pin 9 is timer1's A pin, pin3 is timer2's B pin.  Why not use pin 11 for timer2?

The two timers are similar, but different - in particular timer1 has more modes I believe, so you need to see which mode is being used and see what the equivalent mode for timer2 would be.  The mode control bits will not be the same I'm pretty sure.
Logged

[ I won't respond to messages, use the forum please ]

Pages: [1]   Go Up
Jump to: