Featured image of post Flysky (iBUS) interfacing to an arduino

Flysky (iBUS) interfacing to an arduino

Controlling an arduino with an RC Controller

Recently I had a need to control an arduino with an RC Controller, this was a proof of concept project that took 2 or maybe 3 tries to get working but from what I’ve seen online there’s not that much documentation for projects like this.

This is a very sparse and simple explanation for the process but hey, it should work.

This project, as well as other electronics projects I do use PlatformIO on VSCode because the Arduino IDE and I don’t get along. Even the newer 2.0 one.

Required parts

Flysky FS-A8S:

Breadboard:

Flysky FS-i6 RC Controller:

Arduino PRO Micro:

Wiring

There’s only 3 wires to take into account here:

Arduino Pro Micro PIN FS-A8S PIN
RX1(D0) IBus
Ground Ground
5v(VCC) Vin

Setting up the Arduino Pro Micro

The Pro Micro’s setup is pretty straight forward, since we’re using a FlySky RC Controller for this setup why not use it’s iBUS protocol wich is widely documented and easy to implement on the arduino since it already has a library. You can find the library here along with it’s documentation.

Platformio need to have a platformio.ini file, this is created automagically when you create the project using platformio’s interface -> next, next, next, confirm, wait, profit.

Once it’s created you can set up libraries and other stuff on it, since this is a basic proof of concept we’re only importing the iBusBM library:

[env:sparkfun_promicro16]
platform = atmelavr
board = sparkfun_promicro16
framework = arduino
lib_deps = bmellink/IBusBM @ ~1.1.4

As for the main.cpp arduino code (it’s heavily commented for your pleasure):

// Include iBusBM Library
#include <IBusBM.h>
#include <Arduino.h>

// Create iBus Object
IBusBM ibus;

// Read the number of a given channel and convert to the range provided.
// If the channel is off, return the default value
int readChannel(byte channelInput, int minLimit, int maxLimit, int defaultValue) {
  uint16_t ch = ibus.readChannel(channelInput);
  if (ch < 100) return defaultValue;
  return map(ch, 1000, 2000, minLimit, maxLimit);
}

// Read the channel and return a boolean value
bool readSwitch(byte channelInput, bool defaultValue) {
  int intDefaultValue = (defaultValue) ? 100 : 0;
  int ch = readChannel(channelInput, 0, 100, intDefaultValue);
  return (ch > 50);
}

void setup() {
  // Start serial monitor
  Serial.begin(115200);

  // Attach iBus object to serial port
  ibus.begin(Serial1);
}

void loop() {

  // Cycle through first 5 channels and determine values
  // Print values to serial monitor
  // Note IBusBM library labels channels starting with "0"

  for (byte i = 0; i < 5; i++) {
    int value = readChannel(i, -100, 100, 0);
    Serial.print("Ch");
    Serial.print(i + 1);
    Serial.print(": ");
    Serial.print(value);
    Serial.print(" | ");
  }

  // Print channel 6 (switch) boolean value
  Serial.print("Ch6: ");
  Serial.print(readSwitch(5, false));
  Serial.println();

  delay(10);
}

Then just build it and upload it onto the Pro Micro

Setting up the RC Controller

Just bind it, same procedure as 10 years ago.

Additional Considerations

This “sketch” outputs the values incomming from 6 channels, if you have another RC Controller that has more channels just change the loop that goes through every channel.

Once you have those values you can parse them into variables of your own definition. Take this as a starting point. Baby steps!

Built with Hugo