Thread Tools
Apr 05, 2006, 03:50 PM
Registered User
AnthonyRC's Avatar

PPM decode + PWM encode in one PIC

No feedback yet from the UAV guys, so let me try here.
Sign up now
to remove ads between posts
Apr 05, 2006, 04:22 PM
Registered User
I don't know if you want the replies 'here' or 'there'...

This isn't really an answer just an idea.

I wrote a camera switch that decoded one servo control stream and processed timer interupts etc and produced as output a servo control stream to control a servo driving the shutter.

As you have noted it is difficult to get stable servo output in the presence of interrupts etc. I wanted 1us stability so that the servo didn't jitter. My solution was to use a timer to time the duration of the control pulse and monitor the timer. When it got close to the end time I turned the interrupts off and used software timing to complete the period.

The tricky part was to sync the PIC so that the turn off code would fall at the right time. I was using a 12F675 @ 4MHz you may not have this problem at 20Mhz. My code to do this is shown below.

The ESC I wrote also uses a similar technique of using a combination timer+interrupt and software timing to produce stable motor drive PWM. For this project I wrote a Perl program that produced the PIC code for the PWM engine. The Perl program was able to compute all the delays, timing etc and then produce the 'PWM engine' code.

Are you producing all the output PWM signals in parallel or one after the other? I would be looking at producing them all in parallel. Maximum duration 2ms to produce all output channels.


---- Sample Code ----

; Disable interrupts for the last bit of waiting to
; get it as exact as we can
; To get a stable output pulse we need to arrive at ds_w3 with
; TMR1 in the same phase mod 4Tcy regardless of the phase we
; are in now. So given TMR1L & 3 we need:
; 0 -> 3 mod 4 TCY
; 1 -> 2 mod 4 TCY
; 2 -> 1 mod 4 TCY
; 3 -> 0 mod 4 TCY
movfw TMR1L
andlw 03h ; find out where we are in the cycle mod 4 Tcy
btfsc STATUS,Z
goto ds_w3 ; 0 -> 3 TCY
addlw -1
btfsc STATUS,Z
goto ds_w3 ; 1 -> 6 TCY (2 mod 4)
addlw -1
btfsc STATUS,Z
goto ds_w3 ; 2 -> 9 TCY (1 mod 4)
; FALLTHROUGH ; 3 -> 8 TCY (0 mod 4)
goto $+1
goto $+1
nop ; force this loop to 4 Tcy in length
btfsc TMR1H,7
goto ds_w3
; Clobber output
movfw gpioout
movwf GPIO
Apr 05, 2006, 05:04 PM
Registered User
AnthonyRC's Avatar
Many thanks for the info Tim. An interesting approach!.

I guess I'll answer the last part first, since that makes it difficult to do the first part.

I'm producing the PWM signals one after the other, but maybe it is time to reconsider that. My theory was that I wanted to limit the current drawn by the servos. When they are all driven in parallel I was concerned that I would have current spikes around that time. Spreading them out seemed to be a nice way to avoid that.

It is true however that even though I need to decode up to 7 channels, I only need to drive 4 channels' worth of servos (Rudder + Elevator + Ailerons + Camera angle). The other output channels, Camera switch, and ESC, don't draw large amounts of current when their PWM pulse arrives.

So, 7 x 2ms (ppm decode) + 2ms (pwm encode) + 1ms (i2c) = 17ms... fits easily into a 22ms frame.

Shame its midnight here... I'd give it a try...
Apr 06, 2006, 04:34 AM
Registered User
xtal's Avatar
file 18f905 is 8 channel decoder that can have pwm added [t2/ccp are available]
Apr 06, 2006, 03:33 PM
Registered User
xtal's Avatar
you might want to look at the 18F series... more instructions ,,translate to simpler/faster code ,,,,simpler branch inst,,,,bit toggle inst,,,,
faster retfie the 18f1220/1320 have 13 + io depending on cfig...and can run @ 40mhz
[10mhz*4]....and resonable price....and you can get samples!!!!!!

