Circuit Python tutorials in Robotics II
View the Project on GitHub MrPrattASH/Robotics-II-Circuit-Python
This page will show you how to use the rc.py library for controlling a FlySky FS-i6(X) controller with an FS-iA6B reciever in circuitpython.
Let’s get into remote controlled rovers! We will start simple and build up to a full state-machine-controlled system.
Option 1: Video tutorial. Option 2: Text Tutorial
The FlySky transmitter/receiver consists of 2 parts. The transmitter is the controller with the joysticks & switches, the receiver is the small box with the antenna.
As this is a drone controller, it has a few safeguards in place to prevent your robot from immediately driving off or turning on it’s attack mechanisms. Your transmitter should have the following setup:

The transmitter can send values for 6 different channels at any one time. It does have the option to have up to x4 toggle switches, and x2 potentiometers, but this is the intended output for our controller in this class.
Ch1 - Right joystick, Left/Right ControlCh2 - Right joystick, Up/Down ControlCh3 - Left joystick, Left/Right ControlCh4 - Left joystick, Up/Down ControlCh5 - SWB, 2 way toggle switchCh6 - SWC, 3 way toggle switchEventually, we will drive the robot throttle with CH2, and steer with CH1. CH3/4 will likely not be used, and CH 5/6 will be used for various mechanisms attached to our robot.
It is important to know that the receiver outputs a 5V signal. However, our Metro board has both 3.3 and 5v logic pins (or 5V tolerant at least), meaning that we don’t need to change voltage to read our signals.
You’ll need a wiring harness for the receiver, and the receiver itself


You can simply attach the wiring harness into the reciver, so that:


Now that you’re wired up, lets program this board and start recieving signals.
CIRCUITPY lib folder.To start, we will read only the horizontal movement of the right joystick (Channel 1). This channel returns a float (a decimal number) between -1.0 and 1.0.
import time
import board
from rc import RCReceiver
# Initialize the receiver. We only care about Channel 1 for now.
# Connect the signal wire of Channel 1 on your receiver to D0.
rc = RCReceiver(ch1=board.D0)
while True:
# Read the value of Channel 1
spin = rc.read_channel(1)
print("Steering (Ch 1):", spin)
# CRITICAL: This 0.02 sleep is required to stay in sync with the PWM cycle.
# Without this, the receiver readings will fail!
time.sleep(0.02)
Try to get the console to print exactly 0.0 by letting go of the stick. Then, try to hold it at exactly 0.5.
# Make sure your RC Transmitter is turned on!
# If you see "None" or errors, check that the signal wire is on D0
# and the receiver has power (Red/Black wires).
Now let’s add the vertical movement of the right joystick (Channel 2). Like Channel 1, this returns a value from -1.0 to 1.0.
import time
import board
from rc import RCReceiver
# Initialize with two channels
rc = RCReceiver(ch1=board.D0, ch2=board.D1)
while True:
spin = rc.read_channel(1)
throttle = rc.read_channel(2)
print("Ch1 (X):", spin, " | Ch2 (Y):", throttle)
time.sleep(0.02)
Create a script that prints “Forward” if the throttle (Ch 2) is greater than 0.5, and “Reverse” if it is less than -0.5.
# Use an 'if' and 'elif' statement inside the loop.
# Compare the variable 'throttle' to the numbers 0.5 and -0.5.
while True:
throttle = rc.read_channel(2)
if throttle > 0.5:
print("Forward")
elif throttle < -0.5:
print("Reverse")
else:
print("Neutral")
time.sleep(0.02)
Joysticks provide a range, but switches provide specific steps.
import time
import board
from rc import RCReceiver
# Initialize sticks and switches
rc = RCReceiver(ch1=board.D0, ch2=board.D1, ch5=board.D2, ch6=board.D3)
while True:
ch1 = rc.read_channel(1)
ch2 = rc.read_channel(2)
sw_l = rc.read_channel(5)
sw_r = rc.read_channel(6)
print("Sticks:", ch1, ch2, " | Left Switch (2-way):", sw_l, " | Right Switch (3-way):", sw_r)
time.sleep(0.02)
Modify the code so that Channel 5 acts as a “Safety Switch.”
# Wrap your print statements for Ch1 and Ch2 inside an 'if' statement.
# Check if the value of Channel 5 is equal to 1 (sw_a == 1).
while True:
sw_a = rc.read_channel(5)
if sw_a == 1:
ch1 = rc.read_channel(1)
ch2 = rc.read_channel(2)
print("Active - X:", ch1, "Y:", ch2)
else:
print("SYSTEM DISARMED")
time.sleep(0.02)
In advanced robotics, we don’t want to just “if/else” everything. We want to switch between different modes of operation. We can use the 3-way switch (Channel 6) to change the “State” of our robot.
Create a State Machine with three states: "MANUAL", "AUTO", and "OFF".
"OFF""MANUAL""AUTO""MANUAL", print the joystick values."AUTO", print “Robot is thinking…”"OFF", print “Shutting down…”
# 1. Create a variable called 'robot_state' and set it to "OFF" initially.
# 2. In the loop, read Channel 6. Use 'if/elif' to change the 'robot_state' string.
# 3. Create a second set of 'if/elif' statements to perform actions based on the string.
import time
import board
from rc import RCReceiver
rc = RCReceiver(ch1=board.D0, ch2=board.D1, ch6=board.D3)
robot_state = "OFF"
while True:
# 1. Update State based on RC Switch
mode_switch = rc.read_channel(6)
if mode_switch == 0:
robot_state = "OFF"
elif mode_switch == 1:
robot_state = "MANUAL"
elif mode_switch == 2:
robot_state = "AUTO"
# 2. Perform actions based on State
if robot_state == "MANUAL":
x = rc.read_channel(1)
y = rc.read_channel(2)
print("Manual Control Mode -> X:", x, "Y:", y)
elif robot_state == "AUTO":
print("Autonomous Mode -> Robot is thinking...")
elif robot_state == "OFF":
print("System is OFF")
time.sleep(0.02)