Multithreading Raspberry Pi Game Controller in Python

Multithreading Raspberry Pi Game Controller for Robot Control

Multithreading on the Raspberry Pi is an excellent way to keep the main thread of your program running as efficiently as possible. To demonstrate, I show how you can move game controller polling routines to a separate thread. Find the Python example code for robot control at the end of this feature.

In the last article, featuring this controller, I include example code to show how you might interface with the device using python code. Unfortunately, while using the inputs Python package, the Python program will only run one program cycle between each controller event update. This code blocking event meant that the program would not perform other tasks while the controller is inactive. So to fix this code blocking, I am going to add multithreading to the new example code; which I include at the end of this feature.

Multithreading Raspberry Pi Game Controller Robot Control
Multithreading Raspberry Pi Game Controller for Robot Control

Despite the code execution blocking of the Python inputs package, I was still able to code an excellent remote control robot vehicle. Variable speed and steering control were very responsive with no noticeable lag. And I can probably add a lot more functions to the code without the need to use multithreading. However, it will not be possible to add tasks that you expect to run during controller idle times. For example:

  • Robot sensor scans and updates to a display cannot be made during controller idle times.
  • An autonomous robot control function will not be able to poll events from an idle controller without becoming blocked.
  • It will not be possible to switch from an active autonomous function to manual control without the independent function polling controller events.
  • OpenCV applications can be less efficient if processing is restricted to fit between controller event polling.
Multithreading Performance
HTOP Terminal Application
HTOP Terminal Application

The Terminal application above can help check the multithreading performance of your Python application. You can install the program by entering the following command at the Terminal command prompt of the Raspberry Pi:

To run the program just enter the following:

Then open a second Terminal session to execute a Python program.

Multithreading

Ideally, I want the main thread of my program to run as efficiently as possible while looping continuously; executing function after function. However, connected devices such as game controllers, LCDs and many kinds of external sensors can drastically slow down or block the main program. This slowdown is due to slow IO interfaces rather than processor utilisation limits.

The game controller can restrict the scope of my robot programming in ways explained above. If I use multithreading programming techniques, I can run the game controller class methods in a separate thread from the main program. I can then use custom class methods to poll the game controller indirectly, thus avoiding the code execution blocking methods of the game controller class.

Running IO devices, in separate program threads, will allow more processor utilisation in the program’s main thread.

Multithreading Example Code

The example Python program shows one way to implement multithreading. However, this implementation may not suit all situations so research for a suitable implementation for your specific application. The example program is experimental and is so far working on a Raspberry Pi 3.

Note that multithreading works best with IO devices if the thread remains active for long durations, this is due to IO devices like the game controller having very low processor utilisation.

Robot Control Controller Button Map
Robot Control Raspberry Pi Controller Button Map for Python Inputs Module
Code Snippets

Here I will make a few notes on code snippets taken from the full Python program.

Using the button reference in the game controller image above we can create a list of buttons we want to use. The default value is included to indicate the controller button resting position. The dictionary data structure allows access to button values utilising the button name as the key. The button names are referred to as commands throughout the program.

We initialise the class that contains the gamepad and multithreading methods.

Before we start the gamepad object, we need to load it with controller buttons from the list created earlier. The object multithreading method will only record gamepad events from the controller buttons included in the list.

We execute the object start method to begin the multithreading. This object method will start the polling of the game controller in a separate thread from the main program. Therefore, the idle game controller will no longer stop the main program thread from executing.

The gamepad object read method returns any new controller event update; which returns button name and value. If there is no event update, the read method will return ‘No Match’.

We can now poll the game controller as many times as we want without blocking the main program.

If there is a new event update from the game controller, the gamepad object read method will return the name of the button. Python ‘if’ statements is an excellent to apply actions to individual controller buttons.

I slow the program without affecting current functions. Reducing processing loops will help save battery power on a project such as a robot vehicle.

Class Methods

So, here is the gamepad read method that will return any new game controller updates. Updates are put in the queue object, but the read method will only pass the last entry in the queue (LIFO – last in first out). Therefore, the read method will flush any older entries from the queue object. The read method will return a ‘No Match’ if the queue is empty.

The above method will return the latest value for any button in the list.

The start method starts the above method to run in a separate thread. Every game controller event is collected and filtered here. If the idle game controller blocks this method, the main program thread will continue to execute.

The Full Multithreading Program

You can also get the full multithreading Python code example from GitHub here.

Or download the code from the Raspberry Pi Terminal by entering the following at the command prompt.

Copy and paste the above line to the Terminal if possible.

Related Articles

Raspberry Pi Controller for Robot Control Review

Raspberry Pi Controller For Robot Control Review Link.

Robot Control with Raspberry Pi and Python

Robot Control with Raspberry Pi and Python – Link.

Buying Featured Items

The purchase price is going to vary greatly depending on how quickly you want the items. Therefore shop around checking out Amazon, Ebay, Adafruit and local electronic stores.

The Pi Hut

  • Raspberry Pi Compatible Wireless Gamepad / Controller – Link

UK Searches:

UK Amazon:

  • Raspberry Pi – Search
  • MicroSD Card – Search
  • Raspberry Pi Compatible Wi-Fi Dongle – Search

US Searches:

US Amazon:

  • Raspberry Pi – Search
  • MicroSD Card – Search
  • Raspberry Pi Compatible Wi-Fi Dongle – Search

On Closing

I hope you find this article useful – Multithreading Raspberry Pi Game Controller in Python, please like and share.

One thought on “Multithreading Raspberry Pi Game Controller in Python”

Leave a Reply

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