FlySky FRM302 and FTR16S AFHDS3 receiver = 2.4GHz Long-Range radio system

ImmersionRC Ghost is the new long-range 2.4GHz radio system that is getting the most traction in the media in the last few days. However, IRC Ghost is not the first 2.4GHz SX1280/SX1281 LoRa based radio system that has hit the market. FlySky FRM302 TX module and FlySky FTR16S AFHDS3 receiver are available since May 2020, and underneath, they are the same technology as Ghost.

FlySky FRM302 2.4GHz long-range module and FTR16S AFHDS3 receiver

Continue reading “FlySky FRM302 and FTR16S AFHDS3 receiver = 2.4GHz Long-Range radio system” »

Crossbow LRS: ready for next tests

Looks like I was able to solve all major known problems with my DIY long range radio system Crossbow. I'm writing known, since no idea what lies beneath… Anyhow… What changed? Quite a lot:

  • I've extended Arduino-LoRa library with ability to transfer full packet in single SPI transaction. Right now, each read of write to SX1276 uses single transaction. Previously, there were 2 transactions per byte…
  • The same library now has ability to send packets in async mode. Previously it was blocking code execution until LoRa packet was transmitted. Huge waste on processing time
  • With OpenTX 2.2.1 on the loose, I was finally able to drop PPM input from Taranis to TX module and replace it with S.BUS. But not without problems. According to specification, S.Bus should be SERIAL_8E2. But my Taranis clearly outputs it as SERIAL_8N2
  • For now, OLED display is disabled. It was taking too much time to update it using I2C and TX module was loosing S.Bus packets
  • I've improved RC channels processing time, time required for encoding/decoding went down by 1ms
  • It is still LoRa32u4 II 868MHz based but I'm considering different hardware. For example ESP32 with LoRa. Time will show

Crossbow LRS development with LoRa32u4 and SX1276

Next test hopefully this weekend. If weather allows, of course. We have very wet autumn this winter in central Europe this year…

LoRa versus FSK modulation signal spectrum

LoRa modulation has some advantages. Like superb receiver sensitivity and immunity to interference. Has some problems, true, but at the end, it's a great way to send small packets of data to long ranges using low power.

Anyhow, today only one picture: how LoRa spectrum compares to FSK signal spectrum? Like this:

LoRa modulation vs FSK modulation

Those two peaks are nearby FSK stations, while plateau is 250kHz wide LoRa signal. Difference is at least clearly visible 😉

Crossbow LRS, I’m still doing this wrong…

Only two weeks ago I thought I solved all my major problems with DIY LoRa RC link. I was wrong. I was able to solve one problem (link unstable due to rouge packets messing up with protocol decoding), but an old problem came up again: PPM input from Taranis is no longer stable. At least I know why since this is a second time this is happening.

Current code read bytes from SX1276 buffer inside interrupt callback procedure (ISR). PPM decoding is also done in ISR. How many threads ATmega has? What happens when one ISR is triggered while second is still executed? Problems. The solution is to keep ISRs as simple and fast as possible. My code was not simple and fast enough.

On top of that, it turned out that Arduino LoRa library I’m using is not efficient. It performs 2 SPI transactions to read one byte from SX1276 FIFO buffer. So, 12 bytes of typical data packet equals 24 SPI transaction… Looks like I will have to do some low-level coding I wanted to avoid in the beginning… Oh well…

A proper way of doing read callback receive with Arduino LoRa

Arduino LoRa is a great library that brings LoRa support (SX1276/SX1277/SX1278/SX1279) to Arduino world. I'm using it in my Crossbow LRS project (still not stable enough for flight, work in progress). Until now, the biggest problem with this library I've found is that examples suggests that heavy protocol processing inside interrupt callback is fine.

Unfortunately, it is not. It can lead to unexpected processing delays, create conflicts with other interrupts, bus clashes and other hard to debug things. This is why, the better way is to do packet reading (and processing) inside main loop and use read callback only to set a flag. Like this:

Only please remember to set all variables modified in ISR routine as volatile.

DIY RC radio link: the problem of protocols

So, you want to build your own RC radio system? Long range maybe? Cool, I want to do it too. Since I’m pretty deep in that topic now, I can give you a hint or two. For example, have you thought about a protocol your radio system will implement?

RC link simplified

Or rather should I say: protocols? Why plural? If you want to do a RC link that talks with popular radios like FrSky Taranis on TX side and servos or flight controllers on the RX side, it will have to implement at least 2 different protocols. More likely 3. And if you will want to add telemetry downlink, 4 or even 5…

Continue reading “DIY RC radio link: the problem of protocols” »

