Anyone have success with an Express LRS/CRSF RX?

BetaFPV Nano 900Mhz attached to BeagleBone Blue UART5, /dev/ttyS5 mapped using -F to SERIAL_5. SERIAL_5 configured for RCIN (23).

I can clearly see the radio data stream on /dev/ttyS5 using tio but Ardupilot either doesn’t see it or can’t interpret it. Also tried restricting RC_PROTOCOL to just CRSF with the same result.

Arducopter 4.2.1, Debian 10.3 console, PRU is enabled.

For anyone else hitting this issue and comfy with sourcecode, have a look in HAL_Linux_Class.cpp which overrides the usual SERIAL_PROTO=23 logic that might allow CRSF to work, and instead only accepts input on ttyS4, which’ll be the “DSM2” port on the blue.

Just remove all that and let it use the default object and it should work. I’ll test this tomorrow…

I’m just setting up my BeagleBone blue and wondering if you managed to get this to work?

There’s a few issues with getting ELRS to work on the BB Blue, but it can be made to work if you’re comfortable compiling everything yourself.

Firstly there’s a baud rate issue that means you’ll need my commit AP_HAL_Linux: Use Linux-specific TCSETS2 ioctl to enable "non-standar… · ArduPilot/ardupilot@0326d5e · GitHub (which is on master, but not released yet).

Then there’s a hardcoded assumption in libraries/AP_HAL_Linux/HAL_Linux_Class.cpp that means it’ll only support the built-in RC receiver and not serial:

static RCInput_Multi rcinDriver{2, new RCInput_AioPRU, new RCInput_RCProtocol(NULL, "/dev/ttyO4")};

So you’ll need to change it to:

static RCInput_RCProtocol rcinDriver{nullptr, nullptr};

Here it is at a git patch:

diff --git a/libraries/AP_HAL_Linux/HAL_Linux_Class.cpp b/libraries/AP_HAL_Linux/HAL_Linux_Class.cpp
index b9a73248ba..1b12182709 100644
--- a/libraries/AP_HAL_Linux/HAL_Linux_Class.cpp
+++ b/libraries/AP_HAL_Linux/HAL_Linux_Class.cpp
@@ -148,7 +148,8 @@ static RCInput_PRU rcinDriver;
 static RCInput_AioPRU rcinDriver;
-static RCInput_Multi rcinDriver{2, new RCInput_AioPRU, new RCInput_RCProtocol(NULL, "/dev/ttyO4")};
+//static RCInput_Multi rcinDriver{2, new RCInput_AioPRU, new RCInput_RCProtocol(NULL, "/dev/ttyO4")};
+static RCInput_RCProtocol rcinDriver{nullptr, nullptr};

One day I hope to upstream a portable fix that allows the built-in receiver to still work as well as serial, but I don’t understand the Linux RCInput stack quite enough to do it yet. In theory I thought RCInput_Multi would allow this, but it doesn’t seem to. If you want to figure this out, be my guest!

Beyond this patch, you just need to set the serial proto in the usual manner as @dmazan pointed out and you should see the CRSF init in the messages.

Let me know if you get stuck, I’m happy to help!

Also by the way, if you want to first verify the ELRS receiver is correctly communicating with the BB, I used GitHub - AlessioMorale/crsf_parser: A package to parse and create CRSF (Crossfire) frames, developed primarily to interoperate with ExpressLRS (modified the to listen to the appropriate port)

Hi Tim. Sorry to say that I don’t have it working yet but that’s mostly because I haven’t been trying. The good weather window was upon me and I decided I’d rather fly working drones than look at code. I did note Neil’s initial suggestion and take a quick look but that was it.

Now with winter setting in and more information from Neil maybe I’ll get motivated to dig into it again. I’m fine compiling individual modules, it’s usually the build dependancies that mess me up.

I’ll post any successes and failures. Thanks for reigniting the question.


