Flysky is a manufacturer of radio control (RC) transmitters and receivers that utilize the AFHDS (Automatic Frequency Hopping Digital System) protocol to wirelessly transmit PWM, PPM, or serial control signals to electronic speed controllers (ESCs), servos, and microcontrollers. In a real circuit, a Flysky system replaces hardwired potentiometer and joystick circuits with a 2.4 GHz digital RF link, translating physical stick movements into standardized digital pulse trains that a microcontroller or ESC can decode. The most common point of confusion for makers is conflating the Flysky hardware brand (like the popular FS-i6 transmitter) with the underlying AFHDS 2A protocol, or assuming all Flysky receivers output standard 5V PWM when many actually output 3.3V logic or inverted UART serial.

The AFHDS 2A Protocol: RF Theory and Frequency Hopping

To understand what Flysky is at a component level, you have to look at its proprietary RF protocol: AFHDS 2A. Operating in the 2.4 GHz ISM (Industrial, Scientific, and Medical) band, the system doesn't just sit on a single frequency. If it did, a nearby WiFi router or microwave oven would easily drown out your control link.

Instead, AFHDS 2A uses frequency hopping. Think of it like a convoy of trucks changing lanes on a highway every few milliseconds to avoid traffic jams; the transmitter and receiver hop across 16 distinct channels in the 2.402–2.480 GHz range in a synchronized, pseudo-random sequence.

Protocol Cycle Time: The AFHDS 2A transmission cycle is exactly 3.8 milliseconds, allowing for a theoretical refresh rate of over 250 Hz, though standard receiver outputs are typically throttled to 50 Hz (20 ms) to maintain compatibility with legacy analog servos.

According to reverse-engineering efforts documented by the RF hobbyist community on RCGroups, the protocol uses a highly efficient packet structure. It transmits 37-byte payloads containing channel data, telemetry requests, and fail-safe configurations, secured by a simple but effective CRC (Cyclic Redundancy Check) to drop corrupted packets rather than executing erratic servo movements.

Signal Outputs: PWM, PPM, and i-BUS Compared

When you buy a Flysky receiver (like the ubiquitous FS-iA6B), it breaks out the decoded RF data into physical electrical signals. Choosing the right output protocol is critical for your microcontroller's interrupt load and wiring complexity.

Protocol Wiring Signal Type Timing / Baud Rate Microcontroller Load
PWM 1 wire per channel Analog Pulse Width 50 Hz (1000-2000 µs) High (requires 1 interrupt per channel)
PPM 1 wire total Analog Pulse Train 50 Hz frame, 300 µs pulses Medium (1 timer interrupt per frame)
i-BUS 1 wire total Inverted UART Serial 115200 baud, 8E1 Low (Hardware UART + DMA)

Worked Numeric Example: Calculating a PPM Frame

Pulse Position Modulation (PPM) strings multiple channels together into a single wire by varying the spacing between fixed-width pulses. Let's calculate the maximum frame time for an 8-channel Flysky PPM output.

  • Pulse width: Fixed at 300 µs (0.3 ms).
  • Channel spacing: Varies from 1000 µs (1 ms) to 2000 µs (2 ms) representing stick position.
  • Maximum channel time: 0.3 ms + 2.0 ms = 2.3 ms per channel.
  • 8 Channels: 8 × 2.3 ms = 18.4 ms.
  • Sync Pulse: A final gap of at least 3 ms tells the microcontroller the frame has restarted.

Total Maximum Frame Time: 18.4 ms + 3.0 ms = 21.4 ms. This yields a maximum refresh rate of roughly 46 Hz. If you need faster control loop updates for a balancing robot, PPM is too slow; you must use i-BUS.

Where You Meet Flysky in Practice

You will encounter Flysky ecosystems primarily in three DIY and bench scenarios:

  1. DIY RC Vehicles and Drones: Using the FS-i6 transmitter paired with an FS-iA6B receiver to drive standard 50 Hz PWM electronic speed controllers (ESCs) and steering servos.
  2. Arduino/ESP32 Robotics: Reading PPM or i-BUS signals to control autonomous rovers, robotic arms, or walking hexapods where the RC transmitter acts as a manual override or teleoperation link.
  3. Telemetry Systems: Utilizing the bi-directional capability of AFHDS 2A to send sensor data (battery voltage, RPM, temperature) from the vehicle back to the transmitter's LCD screen via the receiver's secondary i-BUS/Sensor port.
