yahboom
HomeLearn
Solution
Blog
Online Store
About Us
EN/中文
Game Handle📖
1.Introduction to the Handle
  • Introduction to the Handle
2.Python Driver Tutorial
  • Python Driver Tutorial
3.ROS Driver Tutorial
  • ROS1 Handle Driver
  • ROS2 Handle Driver
4.Car Control Tutorial
  • ROSMASTER M3 Pro Car Control Tutorial
  • ROSMASTER X3PLUS Car Control Tutorial
5.ROS Car Upgrade Controller Adaptation Tutorial
  • ROS Car Upgrade Controller Adaptation Tutorial
Download
  • Code
  • VM_File
  • Instruction Manual
  • WindowsSoftware
Download ZIP

Welcome to Game Handle repository

Python Driver Tutorial

Python Test Handle

I. Experimental Environment

  • Jupyter Lab

  • Python Environment

Ii. Test Method

Note

This tutorial uses a 2.4G test environment as an example!

The controller supports rapid-fire functionality. If you experience jitter when pressing a button, please disable the rapid-fire function for the corresponding button according to the instruction manual.

Before testing, ensure the controller receiver is connected to the motherboard or PC, and switch the controller to DINPUT. ( Press and hold FN+SELECT for 3 seconds ) A solid blue indicator light indicates successful pairing of the controller.

Environment Setup

The provided virtual machine has already set up the test environment; no further setup is required. Please skip directly to starting Jupyter Lab.

sudo apt update

Install required dependencies

xxxxxxxxxx
sudo apt install -y python3-pip python3-dev python3-setuptools libsdl2-dev libsdl2-image-dev libsdl2-mixer-dev libsdl2-ttf-dev libportmidi-dev libswscale-dev libavformat-dev libavcodec-dev zlib1g-dev gcc build-essential libffi-dev jupyter-core
xxxxxxxxxx
pip install cffi pygame jupyter notebook jupyterlab ipywidgets

Start Jupyter Lab

Open the terminal and enter Jupyter lab.

xxxxxxxxxx
jupyter lab

image-20251212103312137

It can be opened by using the IP address or port number

http://localhost:8888/

Before testing, make sure the handle receiver is connected to the motherboard or PC and successfully paired. Enter the following command to check if the handle device can be detected.

image-20251209100243262

As shown in the image above, this indicates that the gamepad receiver has been successfully recognized. Note that if a mouse or keyboard is connected, it may also be recognized as a js device, but the program only recognizes js0. Therefore, if multiple js devices are connected, connect the gamepad receiver first, then connect the other devices. When the gamepad is connected, the indicator light will be solid blue; flashing indicates a disconnection.

ipywidgets Test

image-20251210200434014

pygame Test

After pressing a key, it will print which key was pressed

​x
import pygame
import time
import platform  

# Initialize Pygame
pygame.init()
pygame.joystick.init()

# Get number of connected gamepads
joystick_count = pygame.joystick.get_count()
print(f"Detected {joystick_count} gamepad(s)")

if joystick_count == 0:
    print("No gamepads detected. Please connect a gamepad and try again.")
    exit()

# Initialize all detected gamepads
joysticks = []
for i in range(joystick_count):
    joystick = pygame.joystick.Joystick(i)
    joystick.init()
    joysticks.append(joystick)
    
    print(f"\nGamepad {i}: {joystick.get_name()}")
    print(f"  Number of axes: {joystick.get_numaxes()}")
    print(f"  Number of D-pads (hats): {joystick.get_numhats()}")

# Detect operating system for platform-specific mappings
system = platform.system()
print(f"Platform: {system}")

if system == "Windows":
    # Button/axis mappings for Windows
    button_names = {
        0: "A", 1: "B", 3: "X", 4: "Y",
        6: "LB", 7: "RB", 8: "LT", 9: "RT",
        10: "SELECT", 11: "START", 12: "Left Stick Click", 13: "Right Stick Click"
    }
    axis_names = [
        "Left Stick X", "",  # Unused axis 1
        "Left Stick Y", "Right Stick X",   
        "", "Right Stick Y"  # Unused axis 4
    ]
