RR Rated M For Mature
HOME   rrTV-PHOTO   GALLERIES   MY GALLERY   HELP-FAQ
myHOME PM pmRR MEMBERS 869 ONLINE 18 EVENTS SEARCH REGISTER  START HERE
 
9 pages [ <<    <     7      8     ( 9 )    >    >> ]15675 viewsPOST REPLY
Ron’s HeliProz South . MTA Hobbies . Model Rectifier Corp

.
.
Radio - Servo - Gyro - Gov - Batt > Starting a Home-Brewed PCM Receiver Project
 
 
MarkF
Senior Heliman
Location: Palo Alto, CA

My Posts This: Topic  Forum
I really am working on it...

Hi, Gang!

I really am working hard to get this code published as soon as possible. As I’d mentioned earlier, documenting it properly can take a lot of time. To help get folks started with understanding this project, I’m giving a sneak preview by reproducing a copy of (by far) the largest single comment block in the project: the module header for rx.c:

“This module contains the high-level routines for the "Omega 16" PCM-FSK R/C receiver. It is responsible for processing received command frames, parsing the received commands, and driving the servos to the commanded positions.

The driving philosophy behind the design of this project is _speed_. It was created to deliver the fastest possible frame-based receiver design, and it is indeed quite fast: as currently configured, it _completes_ the first servo outputs less than 32 microseconds (millionths of a second) after the last input sample of an incoming frame is received. In addition, this receiver surpasses current receivers in another way: it drives all 16 of its servos simultaneously, so that all 16 servo outputs will be completed within one millisecond (1/1000th of a second) of the end of a frame (this millisecond is unavoidable with the current generation of servos, due to the fact that the range of command pulses varies by about a millisecond).

While future versions of this project will explore even faster alternatives, such as command word-based processing rather than frame-based processing, as well as alternative methods of communicating with the servos, this is a useful starting point.

Beyond speed, a second major driver behind this project is improved RF performance. Unlike current PCM-FSK R/C systems, which sample the RF input once to receive each bit that is transmitted, this receiver samples the RF input five times for every bit, enabling it to reject much of the noise that causes other systems to lose information.

The need to drive all 16 servo outputs in parallel leads to a very demanding timing environment - the receiver must be able to generate 16 pulses simultaneously that can vary in width by just one microsecond, which is easy to implement in hardware, but quite challenging to deliver in software. To handle this extreme level of performance, this receiver contains its own "compiler" that creates a new machine language subroutine every time a new frame is received - this custom routine drives each of the servo outputs with "perfect" timing precision. Furthermore, the compiler infrastructure is capable of much higher levels of performance, and it is also extensible for next-generation systems.

-------------

At the core of this receiver is the concept of "events", which are specific Inputs or Outputs that must occur at a precise point in time. Input events are used for sampling (reading) the RF input received from the transmitter, and Output events are used to drive the servo pulses that communicate position information to the servos.

Due to the use of 5X "oversampling" to improve RF performance, an Input event must occur every 31.250 microseconds, without exception. This means that each section of the code must complete its processing in less than about 31 microseconds (uS), or data will be lost. This is particularly challenging during the millisecond long period while the servo pulses are being driven.

To help solve this problem, the receiver introduces the concept of "event lists". Rather than attempting to perform single Input or Output events, event lists are constructed that contain both Input and Output events (and in fact, when two events happen to be coincident in time, the receiver also supports the concept of combined Input/Output events). To begin the process of understanding how this receiver works, let's first concentrate on the millisecond long time period during which the 16 servo output pulses are being turned off (all of the servo outputs are turned on while the frame is still being received, but that will be described later on).

During this millisecond time period, the receiver must not only end 16 different output pulses at different times, it must also sample the RF input 34 times. While the receiver initially doesn't know when each output must end, it knows with certainty the times it must sample the RF input – this is the case because all timing in the receiver is driven by the timing of each RF sample event. Since the receiver knows when it needs to sample the RF input, it starts with an event list that contains all of the Input sampling events that will need to occur during that critical millisecond.

