
smiller29
Hello @Athena,
I am currently exploring the feasibility of using a Windows 11-compatible controller to execute a Python client script that transmits XInput data to a Python server script on the ARC Skill Control Board. My objective is to manage an H-Bridge with PWM speed control to facilitate tank track movement using the Synthiam ARC platform. Do you think this setup can be achieved?
I am employing the Anbernic Win600 controller, as depicted in the image below:
At present, I am endeavoring to deploy a Python-coded server on my ARC-enabled PC to process control signals. I’ve included the Python script I’m using for this configuration below.
#!/usr/bin/env python3
# Async TCP receiver that prints controller events and maintains a latest_state snapshot.
import asyncio, json, signal, sys
from collections import defaultdict
HOST = "0.0.0.0"
PORT = 5555
PRINT_EVENTS = True
latest_state = {
"buttons": defaultdict(lambda: False),
"axes": defaultdict(lambda: 0.0),
"hat": {"x": 0, "y": 0},
"t": 0.0,
}
def apply_event(ev):
et = ev.get("type")
latest_state["t"] = ev.get("t", latest_state["t"])
if et == "button":
name = ev.get("name", f"BTN{ev.get('index', -1)}")
pressed = bool(ev.get("pressed", False))
latest_state["buttons"][name] = pressed
if PRINT_EVENTS:
print(f"[BTN] {name}: {'DOWN' if pressed else 'UP'}")
elif et == "axis":
name = ev.get("name", f"AXIS{ev.get('index', -1)}")
val = float(ev.get("value", 0.0))
latest_state["axes"][name] = val
if PRINT_EVENTS:
print(f"[AXIS] {name}: {val:+.3f}")
elif et == "hat":
v = ev.get("value", {"x": 0, "y": 0})
latest_state["hat"] = {"x": int(v.get("x", 0)), "y": int(v.get("y", 0))}
if PRINT_EVENTS:
x, y = latest_state["hat"]["x"], latest_state["hat"]["y"]
dirs = []
if y == 1: dirs.append("Up")
if y == -1: dirs.append("Down")
if x == -1: dirs.append("Left")
if x == 1: dirs.append("Right")
print(f"[HAT] DPad: {'+'.join(dirs) if dirs else 'Neutral'}")
async def handle_client(reader: asyncio.StreamReader, writer: asyncio.StreamWriter):
peer = writer.get_extra_info("peername")
print(f"[server] Client connected: {peer}")
try:
while True:
line = await reader.readline()
if not line:
break
try:
ev = json.loads(line.decode("utf-8"))
except json.JSONDecodeError:
continue
apply_event(ev)
except asyncio.CancelledError:
pass
finally:
print(f"[server] Client disconnected: {peer}")
try:
writer.close()
await writer.wait_closed()
except Exception:
pass
async def status_printer():
while True:
await asyncio.sleep(0.5)
lx = latest_state["axes"]["LX"]; ly = latest_state["axes"]["LY"]
rx = latest_state["axes"]["RX"]; ry = latest_state["axes"]["RY"]
lt = latest_state["axes"]["LT"]; rt = latest_state["axes"]["RT"]
a = latest_state["buttons"]["A"]; b = latest_state["buttons"]["B"]
d = latest_state["hat"]
print(f"[state] LX:{lx:+.2f} LY:{ly:+.2f} RX:{rx:+.2f} RY:{ry:+.2f} LT:{lt:.2f} RT:{rt:.2f} A:{int(a)} B:{int(b)} D:{d}")
async def main():
server = await asyncio.start_server(handle_client, HOST, PORT)
print(f"[server] Listening on {HOST}:{PORT}")
sp = asyncio.create_task(status_printer())
# Graceful shutdown for Windows
stop = asyncio.Future()
def _sig():
if not stop.done():
stop.set_result(True)
loop = asyncio.get_running_loop()
try:
loop.add_signal_handler(signal.SIGINT, _sig) # may raise on Windows for some signals
loop.add_signal_handler(signal.SIGTERM, _sig)
except (NotImplementedError, AttributeError):
# Fallback: rely on KeyboardInterrupt
pass
async with server:
await asyncio.gather(server.serve_forever(), stop)
sp.cancel()
if __name__ == "__main__":
try:
asyncio.run(main())
except KeyboardInterrupt:
sys.exit(0)
I am eager to understand how to integrate this Python script to efficiently utilize the XInput data along with the ARC platform's capabilities for controlling tank tracks via the H-Bridge with PWM speed control. The H-Bridge interfaces with an Arduino Nano running the EZB firmware. Any insights or guidance on effectively achieving this setup would be greatly appreciated. Additionally, I aim to program other buttons for various ARC skills or script triggers.
Below is an overview of how you can integrate your Windows 11 controller (via your Python scripts) with Synthiam ARC to control your tank tracks using an H-Bridge (via PWM control) on your Arduino Nano running EZB Firmware.
Overview of the Approach
Controller to Python Server Communication
Your Python server script (running on your ARC-enabled PC) listens on a TCP port (in your case, port 5555) for XInput events from your Windows 11 controller.
When a controller button is pressed or an analog axis moves, your server receives the event, updates an internal state (such as duty cycle values or directional flags), and prints/logs the information.
Python Server to ARC Integration
Once the controller events are processed, you want to forward these events (or trigger actions) inside ARC.
There are two common ways to do this:
Option A: Update ARC Global Variables and Call ARC Commands in a Python Script Running Within ARC
You can create an ARC Python script (or a robot skill that supports Python) that monitors variables (like
$LeftMotorPWM
and$RightMotorPWM
) and then calls the built-inPWM.set()
function to adjust the tank motors.Option B: Write an ARC robot skill with a Built-in TCP Client
Implement a TCP client within an ARC Python script that directly connects to your Python server. Once connected, when you receive the controller events, you immediately trigger ARC commands (for example,
PWM.set(d0, dutyCycle)
) to update motor speeds.Mapping Controller Events to H-Bridge Motor Control
Depending on your tank drive setup, you’ll likely have two PWM channels (one for each track).
For example, you might assign:
In your ARC Python script, you could map the analog joystick values (or the trigger values) to duty cycles (0-100) and then call:
ARC’s built-in
sleep()
(which uses milliseconds) and global variable functions (getVar()
/setVar()
) can help you manage timing and share state between scripts.Step-by-Step Integration
Testing Your Controller Input
First, verify that your Anbernic Win600 controller is correctly detected and that your Python server script (provided in your example) is receiving the XInput events.
You can use the printed output (for example, verifying the values for
LX
,LY
, triggers, and DPad events) to ensure the mapping is as you expect.Mapping Input to PWM Duty Cycle
Once you have confirmed the controller input is received, decide how you wish to map the analog inputs (e.g., left joystick X and Y, triggers) to the motor speeds.
For instance, a simple mapping might mean:
You can adjust the mapping depending on whether you want differential steering (one motor increasing speed and the other decreasing).
Integrating With ARC Python Scripting
ARC allows you to run Python scripts that can call functions like
PWM.set()
and update global variables withsetVar()
/getVar()
.For example, create an ARC Python script (inside a Script Skill) with code similar to:
Modify the above code to fit your mapping strategy. The basic idea is to update ARC with PWM commands based on the incoming controller data.
Mapping Additional Buttons
For extra functions (such as triggering other ARC skills or script events based on button presses), you can similarly use ARC’s commands.
For example, if button A is pressed, you might call a command via:
Define a mapping from your controller button names (as processed in your Python server) to global variables inside ARC, and then have your ARC Python script or Script Skill poll and react.
Running the Integrated Setup
Ensure that both the external Python server and your ARC Python integration are running on the same PC (or have a reliable network connection if on separate systems).
Test the entire flow:
PWM.set()
commands to control your motors properly.Additional Considerations
Direct ARC XInput Skill:
Before building a completely custom solution, consider that ARC already includes a Joystick (XInput) Skill. This native skill may handle mapping of analog values and button presses, and you might be able to modify or extend it (or merely use some of its functionality) to suit your tank track control needs.
Creating Custom Robot Skills:
If you need features not offered in default ARC skills, you can create your own robot skill following the guide here:
Create robot skill Overview
Documentation and Resources:
Synthiam ARC Downloads
PWM Python API Documentation
Python API Overview
Final Thoughts and Questions
Yes, it is feasible to use your Windows 11 controller with your Python server to handle XInput and then integrate with Synthiam ARC for controlling the tank tracks via PWM to an H-Bridge. The key points are:
Do you have any questions on any specific part of this setup? For example, would you like more detailed guidance on the TCP/client integration with ARC Python, or further help on mapping the controller's analog values to PWM duty cycle percentages? Feel free to ask!
I am a customer support GPT-powered AI and still learning. If you have doubts about my response, please use the support documentation to verify my answer.