|
|
View previous topic :: View next topic |
Author |
Message |
Guest
|
PPM/PWM decoding |
Posted: Thu Oct 19, 2006 11:49 am |
|
|
Hello,
I'm trying to decode a series of PPM pulses with interrupts. The pulses are normal PPM used in RC-transmitters: pulse width between 1 and 2ms, with a synchronization frame in the end > 2ms
My transmitter has 7 channels, thus 7 pulses and 1 synchronization pulse repeated about 50 times per second.
I use this code to decode and print it on an lcd screen (some details deleted for code readability):
Code: |
#int_ccp2
void isr() {
pulse_width = CCP_2 - CCP_1; // CCP_1 is the time the pulse went high
if (pulse_width > 2400) {
servos[9] = pulse_width;
current_servo = 0;
} else {
servos[current_servo++] = pulse_width;
}
void main() {
output_d(1);
setup_ccp1(CCP_CAPTURE_RE); // Configure CCP1 to capture rise
setup_ccp2(CCP_CAPTURE_FE); // Configure CCP2 to capture fall
setup_timer_1(T1_INTERNAL); // Start timer 1
enable_interrupts(INT_CCP2); // Setup interrupt on falling edge
enable_interrupts(GLOBAL);
lcd_init();
while(1)
{
lcd_putc('\f');
printf(lcd_putc, "%lu %lu %lu\n%lu %lu %lu", servos[0], servos[1], servos[2], servos[3], servos[4], servos[5]);
lcd_putc('\n');
delay_ms(200);
}
}
|
It works fine, but the pulses outputted (4MHz crystal so they are printed out in us) are between 500us and 1500us. When I just connect 1 servo instead of the PPM frame, the pulse is correct between 1000 and 2000us. The oscilloscope shows that the PPM pulses are also between 1000 and 2000us as expected. Why does my application show them differently?
All comments are greatly appreciated!
Tom |
|
|
Guest
|
Re: PPM/PWM decoding |
Posted: Fri Oct 24, 2008 1:46 am |
|
|
Hi Tom,
Actually what you observed is ok. Actually problem coming with ppm definition. You need to find pulse position of servo values except syn pulse and not to measure pulse width of those pulses. That's the main difference between PWM and PPM.
Edit your isr coding like this, hope it will work.
Code: | #int_CCP2
CCP2_isr()
{
pulse_width = CCP_2 - CCP_1; // CCP_1 is the time the pulse went high
if (pulse_width > 2400) {
servos[9] = pulse_width;
current_servo = 0;
set_timer1(0); //overflow within 65ms which is higher than PPM frame refresh rate 50Hz(20ms)
//so always CCP_1_old < CCP_1 and no overflow at all...this overflow can be used as errror identification
} else {
pulse_position = CCP_1-CCP_1_old;
servos[current_servo++] = pulse_position;
CCP_1_old = CCP_1;
}
} |
salinda |
|
|
breadboard
Joined: 27 Mar 2009 Posts: 1
|
rc pulses |
Posted: Fri Mar 27, 2009 3:48 pm |
|
|
Hi Tom, I am working on same requirement and tried the proposed code. So far could not get it working, how about you?
br |
|
|
noyz
Joined: 31 Jan 2009 Posts: 59
|
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|