As a frame is being received, the receiver is "looking forward" to that millisecond time period, planning how to handle the events that must occur during that interval. As servo commands are received, the receiver translates each command word into an appropriate pulsewidth for that channel, and it creates a new Output event for each channel that contains an Output value to be written, and a point in time when that output should occur. These Output events are recorded in the event list, so by the time that the last command has been received in a frame, the event list contains all of the Inputs and Outputs that must occur during that critical millisecond time period (this list is stored in time-sorted order, using an efficient binary search with an “insertion sort” – see add_event() for more information on these techniques).

Following the command words in each received frame are two Cyclic Redundancy Code (CRC) words. These words contain a special mathematical code that is very effective at determining if the data bits that comprise a frame contain any errors. While the CRC codes are being sent, before the receiver even knows if the commands it has received are valid, it speculatively compiles the event list that it has constructed into a new executable machine language subroutine. This "event routine" contains the processor instructions that are capable of executing all of the events that are contained in the event list with "perfect" timing precision.

Something else occurs while the last word of the CRC is being received. The primary rf_input() routine has been counting the number of samples it has taken since the start of this frame. When it determines that the time is one millisecond before the end of the frame, it will automatically drive all16 of the servo output pulses high simultaneously. During this millisecond, the receiver simply continues receiving the CRC - this millisecond is a necessary overhead when driving current-generation servos. By overlapping the first millisecond of the servo pulses with receipt of the incoming frame, however, it is eliminated from the receiver's response time to commands.

After the last sample of the last CRC word has been received, things start to get exciting. First, the receiver must rapidly determine whether the CRC code words indicate that the frame is valid. If so, the main() routine will execute the new event routine, called drive_servos(), to end each of the servo pulses at the appropriate point in time. If, however, the CRC indicates that the frame has been corrupted, then the event routine that's been created is useless, for it almost certainly contains invalid servo commands. When this happens, the receiver must fall back to repeating the last known valid servo position. It does this by calling a routine called drive_last_servos(), which is in fact a previously compiled drive_servos() routine!

Errors are a fact of life in RF communications: it isn't a question of whether or not errors will occur, it's a question of how often they will occur. As a result, the code in the receiver is structured to deal with "bad" frames as efficiently as possible. To do so, it maintains a pair of RX_STATE structures. One of these structures, pointed to by the 'rx->' variable, holds the current receiver state. This state information includes the servo commands as they are received, a pointer to an event list as it is built, and once the frame is received, a pointer to the compiled event routine. Each time a frame is successfully received, main() simply calls the swap_buffers() routine to swap the 'rx->' pointer with a pointer called ‘last_rx->’, thus saving all of the information necessary to reproduce the last good servo position. As you may have guessed, the event routine associated with the current RX_STATE is called drive_servos(), and the event routine associated with the last good RX_STATE is called drive_last_servos().

Whichever servo driver is called, just before returning, the event routine will store the RF samples that it has read into the 64-bit global "rf_sample" buffer (the number of valid samples in rf_sample is called "rf_samples"). As main() loops around to begin processing the next frame, these samples that were taken while driving the servos actually hold the start of the next frame, and so the whole cycle continues...

At this stage, you have a good general overview of how the receiver works, so the best next step is to dive directly into the different sections of the code and read the routine headers. The code in the receiver is rather heavily commented to make it more approachable, and while the code itself is reasonably modular, the comments intentionally are not: most of the routine headers attempt to explain the broader context which the routine operates in. To get started, scroll down to the bottom of this file, and start with the main() routine, for that's where things start happening.”

Hopefully, the rest will come along quickly!

Have Fun!
MarkF
11-12-2003 Over year old.
PROFILE   PM   EMAIL   POSTS   BUDDY   IGNORE   HOMEPAGE  
 
 
MarkF
Senior Heliman
Location: Palo Alto, CA

My Posts This: Topic  Forum
Hi, Gang!

