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:
- Flysky FS-i6 RC Controller - Aliexpress Affiliate Link
- Flysky FS-i6 RC Controller - Amazon Affiliate Link
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!