Major release of SPEKTRUM code

This forum is dedicated to software development related to MultiWii.
It is not the right place to submit a setup problem.
Software download
Post Reply
Danal
Posts: 137
Joined: Tue Oct 18, 2011 5:15 pm

Major release of SPEKTRUM code

Post by Danal »

The shared branch contains a major release of Spektrum Satellite support code, at or above R1012.

This is a complete rewrite of the Spektrum serial interrupt handlers. The goal was to reduce interrupt time, and make the handlers compatible with the "new" way of doing serial. The Spektrum handlers now spend minimal time with interrupts disabled. In fact, fewer clocks than the Arduino clock/timer handlers, which always run as part of the Arduino core.

This release also introduces new features:
  • GUI is now autosensed. End user can hot plug between RX and GUI and everything just works. Must NOT be armed at time of unplugging RX.
  • Boards with more than one serial port (e.g. MEGA) support any port for the Spektrum satellite via a #define in config.h
  • LCD_CONF works. (It used to immediately exit).
  • If the main loop gets behind for any reason, "old" frames are discarded from the buffer, and only the most recent frame is processed.

Danal
Last edited by Danal on Wed Aug 01, 2012 12:28 pm, edited 1 time in total.

Danal
Posts: 137
Joined: Tue Oct 18, 2011 5:15 pm

Re: Major release of SPEKTRUM code

Post by Danal »

As a side note:

I've had this code in flight test in the 'Danal' branch for months. When I integrated it into 'shared' yesterday, I did not completely realize that Alex was both packaging 2.1 yesterday, and working the GPS code. I also did not realize the full implications of some serial code that was a little different than what was in my branch.

Therefore, I collided with a couple of things Alex was doing and would like to publicly apologize for so doing.

And... there may be a tweak or two coming to iron out some of the things I missed in serial. The code works at this time and is good to fly on a satellite; the biggest gap is that the the GUI autosense may not be working as reliably as it should.

User avatar
Hamburger
Posts: 2578
Joined: Tue Mar 01, 2011 2:14 pm
Location: air
Contact:

Re: Major release of SPEKTRUM code

Post by Hamburger »

Does failsafe work with sattelite?
Would it matter if we moved default pin for failsafe detection to rollpin?

Alexinparis
Posts: 1630
Joined: Wed Jan 19, 2011 9:07 pm

Re: Major release of SPEKTRUM code

Post by Alexinparis »

Danal wrote:As a side note:

I've had this code in flight test in the 'Danal' branch for months. When I integrated it into 'shared' yesterday, I did not completely realize that Alex was both packaging 2.1 yesterday, and working the GPS code. I also did not realize the full implications of some serial code that was a little different than what was in my branch.

Therefore, I collided with a couple of things Alex was doing and would like to publicly apologize for so doing.

And... there may be a tweak or two coming to iron out some of the things I missed in serial. The code works at this time and is good to fly on a satellite; the biggest gap is that the the GUI autosense may not be working as reliably as it should.


No problem Danal ;)
I think it's a good thing we have now an efficient Spektrum code.

Other thinks about the code:
- You implemented something especially to check if there is old frames in the RX buffer (and if yes discard them)
I think it should be possible to handle the Spektrum RX frame exactly like we handle the GPS frame currently, and avoiding this mecanism.

ie: at each cycle or at each RC cycle:
- test the RX buffer
- if bytes are present, then decode them until the buffer is empty, even if it implies multiple frames

The interrupt would be used only to feed the RX buffer in background, as it's currently done for GPS.

This way, it ensures RCCommand info is the most up to date at each cycle, without having to check the lenght of the buffer. No need to compute time. And the Serial code would be left generic, without Spektrum spcecial cases.

Danal
Posts: 137
Joined: Tue Oct 18, 2011 5:15 pm

Re: Major release of SPEKTRUM code

Post by Danal »

Hamburger wrote:Does failsafe work with sattelite?
Would it matter if we moved default pin for failsafe detection to rollpin?


Yes, if the #define for failsafe is on, it works just great.

FAILSAFE_PIN is not used by Serial receivers such as Spektrum or Futaba SBUS. We reset the failafe counter directly when we get a valid frame on the serial port.
Last edited by Danal on Wed Aug 01, 2012 3:23 pm, edited 1 time in total.