w.pasman: I'd ordered Feher's books describing the original FQPSK a week or so ago, and they just showed up from Amazon.com. As it turns out, Feher himself used a standard low pass filter on the original FQPSK, which means that FQPSK-B just uses a better filter! Based on the bandwidths Feher achieved with the original FQPSK, it looks like picking an appropriate low pass filter for EFQPSK, which will respond even better than FQPSK will to the same low-pass filter, will actually be a piece of cake! Hallelujah! This is great news, for it means that I won't have to spend months mucking around with different filter types to achieve the 10K bps goal! I'm a very happy camper, indeed!

Folks: As I'm getting closer to getting the V1.0 PCM-FSK code out the door, I've decided that the next step afterwards will be to integrate the EFQPSK modulator code with the BASS portable sound driver system, so that we'll have an EFQPSK generator that'll run on most PCs. And yes, I'll publish the full source to that one, too.

Have Fun!
MarkF
11-13-2003 Over year old.
PROFILE   PM   EMAIL   POSTS   BUDDY   IGNORE   HOMEPAGE  
 
 
MarkF
Senior Heliman
Location: Palo Alto, CA

My Posts This: Topic  Forum
Hi, Tom!

Thanks a bunch! You are actually right on. As it stands, 100% of the effort has gone into the same basic receiver functionality that today's systems offer, just much faster and with better RF performance. By making the source code available to the public, I'm hoping that other folks (maybe even the current R/C manufacturers) can build on that base, and add new bells and whistles that'll make our receivers even more useful!

A few examples that come to mind include:
  • Serial communications capability, to enable the receiver to communicate directly with a PC. This would enable all sorts of interesting possibilities!
  • Using the chip's on-chip I2C driver to communicate with an external EEPROM. This would allow the receiver to record not just permanent Failsafe commands, but it could also maintain a log of RF performance, battery levels, and even a flight log that contains the commands it received!
  • As someone suggested early on in this thread, there probably is sufficient horsepower available in the FSK version to include \"autopilot\" capability by communicating with external silicon rate sensors.
  • Support for \"slaved\" receivers, if 16 (or 29) channels are insufficient for the application.
  • Pre-programmed routines? With the addition of rate sensors, one of these days somebody's going to be pushing the \"pirouetting tumble\" button! \"\"
  • Data transmission capability! This would enable us to close the loop and have in-flight monitoring, which would make all kinds of interesting things possible!
I'm sure there are dozens of other ideas, which is why folks should dive in and give it a shot!

Have Fun!
MarkF
11-13-2003 Over year old.
PROFILE   PM   EMAIL   POSTS   BUDDY   IGNORE   HOMEPAGE  
 
 
w.pasman
Elite Veteran
Location: Netherlands

My Posts This: Topic  Forum
Hi MarkF

I guess you can do even better than low pass filtering and get even more performance? But if you get the 10kbps you reached your goal I agree
One thing I never understood: if you have phase jumps, isn't that in fact a very high frequency component? If you filter that out, what is left of the phase jump?
11-13-2003 Over year old.
PROFILE   PM   EMAIL   POSTS   BUDDY   IGNORE   HOMEPAGE   GALLERY
 
 
MarkFSenior Heliman - Location: Palo Alto, CA - My Posts This: Topic  Forum
Hi, w.pasman!

You're definitely on the right track. Rapid phase shifts generate huge bandwidths, which is precisely why standard FSK transmission takes up so much bandwidth. To make it work at all without complex filtering, the R/C manufacturers have had to slow it down to a transmission rate that is far below the channel capacity.

EFQPSK is different. Here's another look at the cool strip chart view that will be helpful in this discussion:



Ignoring that very first (blue) startup transient, which I'll fix when I can get back to this, do you see the first double pulse cycle, where the I & Q components just barely "kiss" at the two positive peaks? What might surprise you is that those two waveform cycles alone represent ten bits of information! The secret of FQPSK/EFQPSK is using efficient coding to reduce the degree of phase shift that's required to begin with, and to do so with a nearly constant envelope signal.