Hands on: LoRa32u4 II 868MHz LoRa development board

Idea for Crossbow, DIY LRS system did not appearned in my mind out of nowhere. All my previous LoRa attempts were aimed at telemetry purposes only. E45-TTL-100 are cool, but bulky. If I would want to use them, I would either have to attach Arduino to it or hack it open and reprogram onboard CPU (like Qczek LRS does). Somehow it was not something what suited me very much.

But then I came across Adafruit Feather LoRa32u4 RFM95. Awesome idea. ATmega32u4 and HopeRF RFM95 LoRa module on one PCB, Arduino compatible, reasonably small and light. As a bonus, can be LiPo battery operated and has own 1S LiPo chanrger. The only thing I did not liked (OK, not the only one, but that was the biggest one) was price tag: $34.95 is somehow slightly more than I’m willing to pay for ATmega32u4. Even with radio module. So, after some digging on eBay I’ve found something that looked like a clone of Adafruit Feather LoRa32u4 RFM95: BSFrance LoRa32u4 II.

LoRa32u4 II 868MHz LoRa development board

BSFrance LoRa32u4 II 868MHz LoRa development board

Continue reading “Hands on: LoRa32u4 II 868MHz LoRa development board” »

Crossbow LRS second range test

Looks like crappy range problem from previous post is fixed now. Today I managed to reach 2.8km range with better antennas. The ones I got from LoRa32u4 supplier were NOT 868MHz antennas for sure! 2.4GHz/5GHz probably, hard to tell. Traces on PCB are ~60mm long, so perhaps those are loaded 3/2 monopoles for 2.4GHz or 1.2GHz? No idea.

Anyhow, I soldered 78mm long copper wires to both TX and RX and did the same route as yesterday. At 500m link was solid. At 2.8km, link was solid when antenna polarizations were matched. With 40dB of link budget still to spare. Quite nice!

LoRa modulation was set to:

  • Bandwidth: 500kHz
  • Coding Rate: 2
  • Spreading Factor: 8
  • CRC: On
  • Receiver Sensitivity (computed): -131dBm
  • Transmit Power: 17dBm (50mW)
  • Total link budget: 148dB
  • Payload: 13 bytes per frame

Now it's time to optimize air protocol a little and shave a byte or two…

QuadMeUp Crossbow LRS: introduction

Few days ago I mentioned that I'm working on my own DIY long range radio system (LRS) that I named QuadMeUp Crossbow LRS. Today I will share some more details about it.

First of all, I'm not creating anything new or "amazing". There are plenty of "DIY" or OpenSource LRS systems. OpenLRS for example. Or QCZEK LRS that is made from almost nothing at all. And amazing commercial systems like TBS Crossfire.

Is there a place for something else? I think there is. For example, I was so pissed of by complexity of OpenLRS. So many options, so hard to understand. Or do you know how much micro RX for Crossfire costs? And that you do not need 2W of power to fly up to 5km? And most of pilots owning Crossfire never flied > 2km?

This is why, my idea for DIY LRS is:

Continue reading “QuadMeUp Crossbow LRS: introduction” »

E45-TTL-100 not transmitting when connected to Arduino

While working on one of my project involving Arduino and E45-TTL-100 LoRa 868MHz radio modules, I’ve discovered that it is not working exactly like expected. Documentation states:

(…) When the data inputted by user is up to 58 byte, the module will start wireless transmission (…)
(…) When the required transmission bytes is less than 58 byte, the module will wait 3-byte time and treat it as data termination (…)

If I understand this correctly, E45-TTL-100 should begin radio transmission when:

  • 58 bytes were sent via serial port
  • serial transmission stopped for 3 bytes. So, at 9600bps, 3ms pause whould trigger transmission
    void loop() {
        Serial.print("Test");
        delay(100);
    }

In theory, code from the able should send string “Test” every 100ms. Unfortunately, it was not happening. Second E45-TTL-100 was not receiving anything. Also SDR dongle was not catching any transmissions. Something was wrong. I even contacted CD Ebyte, but they were unable to help me and The Internet was equally useless. What was wrong? No idea… looks like some kind of E45-TTL-100 MCU bug…

The solution

The solution is, hmmm, surprisingly simple. You not only have to stop transmitting, but also end serial port (Serial.end()) and open it again (Serial.begin()) after short period of time. In my experiments I’ve determined that 20-30ms of closed port selves the problem. So, code from above should be replaced with following:

void loop() {
        Serial.print("Test");
        Serial.end();
        delay(30);
        Serial.begin(9600);
        delay(70); //The rest of requested delay. So 100 - 30 = 70
    }

It might not be the prettiest solution ever, but it works.