PDA

View Full Version : Question PPM decode + PWM encode in one PIC


AnthonyRC
Apr 05, 2006, 07:11 AM
Maybe someone has 'been there, done that', and can help me here.

I'm struggling with part of a UAV design for a custom control board. The part with (as the title suggests) is responsible for the PPM decode (from the Rx), and PWM synthesis (to drive the servos).

Basically, it 'works'. The problem is that the 'jitter' on the PWM outputs is significant, and outside of the deadband on just about every servo that I have tried (over 10us).

The design uses a 16F88 PIC, clocked at 20MHz, with the PPM driving one of the GPIO lines, and 5 PWM outputs emitting from others.

I've looked at various ways to this, but keep hitting against brick walls when I try to reduce the jitter in the output. Here goes on the more technical details.

The basic problem is that during one 22ms PPM frame, I don't have enough time to decode 7 channels of PPM, and encode 5 channels of PWM, plus i2c communications with another device, without the PPM and PWM overlapping to some extent.
When the processor is busy processing an edge on the decode side, the encode side is delayed, and vice-versa. Using interrupts doesn't really help since the interrupt latency on this part is fairly significant, and adds to the jitter.

One thought was to use do something quite extreme, and 1/2 the frame rate. Interleaving PPM frame decode, with PWM encoding. This would 1/2 the frame rate to the servos. Is this something that is commonly done in the UAV controller world?. All of the servos that I have tried don't seem to be upset about the 1/2 frame rate. Of course the holding torque is reduced, and the speed is lower, but for UAV purposes with a fairly slow model it sounds reasonable.

Another thought was to reduce the number of channels supported. With only 4 channels decoded, and 4 channels synthesized, the problem goes away, but when you include Rudder, Elevator, Ailerons, Motor, Camera shutter, Camera position, you quickly exceed 4 channels. Of course, then there is the autopilot on/off which consumes another channel.