I should also add that I built a quad specifically for the BBB (a) because I love the idea of a US$ 40 flight controller that runs standard Linux and (b) I was at an early UAV conference years ago where there was a demo of compiling the Linux kernel while flying. I want to do that.


Thankfully compiling Ardupilot isn’t too hard, the instructions at BeagleBone Blue — Copter documentation are more or less correct, though I used the Docker method to keep things isolated, and think I needed to change the OS it used to be closer to the older Buster libc for it to run on the blue.

I do want to track down someone who knows the Linux HAL for guidance on the RCInput. It appears there’s implementations of serial RC protocols in the Linux HAL that are separate from the ones in the main RCProtocol library, which I find weird. Maybe a hangover from older days.

Hi ,

the default implementation on Beagles is using the pru to read the rcinput from rc receivers - the pru code use a feature under PRU called eCAP - capture pulses and then transfer using shared memory to ardupilot to decode the packets.
I was with a similar problem, how to use a Crossfire with beagles, but I couldn’t digging a lot but I believe you are rigth, changing the RCProtocol to Serial instead PRU under linux class.
But it’s important to see, once there is the packet read, how the transfer this packet from RCInput to ardupilot.

Yeah, there seems support both for using that PWM counter via PRU or reading DSM from /dev/ttyO4, but that doesn’t allow you to map that serial port as RCInput and have DSM work on it as a standard protocol.

I think a more future-thinking solution would be to change the default parameters to map a serial port to be RCIN and then let the user map that into the executable using either the DSM port or something else if they want.

Certainly since I got into building things with Ardupilot in the past 2 years, serial receivers are very mainstream, PWM/PPM is not at all common anymore (for RC input), and DSM is not probably one of the top serial protocols anymore. Ardupilot has a bit of a bias to the older stuff.

I’m using ELRS on all my builds now, even the ones that really don’t need it, just to keep everything constent. A lot of the CRSF stuff in Ardupilot still feels a bit new and exotic, though it does work. In getting it going on the Blue I realised just how fragile and peculiar the RC protocol detection and baud scanning is!

Happy to report that I made the changes suggested by Neil, recompiled and I now have a working ELRS receiver on my BBB drone build. I haven’t used waf before, being more of a cmake/gnu make kind of guy, but the compile and build went very smoothly. Did the build on a separate Linux box. If I want to compile while flying I’m going to need a bigger SD card.

Neil, do you expect your 0326d5e commit to be accepted for release or does it break other stuff? The other change is pretty trivial as long as you only want to use serial.

I too have only used ELRS receivers in the past year or so. Either 915 Mhz or 2.4 Ghz depending on what I’m using for ground station telemetry. The BBB gets 915 Mhz since it’s using Wifi for the ground feed. I still have a couple of FrSky Archers in some older builds but those will be replaced soon.

Neil, thanks for the tips. Tim, thanks for the motivation to get it done. Let me know if I can provide any help.


You’re gonna need a helluva battery along with a bigger SD card if you think you’re going to compile anything more than “hello world” while airborne. There isn’t much processing power available on the BBB beyond what it takes to run ArduPilot.

I know. The waf configure alone takes forever sitting on the bench. Just a reference to a demo years ago of a guy compiling the Linux kernel while flying.

My commit was accepted and signed off, so at a guess will be folded into 4.4, but doesn’t appear they’re going to put it into the 4.3 series. I wouldn’t worry about it not being there in a future release.

I’d be a little hesitant about loading up the blue. I’ve had a lot of trouble using mine with wifi telemetry to a GCS as I think the MMC controller is sharing interrupts with the wifi, so after a lot of network traffic the MMC controller fails to read/write and Linux fails then filesystem to read only. I’m currently using a USB wifi adapter to get around this issue.

I’m using mine in a rover though, so a controller failure isn’t as bad as it might be in the air!

Glad to hear things worked for you, that’s at least two ELRS users on the blue!