SL4A Bluetooth Controller

Having had a bit of an unproductive Easter break I think it’s about time I got back to posting the concluding details of how the transmitter for the Bluetooth RC was implemented. I built the PIC-based motor and servo controller before acquiring the BlueSMiRF module so initially I wrote the following simple Python script based on the PyGame module to control the board via the direct (wired) serial connection using a USB gamepad.


import pygame
import math
import serial
import threading
SL4A Bluetooth Controller
MAX_SPEED = 0x1f

def clamp(min_val, max_val, val):
return max(min(val, max_val), min_val)

# initialise pygame module
clock = pygame.time.Clock()
running = 1

# initialise serial port 8 [COM9] for direct serial connection
ser = serial.Serial(8, 19200, timeout=1)
# initialise serial port 5 [COM6] for Serial over Bluetooth
#ser = serial.Serial(5, 115200, timeout=1)

print(“using serial port: %s” % ser.portstr)

# reset microchip

# setup asynchronous serial port reader
class AsyncSerialPortReader(threading.Thread):
def run(self):
while running:
debug_output = ser.readline()
if debug_output:
print(“>>%s” % debug_output.decode(“utf-8”))

port_reader = AsyncSerialPortReader()

# initialise joystick
print(“found %d joysticks\n” % pygame.joystick.get_count())
joystick = pygame.joystick.Joystick(0)
print(“initialising joystick: %s\n” % joystick.get_name())

# setup allowed events

# enter joystick event loop
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = 0
elif event.type == pygame.JOYAXISMOTION:
if event.axis == 0:
servo_pos = math.floor(MAX_SERVO_POS * (1 + clamp(-0.7, 0.7, -event.value))/2)
print(“setting servo position %s” % servo_pos)
elif event.axis == 1:
speed = math.floor(MAX_SPEED * clamp(-1, 1, event.value))
dir = 0 if speed <= 0 else 1
speed = abs(speed)
speed_dir = 1<<6 | dir<<5 | speed
print(“setting motor speed and direction %s” % bin(speed_dir))


# cleanup before exiting
SL4A Bluetooth Controller schematic
The code basically bootstraps the PyGame library and enters into an event loop, processing joystick events on the gamepad by mapping them to control commands for the car and writing these to the serial port. The event loop is rate limited because the absence of flow-control on the serial connections means that it is quite easy to overwhelm the PIC UART code with data. The script also includes an asynchronous reader thread for printing diagnostic information outputted from the board. When the BlueSMiRF wireless serial modem was integrated into the board, it was just a matter of commenting out line 20 and using line 22 instead which establishes the serial connection over my PC’s Bluetooth adapter i.e. using the RFCOMM protocol. Note, the BlueSMiRF must first be paired to the PC (default PIN 1234) before the Serial Port Profile (SSP) COM port becomes available for use.

The final step was to somehow port this code to my Android phone, using the accelerometer as if it were a free floating joystick. I decided on the Scripting Layer for Android (or SL4A)  platform which is a neat little collection of facades over the traditional Android Java API, with a wide variety of language bindings thus allowing one to quickly write simple applications in their favourite scripting language to harness the power of their Android device. Unfortunately the Android install packages for these apps are quite mainstream enough to be on the PlayStore so I had to manually download and install them from the website:



For more detail: SL4A Bluetooth Controller

About The Author

Ibrar Ayyub

I am an experienced technical writer holding a Master's degree in computer science from BZU Multan, Pakistan University. With a background spanning various industries, particularly in home automation and engineering, I have honed my skills in crafting clear and concise content. Proficient in leveraging infographics and diagrams, I strive to simplify complex concepts for readers. My strength lies in thorough research and presenting information in a structured and logical format.

Follow Us:

Leave a Comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.