elif system == "Linux":
    # Button/axis mappings for Linux
    button_names = {
        0: "A", 1: "B", 3: "X", 4: "Y",
        6: "LB", 7: "RB", 8: "LT", 9: "RT",
        10: "SELECT", 11: "START", 12: "Left Stick Click", 13: "Right Stick Click"
    }
    axis_names = [
        "Left Stick X", "Left Stick Y", "Right Stick X", "Right Stick Y", "RT", "LT"
    ]
else:
    # Default mappings for other systems (compatibility fallback)
    button_names = {}
    axis_names = []

# Only print axis data with absolute value above this threshold (dead zone)
AXIS_THRESHOLD = 0.1

try:
    while True:
        # Process all Pygame events
        for event in pygame.event.get():
            # Button press event
            if event.type == pygame.JOYBUTTONDOWN:
                btn_name = button_names.get(event.button, f"Unknown Button({event.button})")
                print(f"Gamepad {event.joy}: Button {btn_name} pressed")
            
            # Button release event
            elif event.type == pygame.JOYBUTTONUP:
                btn_name = button_names.get(event.button, f"Unknown Button({event.button})")
                print(f"Gamepad {event.joy}: Button {btn_name} released")
            
            # Joystick axis movement event
            elif event.type == pygame.JOYAXISMOTION:
                if abs(event.value) > AXIS_THRESHOLD:
                    axis_name = axis_names[event.axis] if event.axis < len(axis_names) else f"Axis {event.axis}"
                    # Suppress unused axes (1/4) only on Windows; show all axes on Linux
                    if system == "Windows":
                        if event.axis != 1 and event.axis != 4:
                            print(f"Gamepad {event.joy}: {axis_name} = {event.value:.2f}")
                    else:  # Linux systems
                        print(f"Gamepad {event.joy}: {axis_name} = {event.value:.2f}")
            
            # D-pad (hat) movement event
            elif event.type == pygame.JOYHATMOTION:
                if event.value != (0, 0):  # Only show non-neutral positions
                    hat_dir = {
                        (1, 0): "Right", (-1, 0): "Left",
                        (0, 1): "Up", (0, -1): "Down",
                    }.get(event.value, event.value)
                    print(f"Gamepad {event.joy}: D-pad = {hat_dir}")
        
        time.sleep(0.01)  # Reduce CPU usage

except KeyboardInterrupt:
    print("\n\nProgram terminated")
    pygame.quit()

Iii. Gamepad Key Value Definition

【Buttons】Represent physical buttons

Buttons IndexGamepad Button
buttons[0]A
buttons[1]B
buttons[2]-
buttons[3]X
buttons[4]Y
buttons[5]-
buttons[6]L1|LB
buttons[7]R1|RB
buttons[8]L2|LT
buttons[9]R2|RT
buttons[10]SELECT
buttons[11]START
buttons[12]Left Stick Press
buttons[13]Right Stick Press

【Axes】Represent joysticks and linear triggers

Axes IndexGamepad ControlDescription
axes[0]Left Joystick (Horizontal)Positive = Left, Negative = Right
axes[1]Left Joystick (Vertical)Positive = Up, Negative = Down
axes[2]Right Joystick (Horizontal)Positive = Left, Negative = Right
axes[3]Right Joystick (Vertical)Positive = Up, Negative = Down
axes[4]Linear Trigger R2|RTReleased: -1, Pressed: 1
axes[5]Linear Trigger L2|LTReleased: -1, Pressed: 1
axes[6]D-pad (Horizontal)Positive = Left, Negative = Right
axes[7]D-pad (Vertical)Positive = Up, Negative = Down
Introduction to the Handle
ROS1 Handle Driver

COMPANY

  • About us
  • Team Style
  • Blog

LEARNING & EXPLORATION

  • Tutorials
  • Edge AI hardware
  • Educational robots
  • Embedded intelligent hardware

WHERE TO BUY

  • Yahboom Online Store
  • Amazon
  • Alibaba
  • AliExpress
  • Mercado

TECHNOLOGY SUPPORT

  • Email: support@yahboom.com

BE A DISTRIBUTOR

  • Email: sales@yahboom.com
QR Code
QR Code

Copyright © 2017-2026 Yahboom. All Rights Reserved.

EN/中文