You are also correct that it is possible to improve the performance beyond just using a normal low-pass filter. In addition to the low-pass filters, the addition of a "hard limiter" after the two I & Q channels have been modulated to RF, just before the amplifier, can further reduce bandwidth requirements. The hard limiter, which has a "sigmoid" transfer function, prevents the signal from exceeding, say, +/-1 Volt. It does so in such a way that the closer the signal gets to +/-1, the more it is "compressed", preventing clipping distortion. This lets you crank up the power level higher (running the power amplifier at "saturation"), which is important for power efficiency.

What both of these components do is analagous: their purpose is to control the slew rate of the signal (in the case of the low pass filter), and to cap its excursion (in the case of the hard limiter). This will definitely change the signal slightly, but slightly is the point. Let's imagine that the filter that I choose will be reducing the signal by 10 dB at 4,000 Hz. As the FFT chart shows, the power level at that bandwidth is currently about -40 dB. Let's figure out what the voltage level associated with that bandwidth is. Since db = 10log(E2/E1), then we have -40 = 10 log(E2/E1), or -4 = log(E2/E1), and 10^-4 = 0.0001. In other words, the voltage level that's yielding a 4000 Hz bandwidth is just 1/10,000th of the full-scale signal amplitude. If we're working with a +/-1V signal, then the "problem" voltage level at 4,000 Hz is just 100 millionths of a volt (uV)! This signal level is so small that you couldn't even see an error 100 times that high on the chart above.

If my goal is to reduce that "problem" signal by 10 dB, I want to reduce that problem voltage from 100 uV to just 10 uV, which is just a gentle nudge to the signal. This slight tap won't even be visible on an oscilloscope - the only way that you'll be able to see it at all is in the frequency domain!

In other words, in RF you don't normally use a low-pass filter like a sledgehammer, you use it like a feather duster!

Have Fun!
MarkF
11-14-2003 Over year old.
PROFILE   PM   EMAIL   POSTS   BUDDY   IGNORE   HOMEPAGE  
 
 
MarkF
Senior Heliman
Location: Palo Alto, CA

My Posts This: Topic  Forum
Hi, Gang!

I've been furiously hacking away at the receiver, and have just reached an important decision point. For all practical purposes, the receiver is finally functionally complete, and 95% of the documentation is complete. I could publish the code now, but it needs much more testing. What brings this to a head is the new preamble detection routine. Let me explain...

I mentioned before that I'm using a four-bit preamble before each frame. For initial testing, the preamble was a simple code of '1010', and all the rf_preamble() routine did was to scan through the incoming data, ANDing the data with a mask, and essentially comparing it to '1010'. To make a long story short (you'll see two pages of comments in the code for the rf_preamble() routine alone), I now use a much more sophisticated preamble detection routine. While I don't call it that in the code, it's now essentially a Phase-Locked Loop, with error feedback from the CRC checker.

In the new routine, I realized that I could reduce the incidence of the receiver accidentally locking on to data in the middle of a frame by inverting the preamble every other subframe, so it becomes '0101' for even frames, and '1010' for odd frames. I then realized that the even/odd flag that is part of the command word that follows the preamble could be moved around so that it is transmitted immediately after the preamble. This allows the preamble detector to scan not just for the preamble, but also for the first data bit. In other words, the preamble detector now looks for '01010' for even frames, and '10101' for odd frames. In addition to this, there's some fairly complex symbol timing recovery logic that'll take a while to test thoroughly.

Normally, I wouldn't publish the code until all that testing was completed. However, doing so will require that I go create yet another project, a synthetic data transmitter on a PIC chip. That would delay availability of the code for a couple of weeks, and equally important, I'm really anxious to get moving on the EFQPSK project, which is something that I'm quite excited about.

Would you folks like to see the code now, or would you rather wait until I can create a test transmitter and know that everything works properly? Or alternately, is anyone interested in building a test data transmitter for this data format (perhaps a few hundred lines of C)?