Danal
Posts: 137
Joined: Tue Oct 18, 2011 5:15 pm

Re: Major release of SPEKTRUM code

Post by Danal »

Alexinparis wrote:
Danal wrote:As a side note:

I've had this code in flight test in the 'Danal' branch for months. When I integrated it into 'shared' yesterday, I did not completely realize that Alex was both packaging 2.1 yesterday, and working the GPS code. I also did not realize the full implications of some serial code that was a little different than what was in my branch.

Therefore, I collided with a couple of things Alex was doing and would like to publicly apologize for so doing.

And... there may be a tweak or two coming to iron out some of the things I missed in serial. The code works at this time and is good to fly on a satellite; the biggest gap is that the the GUI autosense may not be working as reliably as it should.


No problem Danal ;)
I think it's a good thing we have now an efficient Spektrum code.

Other thinks about the code:
- You implemented something especially to check if there is old frames in the RX buffer (and if yes discard them)
I think it should be possible to handle the Spektrum RX frame exactly like we handle the GPS frame currently, and avoiding this mecanism.

ie: at each cycle or at each RC cycle:
- test the RX buffer
- if bytes are present, then decode them until the buffer is empty, even if it implies multiple frames

The interrupt would be used only to feed the RX buffer in background, as it's currently done for GPS.

This way, it ensures RCCommand info is the most up to date at each cycle, without having to check the lenght of the buffer. No need to compute time. And the Serial code would be left generic, without Spektrum spcecial cases.


It may be possible to handle the frame "catch up" discard a different way, I'll ponder that. In many ways, I don't like having it in there. I put it in mainly for the LCD_CONF loop, because the blinkLED is blocking, and that makes frames pile up.

But... in terms of the core Spektrum code and the interrupt handler, Spektrum's design engineers made life very, very tough for code that is sort of multitasking and sort of not, like us. Spektrum chose NOT to put any form of unique header or trailer byte. And no checksum.* There are people who will tell you there are unique headers, but they are not looking at the complete picture. There are circumstances where those headers will change, in flight, to values that also occur in the bytes of the data payload. So you can't parse on values.**

The only valid way to detect a "start of frame" for spektrum is via timing. Thus the weird, touchy, flag-driven relationship between the interrupt handler and the "readSpektrum" function, and the timer code in both places. The main loop can theoretically call a read function every 1.5 to 2.x millis (on a healthy system), but there are exceptions. Enough exceptions to glitch the data, if you depend on all timer "start of frame" detection to occur only in the read functions and not in the interrupt handler. I've tried it, extensively, and you can see the glitches.

So... to sum up: We are stuck with some flags and timer handling to find the beginning of a Spektrum frame. And, as I said, I'll ponder the discard code. It is possible the "best" method would be to have a 16 byte RX buffer on the Spektrum port. Then, you could never have more than one frame... you'd just be in the progress of receiving one, or not, and when not, the frame in the buffer is the latest. Or something like that.

Danal





* I could kill them for no checksum... a loose wire between a Spek satellite and a "real" Spek 'base' receiver can cause a glitch in this otherwise very robust system. Ask me how I know...

** There have been a lot of arguments about Spektrum frame headers on the internet. People write a parser based on values, that works fine for one type of satellite bound to one type of TX... and therefore works fine for that person. I found enough conflicting information when I decided to write this code for MultiWii, that I decided to do my own research. I sat down with an Oscilliscope, multiple satellites, multiple TXs (some borrowed from a cooperative hobby shop owner) and documented everything. Perhaps I should publish that document some day. :)

itain
Posts: 75
Joined: Tue Aug 23, 2011 10:32 pm

Re: Major release of SPEKTRUM code

Post by itain »

Danal, Did you see how Paparazzi handle Spektrum satellites? They do use timing to sync frames. Some features that they support are also welcome here:
1. Auto detecting of 1024/2048 bits/channel.
2. More than 7 channels.
3. Support of more than one satellite for redundancy.
4. (probably impossible with Arduino due to boot-loader delays) Option to send binding command to satellites.