Cfg is a !@#$@##$@%
Apr 06, 2006, 03:38 PM
Registered User
xtal's Avatar
It may be an easy port from 16f88 to 18f1220/1320.......
Apr 11, 2006, 07:30 AM
Registered User
Originally Posted by AnthonyRC
No feedback yet from the UAV guys, so let me try here.

I am working on PWM decoding, that is, decode each channel individually.
My problem is that how about the accuracy of your code?

I verified my codes using ScottEdward's SSC. When I output the same PWM command using SSC, and decode the PWM signal, the result is shown below. The blue line is the SSC command, rnaging from 0-254, and the pink line is the result of decoding. Clearly, there is a lot of variance in the decoding result, ranging from +-5(small) to +-15 (large). Do you have any suggestion about how to reduce it?

I was thinking about the accuracy of the crystal oscillator, but I have not
test it. Do you have any idea about the oscillator with 4 pins? I saw that
people said the accuracy of the 4-pin oscillator is better.

And how do you get the PCM signal? From a certain pin of the receiver?

Any comment is appreciated. Thanks!
Apr 11, 2006, 10:00 AM
Acetronics's Avatar
Originally Posted by xtal
It may be an easy port from 16f88 to 18f1220/1320.......

18F1320 looks nice on the paper ... here I have two recent parts from the last revision ( DO ).

- EEPROM Bugs need to have BOR Enabled ...
- No way to program them any more w/ the Picstart.

Waiting a bit for Bugs free parts seem to be a must ...

I keep my 16F648 and 16F88 ...

Apr 12, 2006, 04:22 AM
Registered User
xtal's Avatar
I'm mainly using the 18f1220 but have not used the eprom...yet.
my biggest gripe is config setup....and computed goto's that work fine on simulator
but crap out real time,,,,but I love the instruction set!!!!
I use the FENG3 programmer and WINPIC [qsl version] with few probs....
Apr 12, 2006, 03:33 PM
Registered User
Mr.RC-CAM's Avatar
Perhaps the coolest decoder would be built using the soon-to-be-released propeller chip from Parallax. It is a custom ASIC that sort of has eight (8!) 128Mhz PIC-like MCU's in it. The MCU's (called COGS) share the I/O pins and can communicate to each other via a semaphore register set.

I picture one COG doing the PPM decoding and four others handling the PWM for eight R/C channels. That leaves three remaining COGS to do other things, such as model stability using gyros or IR leveling, video for OSD (yup, it has video sync generation built into it), and such.

However, the 40-44 pin chip is expensive ($25 each) and the object oriented compiler uses a custom language that looks a lot like PASCAL. I would have preferred C. So, I'll wait to see if someone introduces a C++ compiler for it.

As far as using one PIC to handle 8 channels of DSP decoding, my suggestion is to break it into two PIC's. Use one for the decoding, and the other as sort of a PWM co-processor. String them together via I2C. You will achieve jitter free (<1uS) performance from that sort of scheme.
Apr 13, 2006, 01:31 AM
Registered User

I made PPM to PCM recoder some time ago. The PPM decoder part is very accurate. I ouput the channels during the frame synchronization gap. If you can live with limited number of channels you can modify the output part. The code is posted here:

BTW, some PIC-s have capture timer (timer value is copied on interrupt to separate register). That would make even better PWM decoder.

Apr 14, 2006, 06:43 AM
Registered User
AnthonyRC's Avatar
Thanks for all the input guys. I ended up solving this by reducing the feature set a little, to 5 channels of decode, and 4 of encode. This is plenty to fly the plane, and lets me support various autopilot modes also. Encode/Decode jitter is < 1us, so well within the deadband of the servos.
The first in-air test of this system took place yesterday, with some results that I am very happy with. For the moment only the altitude hold mode was tested, but even on first flight it held within +/- 5m.

Mr. RC-CAM, the parallax chips look very interesting!, as you say though, expensive!. I think that my entire board costs less than that.
The dual-PIC approach will be designed into the next board, since its clearly a way to do this without many $$$ and with decent performance.