I 'd very much appreciate your feedback!

Thank You!
MarkF
11-14-2003 Over year old.
PROFILE   PM   EMAIL   POSTS   BUDDY   IGNORE   HOMEPAGE  
 
 
MarkF
Senior Heliman
Location: Palo Alto, CA

My Posts This: Topic  Forum
Hi, Gang!

The more I think about it, the more I realize how silly the question I just asked was - I'm essentially asking whether you think something is worthwhile that you haven't seen! So, I'll publish V0.9 of the code tonight or tomorrow morning, and we'll see whether or not it generates any interest. If so, then I'll get back to it sooner rather than later. If not, it's still been a very worthwhile learning experience.

While I'm at it, I think I'll start a new thread - this one's getting to be a real pain in the arse to navigate! In fact, I'll start two different threads - I'll try to focus one thread on core receiver functionality, and the other on EFQPSK and RF issues.

Cheers!
MarkF
11-14-2003 Over year old.
PROFILE   PM   EMAIL   POSTS   BUDDY   IGNORE   HOMEPAGE  
 
 
The Flying Kiwi
Heliman
Location: New Zealand

My Posts This: Topic  Forum
Futaba 9CAPS PCM latency

I'm wondering if anything usable ever came out of this thread? I'm normally on RCgroups, but I didn't have any success there, so searching came across this thread.

I skimmed thru it, and even though it is well above my level of electronic understanding, I can appreciate the exercise in intellectual curiosity. Interestingly early on, there was some mention of a retrofit for the 9Z. This is the type of answer to my problem I was hoping to find.( Some updated guts for my 9CAP!)

I've been in the hobby for about 5 years, and am using a futaba 9Caps on 40 meg ppm. Recently, I've gotten keen on Dynamic Soaring (DS).

DS requires split second timing, flying, at very high speed, often very close to the ground. This is a situation where you want your radio system to respond reliably with a minimum of delay. ( I guess there are alot of similarities to 3D heli)

I was going to go the 2.4 gig route, until I found that carbon glider fuselages, are not 2.4 gig friendly. On a reccomendation, I have recently changed to 72 meg dual conversion PCM. I'm using 148DP recievers.

Now my control is rock solid, I doubt I've had a glitch, but I noticed a certain "mushiness" in the response. It was different to my FM system. I dug further. Turns out that I now have a system with some of the worst latency of the bunch. I don't know exactly how long, but it appears to be in the vicinity of 80 msec.

I dont want rock solid, or great response time, I WANT BOTH!!!

Is there any way of reducing the latency of a Futaba 9 CAPS on PCM?
10-02-2008 Over year old.
PROFILE   PM   EMAIL   POSTS   BUDDY   IGNORE  
 
 
lazy-b
Senior Heliman
Location: Manila, Philippines

My Posts This: Topic  Forum
FlyingKiwi: Look like there are no way of lower the Latency of Futaba 9CHP/9CAP PCM1024 thats about 83.5 Millisec......the cheapest solution is to use PPM, with PPM you can drop the latency to half, thats about 45 Millisec.

I just sold my 9CHP and purchase a Spectrum DX7.....now, Recently, just read John's report about the new Futaba 10CHP.....You will be amaze the speed of 10CHP, this is the Fastest Radio in 2.4 GHZ and Also in PCM 1024.

look like I also answer your post on RCGroups.
10-02-2008 Over year old.
PROFILE   PM   EMAIL   POSTS   BUDDY   IGNORE  
 
 
9 pages [ <<    <     7      8     ( 9 )    >    >> ]15675 viewsPOST REPLY
ReadyHeli . Power Helis . CANOMOD

.
.
Radio - Servo - Gyro - Gov - Batt > Starting a Home-Brewed PCM Receiver Project
 Print TOPIC Advertisers 

Subscribe to This Topic

Monday, November 23 - 11:37 pm - Copyright © 2000 - 2009 runryder.com | email | link to rr | START HERE | NF