Yet another thought was to synthesise the 'jitter-sensitive' channels (Rudder + Elevator + Ailerons) while simultaneously decoding the 'jitter-insensitive' channels (Camera shutter, Motor, Autopilot on/off.

Of course then there is an additional problem, when the receiver is out of range, or the transmitter is powered down. The output of the receiver that I am using (Hitec electron 6) emits noise on the PPM output, which of course the PIC attempts to decode. Since there are many, many edges during the frame period this negatively affects the PWM synthesis timing. When this is detected its not possible to simply ignore the PPM, because when back in range I need to detect the request to turn the autopilot off.

My apologies for the rather verbose post here. I'm Hoping that someone can give some advice.

-- Anthony

kd7ost
Apr 05, 2006, 10:38 PM
Anthony,

I'm not a software guy so can't help you with code. But I'm a hardware guy that would probably use a hardware fix. You can get a servo controller for a fair price. Here's a few options. You only need to output a pulse to each servo once and the controller will continue to replicate the pulse. Up to 8 channels or better depending on the model you adapt. If you need to update a pulse for control purposes, you'll need to send a new pulse with proper duration for that particular servo. I don't know if this will help you but I hope it does.

http://www.seetron.com/ssc.htm
http://www.lynxmotion.com/Category.aspx?CategoryID=52

Dan

radiohound
Apr 05, 2006, 11:30 PM
Of course then there is an additional problem, when the receiver is out of range, or the transmitter is powered down. The output of the receiver that I am using (Hitec electron 6) emits noise on the PPM output, which of course the PIC attempts to decode.

If you use a failsafe receiver, the output of each channel can be pre-set to a chosen position (usually neutral or close to neutral). This will only ocur during lost signal conditions, and should solve this problem.

With some work, you should be able to sense this with your PIC chip, but it sure is easier to buy a failsafe receiver.

There are probably more, but here are a couple receivers.

FMA FS5 , a 5 channel failsafe reciever
FMA FS8 , an 8 channel failsafe receiver with copilot capabilities

Walter

LukeZ
Apr 06, 2006, 02:16 AM
Anthony,

As Dan mentioned there are already a lot of boards out there that might meet your needs, for an even larger list you might check out this thread: http://www.rcgroups.com/forums/showthread.php?t=459418&page=2

However, it sounds like you want to go the DIY route and that's fine. I can't offer very many specific suggestions, except, as Dan noted, that maybe you could come up with some hardware solutions.

It seems to me that camera shutter, and autopilot on/off don't need to be much more than, uh, on/off. Depending on your camera, you may be able to build a hardware shutter trip with a minimum of components. There's lots of good circuits in the DIY Forum as well as the AP forum. Mr. RC-Cam has lots of projects over on his site: http://www.rc-cam.com/projects.htm.

For the autopilot on/off you might consider a circuit similar to what Jay Francis was selling a while back here: http://www.rcgroups.com/forums/showthread.php?t=360746&page=6#post4564161. His RX-Mux was a complete hardware solution for switching servo commands from two sources - RX or autopilot.

Anyways, these might cut down by a few channels the number that you need to decode, perhaps freeing up just enough extra time for you to accomplish what you're trying to do.


Luke

danstrider
Apr 11, 2006, 05:14 PM
Anthony, I'm very interested in the exact features you list that you have working (decode 4 channels, output 4 or less). Check your PM!

Dan

AnthonyRC
Apr 12, 2006, 05:14 PM
Just a short message to say that this problem has been solved, although at slightly reduced specs.

The simultaneous PWM approach was considered, but the current summing is a killer.

The final approach was to reduce the number of channels to decode to 5 (Ail, Rud, Elev, Motor, Autopilot on/off/mode, and the number of channels to encode to 4 (Ail, Rud, Elev, Motor).
This allows for the 5 channels to be decoded, then the 4 channels encoded sequentially, leaving just enough time for an i2c chat with another uP on the board.

The solution results in absolutely rock-solid servo positioning with no noticable jitter (i.e. pwm jitter is within the servo's deadband).

This solution also allows the garbage that emits from the Rx when out of range (or Tx Off) to be processed without affecting the PWM outputs.

kbosak
Nov 25, 2007, 07:52 PM
Just a short message to say that this problem has been solved, although at slightly reduced specs.

I am very interested on details.
My understanding was that in order to keep PWM capture working reliably with Futaba PCM (that emits servo pulses in pairs - per channel), I needed many independent (6? 8?) PWM CCPM modules - while PIC16 series has at best 2.
Simple calculations shows that in order to capture with 1024 resolution, when teh difference of the lenght of duty cycle is 1ms, I need a system that has not more than 1us jitter for PPM receiver and not more than 0.5us for Futaba PCM receiver. With PIC running at 20MHz, instructions are executed at a rate of 5MHz, so one upinstr. takes 0,2us. I cannot imagine interrupt handling on PIC capturing the actual state of PWM requiring not more than 2.5 instructions. For this reason I believe it is not technically possible to capture PWM with 1024 precision using mid-range PIC microcontroller, unless we use dedicated PWM capture modules.
For this reason I am trying to move to ATMEGA162 which has 8PWM modules as I understand. What is your solution?

zik
Nov 25, 2007, 08:49 PM
Hi kbosak,

I think you're confusing interrupt latency with instruction rate. Let's just say that your PIC interrupt handler always takes 10 instructions to register an input change. It's deterministic - it's always the same 10 instructions that it takes to do the job - so all you do is take into account that your event happened 10 instruction periods earlier.

In your example if your instruction timing is 0.2us then your resolution will also be 0.2us. This is ample for 10 bit resolution. (In fact you could do a couple more bits of resolution if you wanted)

kbosak
Nov 25, 2007, 10:35 PM
Hi kbosak,

I think you're confusing interrupt latency with instruction rate. Let's just say that your PIC interrupt handler always takes 10 instructions to register an input change. It's deterministic - it's always the same 10 instructions that it takes to do the job - so all you do is take into account that your event happened 10 instruction periods earlier.

In your example if your instruction timing is 0.2us then your resolution will also be 0.2us. This is ample for 10 bit resolution. (In fact you could do a couple more bits of resolution if you wanted)
I believe I am not confusing it even if it wppears to be so from my post. I was just estimating that it takes not less than single uP instruction to jump into interrupt routine. Extremely, naively optimistic case I would say. Even then, the processing appears to be too slow.

Imagine and interrupt handling routine, that must notice the raising edge.
This is how I suppose this routine to be written:
Suppose that Futaba PCM raises its edges simultaneously on CH1 and CH2 as is used to do. PIC calls proper interrupt handling routine (at least one uP instr, or maybe ten), by some quirk selecting CH1-related interrupt to be raised first (it could have been CH2 as well - depending on which input pin is hotter and conducts better...). In the routine you are starting to do the job, you verify than input line corresponding to CH1 is up as expected but in a next clock or so the interrupt from CH2 is raised. PIC has single level intr priority so the first interrupt must finish (as I understand). So the interrupt routine continues handling CH1. It raises some flag saying f.ex. PWM_SIGNAL_HIGH[CH1]=1 (at least one instr expended if we use named variable in C), affects actual PWM_SIGNAL_RAISE_TIME[CH1] (16bit counter, so >=2 instructions expended if I use named variables). So we spent 4 instr+ the time to call the intr routine handling CH1. And only then interrupt routine for CH2 is called (it could be physically the same function). But it is some 4...10 instructions later. So for the CH2 its time of rising edge will be shortened by the duration of those around 4...10 instructions, what is longer than a period corresponding to 1/1024th of 1ms. Isn't it?
In general you don't know what is channel 2 and what is channel 3, and which is supposed to be paired with who, simply because I need my PIC to register the inputs for post-flight processing.
If Futaba is setting CH1 and CH2 up, the PIC may raise interrupts in any order. You don't know that if you detect in intr. routine that CH2 is high, it doesnt means that CH1 was,or is about to be high. Wlso I don;t want to make something cryptic that will correct itself just for specific model of futaba just to discover that PCM 2048 or something emiths channels in different order - thsi is not a good design as such, I will have much more details to care about later.
Unfortunately, channels from Futaba PCM may go through a gyro, FMA Co-pilot or whatever. On top of this is that my interrupt routine on failing edge has potentially a lot to do (do the math that computes the length of the actual cycle, check valid length, keep old value if invalid or go error state etc.).
At the end of it, I really need 10bit resolution if I want to drive camera pan/tilt servos with the PIC.

You might advise to use shared intr handling routine, check what channels are up then do the bookkeeping, but this is not simple. some channels are ups since a long time already and got their raising time noted, a pair of channels just appeared and both want to know the actual value of 16 biut timer for further processing etc. This will require if() for each channel to check RECENT_UP_BIT[CHn] followed by optional affectation of actual timer value. Worse, the fact that futaba emits CH1 and CH2 in parallel doesnt means that at the beginning of the shared interrupt handling routine both input lines will be high! one might be up at the beginning of intr routine, the other might be up sometime later and will go unnoticed during the lenghty shared bookkeeping, and will be handled in a second call to interrupt routine, this time after very long processing of the first call.

AnthonyRC
Nov 26, 2007, 02:25 AM
I am very interested on details.
My understanding was that in order to keep PWM capture working reliably with Futaba PCM (that emits servo pulses in pairs - per channel), I needed many independent (6? 8?) PWM CCPM modules - while PIC16 series has at best 2.
Simple calculations shows that in order to capture with 1024 resolution, when teh difference of the lenght of duty cycle is 1ms, I need a system that has not more than 1us jitter for PPM receiver and not more than 0.5us for Futaba PCM receiver. With PIC running at 20MHz, instructions are executed at a rate of 5MHz, so one upinstr. takes 0,2us. I cannot imagine interrupt handling on PIC capturing the actual state of PWM requiring not more than 2.5 instructions. For this reason I believe it is not technically possible to capture PWM with 1024 precision using mid-range PIC microcontroller, unless we use dedicated PWM capture modules.
For this reason I am trying to move to ATMEGA162 which has 8PWM modules as I understand. What is your solution?

I guess there is a slight confusionhere. As the title of the thread suggests this was a question of PPM decode, and not PWM. It was the single PPM stream emitted from a modified receiver that was being decoded, and not the individual servo outputs.

zik
Nov 26, 2007, 02:53 AM
Hi kbosak, I actually have a system very much like this in my "SkyBot" autopilot. I just handle any and all pending interrupts in the interrupt handler. Works for me!

Sorry AnthonyRC - I know this is off topic...

fmkit
Nov 26, 2007, 03:47 AM
Hi Anthony! If you were using Cypress PSOC chips instead of PIC ....
Even cheapest ($0.80) chips like CY8C21123 have enough hardware resources to decode/encode many (I use 7) channels practically without jitter.
I mostly use CY8C21234 connected direct to FM detector, one chip controls airplane, video link, K2 LED beacon(plus dropped frames warning), digital camera (on/off,focus,shutter) and TX for locating lost plane.

Unterhausen
Nov 26, 2007, 01:35 PM
I have the pod kit from when they first introduced the PSOC. Do you know if that works with the newer devices?

Jack Crossfire
Nov 26, 2007, 02:23 PM
U can get PIC assembly from vicacopter.com that does this using a 40Mhz clock and a very tight polling loop. This loop also does A/D conversion, 115kbit serial port I/O, and SPI I/O. There is no PPM. The remote control uses CRC checked phase shift keying to eliminate errors.

kbosak
Nov 28, 2007, 11:30 AM
I guess there is a slight confusionhere. As the title of the thread suggests this was a question of PPM decode, and not PWM. It was the single PPM stream emitted from a modified receiver that was being decoded, and not the individual servo outputs.
And that's the point. I posted off-topic! Sorry.
I did it mostly in desperation, looking for efficient method for general PWM capture suing PIC.

What I am trying to do is PCM-Receiver PWM decode using non-invasive methods. I am aware that f.ex. Paparazzi project used direct connection to the output line, but in PCM receivers it is not that well documented (where to steal this signal).
The people saying this 'works' apparently are using non-PCM receivers. I confirm that in PPM case everything is easy to be arranged, f.ex using PIC Interrupt-on-change feature. I am still battling with with the PCM simply because I believe and agree with what JettPilot said once somwhere, that when using PPM Receiver at the edge of reception when using FPV setup, you cannot always distinguish turbulence from glitch, what limits safe FPV flying in windy conditions to fairly small radius.
I believe that PCM output decoding is an unsolved problem on this forum - there are even some magic non-working solutions for interfacing PCM with Co-pilot etc. but this loks like a gray area. Anyway, thanks for advices I received.

dentompie
Nov 29, 2007, 01:54 PM
I've done it in a Pic16:
PPM in + DSP glitch filtering + 8 PWM out + stabilization
even processing power left!

As I recall I did need 2 or 3 timers...
result: http://tom.pycke.be/mav/86/autopilot-phase-1-stabilization-servo-controller

Unterhausen
Nov 29, 2007, 07:10 PM
Have you looked at the way it's done in the open source projects? The crossbow micronav uses an AVR, but it does a reasonably good job of decoding the PPM signal. The code is available on sourceforge.

kbosak
Dec 11, 2007, 09:33 PM
Most of people decode PWM servo signal by grabbing them directly at FM decoder pin (1 signal wire), others decode using Nchannels wires at the PPM decoder output easily, but what is difficult is to capture teh output when PWM signals ar raising at the same time or at any arbitrary moment (PCM or Spectrum receivers).
Apparently 'Getting PPM output from a Spektrum RX without any PPM stage'
answers the question "Is there an easy way to take these 7 (or more for that matter; never know when you'll upgrade to 9 or 12 channels) PWM signals and multiplex them into a single PPM signal which I could then feed to the Mikrokopter controler?" what is what onbe needs to do in order to implement the solution. :)

pionex
Feb 14, 2008, 10:51 PM
I'm trying to do something very similar such as be able to read 6 servo channels and output 6 pwm signals to the servos. I just decided to increase the horsepower and use a pic24 with 8 capture and 8 pwm generators. I think it will work, but I haven't gotten the pcbs designed yet to test. I'm designing it to work with the ar6100e spektrum receiver (and perhaps other rx's with similar pinouts, though anything would work with the appropriate connector cables). I would prefer not to modify the receiver at all, but its not a bad idea getting the decoded rf output. Does anybody know if and how you can get that signal from a spektrum RX? Is it PPM? I hope so, b/c I've already decoded the PPM signal from the trainer port of the radio that came with my CX2.

kbosak
Feb 15, 2008, 06:39 AM
just decided to increase the horsepower and use a pic24 with 8 capture and 8 pwm generators. I think it will work
It WON'T work guaranteed using any uC less than say 1GHz if the signals are rising simultaneously. By not working we mean jitter around 1% of the full scale (1% of 1024 positions is a few-10 units of jitter - quite noticeable, immediately noticeable with pan-tilt setup).
For spectrum 2.4GHz (supposed it outputs signals simultaneously - I put 90% chances on this), and PCM futabas (all of them), you will need FPGA to decode.
BTW There is a thread 'receiver servo capture'.

shanghai_fool
Feb 15, 2008, 07:11 AM
I agree completely. You just can't get the required resolution with interrupts. You will need individual capture timers for each channel. I have tried this. The ARM processor I am using has 9 capture timers and 8 PWM outputs but that doesn't leave any timers for the other things you need to do.

I did not find any PIC processors with that many capture timers.

fmkit
Feb 15, 2008, 07:36 AM
I used PIC and Scenix(Uicom) ,
and now completly into CypressMicro
all my RC planes and cars have UHF transceivers with CY8C2xxx chips that are much powerful than PIC. Clocked 12mhz I can only have 4 proportional and unlimited on/off channels, frames are 9ms /255 steps per ch.
Anyone without ASM skills I wish good luck, even 100MHZ clocked Scenix won't do.

kbosak
Feb 15, 2008, 10:23 AM
It's difficult to be a Microchip visionary those days :rolleyes:
We totally pinned down pionex.

Unterhausen
Feb 15, 2008, 01:36 PM
My thought is the easiest way is to capture the data stream off of one of the spektrum remote Rx

jetblackaircra
Feb 15, 2008, 03:26 PM
This may be too little too late, but I thought I'd mention that on our autopilot we have decided to save output pins by using a decade counter (like a lot of receivers use) to split the PPM into the individual servo PWM signals. So, we only have one input pin reading the pulse train, then one output pin spitting out a pulse train that is similar, but with the new servo command info. Keeps you from having to deal with 7 seperate pins. Makes the code a little bit faster to run, but we're using an ARM chip at 60Mhz so that's not much of a problem for us. :-)

Hope that helps.

pionex
Feb 28, 2008, 10:07 PM
I'm not sure about FM receivers, but the 2.4 GHZ do not output signals simultaneously. I only have a 2 channel scope, but no pairs of outputs overlap. Basically, on a 6 channel scope, this would look like a ppm signal, with about 12ms of time and some amount of dead time between each set of pulses. This is intuitive because the 2.4ghz wireless link does not send analog data directly, it sends digital data to a microprocessor that then generates the pwm. If that microprocessor had to generate all of the pwm's simultaneously, it would have the same problems you pointed out. I will verify this 100% when I get access to a higher channel scope, however.

I'm not sure about the microchip comment, but I see no reason why it would have any problem doing what i need to do. The PICs do only have 2 capture timers, but I'm nearly certain I can get using only 1. I'll let you know how it turns out. And I'm willing to bet that I can do it without any assembly and using the "humble" little pic.

So, I say not pinned yet, I just forgot about this thread.

Tom Harper
Feb 29, 2008, 08:40 AM
The PPM stream is easy to demodulate with the capture registers on a TI MSP430F1232. I've also handled 8 PWM outputs without any jitter.

The MSP430f169 will handle simultaneous PWM inputs with it's 7 capture registers. A second timer has 3 registers. More than enough to manage 8 PWM outputs. The 3 DMA channels allow it to take GPS input without disrupting the other timing. The clock rate is only 8 MHz. The resources do the job so the device is very low power.

These devices are available from SparkFun and are supported by IAR free software. They use in circuit programming.

PIC has some interesting products but they are a bit dated.

shanghai_fool
Feb 29, 2008, 09:58 AM
Thanks Tom
MSP430f169 looks interesting for capturing receiver inputs for at least 10 channels. If thats all it has to do, I'm sure its capable of being a front end. Do you know of any with more than 10 capture registers?

Donald

pionex
Feb 29, 2008, 12:53 PM
Well I don't think there is a way to get a direct PPM out of the receiver, but the point is that in time, the rising edge and falling edges of each servo pwm pulse does not over lap. There is a discrete period reserved for each signal. At least on the AR6100, I think its possible to somehow even multiplex (or just OR) the PWM signals and use a single capture to decode all of the PWM signals. If you ORed the signals, it should look like a 6 channel PPM signal, though I need to make sure that there is a detectable delimiter between each set of pulses.

To directly relate this to the topic, on a PIC it it easy to decode a PPM signal using a single capture, and you should have no problem generating PWM encodings, even without PWM peripherals (up to a certain amount of PWM signals also depending on the servo refresh rate). Just offset the rising edge of the one pwm pulse to occur just shortly after the falling edge of the previous pulse. This will ensure you have no edge transitions that get missed or delayed b/c they are scheduled to occur simultaneously.

Also, I'm interested to know why you feel the PICs are dated? I'm quite happy with the platform I have now, but I'd be interested in knowing what I am potentially missing. If necessary, we could start a new thread or PM so as to not get too far off topic. You might be interested in looking at some of the new pic parts, including the pic32 and pic24/dspic series just in case you haven't looked at the pics in a while.

BarryBaz
Mar 03, 2008, 08:13 AM
Hi
I use PICs quite a lot
http://www.kleefeld.freeserve.co.uk/index.htm

My solution to the original problem in this thread has been to increase the time available for other activity by not READING all the inputs EVERY time. ie read ODD channels during frame 1 then EVEN channels during frame 2
Obviously, you would have time your work to be done while the frame not being read was being transmitted.
This should give you more time in 1MSec increments.

Barry

Tom Harper
Mar 03, 2008, 08:24 AM
pionex,

You may be right. PIC's have come a long way and they have some interesting devices. I went with TI for their architecture and in circuit programming. Also the large family of product is uniform in architecture and code. You might check out the MSP430 family and see what you think. Another thread may be the correct place for discussion.

Tom

pionex
Mar 04, 2008, 05:10 PM
I'm going to a TI event this month to check out there new wireless ez-430s.