LexHSIEH , the PPM signal was retrieved from a slightly modified Hitec electron-6. There are plans somewhere on this forum, but I can't find them at present. Basically it is one wire cut, and one wire added to exit the PPM on channel 6.

xtal, I do have an 18F on the board (18F252) for the main processor, along with a 12F675 for the MSK encoding for the downlink. The high-priority interrupts are pretty nice on those.
Jul 01, 2006, 10:05 PM
Registered User
Originally Posted by AnthonyRC
No feedback yet from the UAV guys, so let me try here.
You can easily control 8 channels of servo PWM in 2ms total time with a 16 to 20 MHz P16 or P18 PIC. That can leave 18ms of a 20ms (50Hz) period to do your decoding. You should be able to get a lot of work done in that much time, especially with those oscillator speeds on a PIC.

There is free source code for this here:
8 and 16 Servo Drivers For PIC
Jul 02, 2006, 11:27 PM
Xtreme Power Systems
I went down this road with our 2.4Ghz system that is just about ready to be released. I used the capture reg on the PIC to time the PPM from the transmitter using 12 bits (4096) resolution and convert it to a packet and send it via a custom wireless module (5 mile range for U.S. users). On the receiver end, the data is converted back into a 12 bit value for each channel (500ns channel resolution) and output one after another to prevent the noise spikes. At 20Mhz you can easily output all channels in parallel, using a simple sort routine to output the shortest duration channel first, followed by each channel based on the pulse length. But in testing, this proves to be the least energy efficient method, and most prone to noise, especially with digital servos. The biggest thing that drove me nuts was the fact that the internall oscillators in the all of the PIC chips are horrible for stability. The receiver channel outputs varied by 2-3us in some cases. Using a real crystal yields perfect pulses down to about 25ns resolution.
Jul 03, 2006, 01:26 AM
Registered User
AnthonyRC's Avatar
I too tried the parallel output method, and experienced similar problems. The load on the supplies when all of the servos move at the same time is significant, and in my application (a UAV), where the servos are making small corrections all the time, it was unacceptable.

In the end I extended the technique described above (5 ch. decode, 4 of encode) to 8 channels of decode, and 4 of encode, with absolutely jitter-free outputs.
The extra 3 channels are actually decoded slower than the rest, since I primarily needed them for dialing in gains of control loops.

Once a second I decode all 8 channels, and then if I have time left in the frame, emit the 4 channels immediately. If there is not time left, I skip a frame.

Turns out that statistically, I rarely need to skip a frame. In all of the R/C systems I've seen the average pulse width for the first few channels is at the mid-point of the range (1.5ms), so even 8 channels of decode, is only 12ms. Leaving plenty of time for the 4 channel encode and inter-chip communications.

The dropped frame, if necessary, doesn't seem to upset neither the servos, nor the ESC (unlike one of the other experiments which was to 1/2 the output frame rate... servos don't like this).

So, for my application I'm pretty happy now, and have flown many autonomous hours using it. Servos are jitter free, I have enough inputs to fly the plane and tune the control loops, and I didn't need to throw hardware at it.

Looking back though, I think the right way to do this is to split this task between two of the lower-end (low-cost) PICS. One decodes, the other encodes, with an i2c/SPI link between them.

Thread Tools

Similar Threads
Category Thread Thread Starter Forum Replies Last Post
Question PPM decode + PWM encode in one PIC AnthonyRC UAV - Unmanned Aerial Vehicles 31 Mar 04, 2008 04:10 PM
Bearcat in-flight pic jbrundt Electric Plane Talk 7 Apr 11, 2003 01:24 AM
The lows and highs of eflight for a newbie (all in one day). f2racer Beginner Training Area (Aircraft-Electric) 5 Sep 10, 2001 10:53 AM
Keeping a plane in one's car stuartaw Electric Plane Talk 5 Aug 08, 2001 12:47 AM
2nd Trainer/Sport/Advanced "ALL in ONE Electric" hoppy Foamies (Kits) 11 Apr 20, 2001 11:19 AM