More than 7 channels is probably easy with minimal changes to the new code (readSpektrum must be called at < 10ms intervals or we're in a serious problem anyway!)
in def.h:

Code: Select all

#define SPEK_MAX_CHANNEL 8

in RX.ino

Code: Select all

static uint8_t rcChannel[SPEK_MAX_CHANNEL] = {PITCH,YAW,THROTTLE,ROLL,AUX1,AUX2,AUX3,AUX4};
(I must admit I have not tested this).

While RX.ino is looked at, see readRawRC() line 344:

Code: Select all

SREG = oldSREG; sei(); // Let's enable the interrupts
It's wrong. Either restore previous interrupt-enable bit to the previous value or explicitly enable interrupts. Never do both!

Danal
Posts: 137
Joined: Tue Oct 18, 2011 5:15 pm

Re: Major release of SPEKTRUM code

Post by Danal »

More than 8 is dead easy. All the code will work. It is just a matter of expanding the defines. Anyone who wants this can make the code changes in a snap, in their copy, and it will just work, for how ever many channels the TX sends.

Auto detect of 1024/2048... hmm... let me look at that! Might be kinda cool. Where is there code repository? And, by the way, there is absolutely no point in 2048 with the rest of Multiwii code using the numeric ranges that are basically 1000 steps wide, in rcData and so forth. The extra resolution will just immediately get thrown away as the values are passed into the main Multiwii code. In fact, I resisted putting in 2048 support at all... I did so at a point in time where I thought that all "new" JR/Spek TXs would be 2048 only. This is not true, but I thought it at the time. Anyway, if autodetect is easy, I'll certainly put it in... but 2048 really is pointless! :)

More than one satellite: This is only possible if the hardware is present. And the only hardware with enough serial ports is the mega and variants thereof. Which very few people seem to be flying. So, yeah, we could put it in the code, but it is a lot of complexity for very little gain. If anyone out there really, really, really feels they need more than one satellite, plug all the sats into this: http://www.nghobbies.com/cart/index.php ... cts_id=718. and then plug it into the Mwii controller.

Binding: Correct, the bootloader makes this impossible, at least when the Arduino and the Sat power up at the same time. The Arduino must power up first, and control the power pin to the sat via a digital IO pin... so code can turn it on and off... I have some experimental code that works. I have not yet taken the time to figure out if there is a good way to move the RX connector, which is almost always a 3-pin-servo connector like shown here: https://picasaweb.google.com/1070613651 ... 0025957426 if there is a good "spot" with 3 pins in a row that would be in the same place on most boards, and so forth. I have also found a bunch of oddities in bind that turn out to be power supply dependent of all things! This (may) explain the many threads I've seen that say something like "My spektrum won't bind on such and such ESC (or BEC), but will bind on a battery" or similar. Anyway, I'm working on binding. Perhaps I'm being too much of a perfectionist.

Danal

Danal
Posts: 137
Joined: Tue Oct 18, 2011 5:15 pm

Re: Major release of SPEKTRUM code

Post by Danal »

Oh, and yes, I agree the interrupt register handling in readRawRC() line 344 is wrong. This is not part of the spektrum code and I was reluctant to change it... even though it looks wrong to me.

Alex?

itain
Posts: 75
Joined: Tue Aug 23, 2011 10:32 pm

Re: Major release of SPEKTRUM code

Post by itain »

Danal wrote:Auto detect of 1024/2048... hmm... let me look at that! Might be kinda cool. Where is there code repository? And, by the way, there is absolutely no point in 2048 with the rest of Multiwii code using the numeric ranges that are basically 1000 steps wide, in rcData and so forth. The extra resolution will just immediately get thrown away as the values are passed into the main Multiwii code. In fact, I resisted putting in 2048 support at all... I did so at a point in time where I thought that all "new" JR/Spek TXs would be 2048 only. This is not true, but I thought it at the time. Anyway, if autodetect is easy, I'll certainly put it in... but 2048 really is pointless! :)

I found the paparazzi Spektrum decoder here:
https://github.com/paparazzi/paparazzi/blob/v4.0/sw/airborne/arch/stm32/subsystems/radio_control/spektrum_arch.c
Their Spektrum decoder is almost similar to MK.

I agree that 2048 is pointless, but 8 channels is not. In any case the mode it is determined by the TX and RX in binding time. Users who use a full receiver for the binding and then use just the satellite do not have control on the mode!
I have used a non-arduino mcu to experiment with different binding sequences. With a DX8 and HK Orange satellite I could get either 7/1024 or 8/2048 (never 8/1024).

Danal
Posts: 137
Joined: Tue Oct 18, 2011 5:15 pm

Re: Major release of SPEKTRUM code

Post by Danal »

Good point on some (many) bindings that force 2048 in order to get two frames, and therefore more than 7 channels. 2048 mode is needed for that reason. Good observation. :)