Bench Tip: Always check the logic level of your specific Flysky receiver. While the FS-iA6 outputs 5V PWM, the FS-iA6B outputs 3.3V logic on its i-BUS pin. If you are interfacing with a 5V Arduino Uno, 3.3V might fall below the reliable HIGH threshold (Vih). Use a logic level shifter or power the Arduino at 3.3V if possible.

Real-World Scenario Walkthrough: ESP32 i-BUS Integration

Interfacing modern microcontrollers with RC receivers is a rite of passage, but it is fraught with protocol-level traps. Here is a real-world bench scenario involving the Flysky i-BUS protocol.

The Setup

You are building a WiFi-enabled rover using an ESP32 DevKit V1. You want to read 8 channels from a FlySky FS-iA6B receiver using the i-BUS protocol to minimize wiring. You connect the receiver's i-BUS pin directly to GPIO 16 (the default UART2 RX pin on the ESP32) and power the receiver from the ESP32's 3.3V pin.

The Numbers

Flysky's i-BUS is electrically identical to Futaba's S.BUS. It runs at 115200 baud, with 8 data bits, Even parity, and 1 stop bit (8E1). A full packet is 32 bytes long, starting with a 0x20 header byte, followed by 14 channel values (16-bit little-endian), and ending with a 2-byte checksum.

The Outcome

You flash your ESP32 code using the standard HardwareSerial library. The serial monitor outputs complete garbage: random integers, framing errors, and occasional 0x00 bytes. The rover twitches erratically and then stops.

What Went Wrong

The i-BUS protocol uses inverted UART. In standard TTL serial, the idle state is HIGH (3.3V), and a start bit pulls the line LOW. In i-BUS, the idle state is LOW (0V), and the start bit pushes the line HIGH. The ESP32's hardware UART expects standard non-inverted TTL, so it misinterprets the inverted idle state as a continuous stream of start bits, causing massive framing errors.

The Fix: You cannot just plug i-BUS into a standard ESP32 UART pin. You have two options:
1. Hardware Inversion: Build a simple transistor inverter using a 2N3904 NPN transistor, a 10kΩ base resistor, and a 1kΩ pull-up resistor to 3.3V.
2. Software Inversion: Use a specialized library like IBusBM which leverages the ESP32's internal UART signal inversion registers (documented in the official Espressif UART API) to flip the polarity in silicon, bypassing the need for external components.

Frequently Asked Questions

Can I bind a Flysky transmitter to a non-Flysky receiver?

Generally, no. The AFHDS 2A protocol is proprietary. While some third-party multi-protocol modules (like the FrSky R9M or IRangA modules) can be flashed with custom firmware to transmit AFHDS 2A, you cannot bind a genuine Flysky FS-i6 transmitter to a standard FrSky or Spektrum receiver. The RF handshake and frequency hopping sequences are locked to the Flysky ecosystem.

What is the real-world range of the AFHDS 2A protocol?

On the bench with a standard dipole antenna, you can expect reliable control up to 500 meters in open air. However, in urban environments with heavy 2.4 GHz WiFi congestion, or when the receiver is buried inside a carbon-fiber chassis (which acts as a Faraday cage), effective range can drop below 50 meters. Always mount the receiver antennas vertically and away from carbon fiber or metal battery straps.

Why does my Flysky receiver output 1500 µs when the transmitter is off?

This is the receiver's Fail-Safe state. When the FS-iA6B loses the AFHDS 2A RF link for more than 500 milliseconds, it stops outputting the last known stick position and defaults to a pre-programmed safe state (usually 1500 µs center for steering, and 1000 µs low-throttle for ESCs). You can configure these exact microsecond fail-safe values in the FS-i6 transmitter's RX Setup menu before binding.