Regarding auto sense: The documentation at the beginning of the Paparazzi code is some of the best I've seen on Spektrum. They are almost totally correct. However, there are some bind modes they do not have, and those modes violate their assumptions. In fact, for a long time, I thought the TX info bytes/bits laid out exactly like they show... until I had some traces that conflicted with that. Mostly from DSMx capable Sats running in DSM2 mode. There are some other exceptions as well.

There is a relationship between binding and those header bytes. In the Paparazzi doc, they call things the "main" receiver and the "secondary". This is a partially correct term, in that, at bind time, pulses are sent to the Satellite at power up to put it in bind mode. Send a certain pattern (there are several) and that individual Satellite becomes the one that links back to the TX during bind by emitting RF that the TX receives. This is how the TX "knows" whether it is binding DSM1, DSM2, DSMX, 1024, 2048, one frame, two frames, etc, etc, etc. Send a different pattern, and that individual Satellite remains silent during bind, just accepting and memorizing things from what it receives. During any given bind, there must be exactly one "Main", and there can be any number of "Secondary". There are even ways to have more than one "main" linked while flying; giant scale guys use this all the time to have multiple RXs, each with sats, in a big model. Anyway, I'm getting off into edge cases. Suffice it to say there's even more than I'm describing... fully documenting the Spektrum bind process takes many paragraphs.

Here is they key point regarding the ability to "Autosense": 1024 vs. 2048 mode (and more, as above) is actually stored in the TX. The satellite only stores the GUID of the TX, and whether it was the "Main" v "Secondary". Nothing else is stored. The Satellite just passes through whatever it is sent, no matter how it was bound. One Frame, two frames, 1024/2048, all determined by what the TX sends, not what the Sat wants.

Furthermore, the Satellites bound as "main" will send "TX info" in their header (although, as noted above, not exactly as Paparazzi documented it), but Satellites bound as "secondary" do not send this "TX Info". And that's the real gap at the moment. If the end user plugs in a satellite that was bound while plugged into a "main" receiver (which is almost their only choice today, because we can't (yet) put a satellite into "main" bind mode for them), then that satellite will not be sending TX info... and, obviously, if it is not there, we can't sense it.

If/when I find a totally reliable way to bind from Multiwii, and we are willing to say "You MUST bind this way, using a sat bound elsewhere is not supported", then we can Autosense. Because we can force "Main" mode, and force a mode that sends a known header.

Until then, set it in the #defines.


Danal

Danal
Posts: 137
Joined: Tue Oct 18, 2011 5:15 pm

Re: Major release of SPEKTRUM code

Post by Danal »

P.S. I will put "more than 7" in the code in shared, test it, etc. over the next few days. As I said, it just works. No reason not to have it.

For RAM conservation reasons, I may make it a #define.

itain
Posts: 75
Joined: Tue Aug 23, 2011 10:32 pm

Re: Major release of SPEKTRUM code

Post by itain »

Danal, thanks for the info. I think the Paparazzi Spektrum support was mostly written for DSM2 (when DXMX was not available or at least not widely used). At that time there was a long discussion of the satellite protocol on RCGroups.

From reading MK source I see there's a certain procedure to plug in the satellite after the controller is on in order to bind it. It's probably consistent but not very user friendly...

I think an option to use two (or more) satellites is going to be very useful when mega and 32-bit controllers become more popular. I like to have very light receivers and less wiring, but never at the cost of losing reliability! Also I think it can be made really simple. Let me know if you want to open it for discussion.

Post Reply