As some of you know, I am an issue at times to myself.
Outside of me thinking I know everything, what would cause the 18-Channel Maestro to shutdown a SBC (BeagleY-AI)?
#!/usr/bin/python3
# Where did this source code come from?
# I am still researching older notes and ideas...
import sys
import usb.core
import usb.util
# Constant definitions mimicking the C++ implementation
VENDOR_ID = 0x1FFB
PRODUCT_IDS = [0x0089, 0x008A, 0x008B, 0x008C]
REQUEST_SET_TARGET = 0x85 # The standard Pololu Maestro native USB request ID
def find_maestro_device():
"""Loops through known product IDs to find the Pololu Maestro device."""
for pid in PRODUCT_IDS:
device = usb.core.find(idVendor=VENDOR_ID, idProduct=pid)
if device is not None:
return device
return None
def set_target_zero(device, position, servo0):
"""Sends the target position to a specific servo channel using a control transfer."""
# bmRequestType = 0x40 (Vendor-defined request, host-to-device direction)
bm_request_type = 0x40
b_request = REQUEST_SET_TARGET
# Value parameter requires position in quarter-microseconds (input * 4)
w_value = int(position * 4)
w_index = int(servo0)
try:
# usb.core.Device.ctrl_transfer(bmRequestType, bRequest, wValue, wIndex, data_or_wLength, timeout)
device.ctrl_transfer(
bm_request_type, b_request, w_value, w_index, data_or_wLength=0, timeout=5000
)
except usb.core.USBError as e:
print(f"USB Transfer failed: {e}", file=sys.stderr)
def set_target_one(device, position, servo1):
"""Sends the target position to a specific servo channel using a control transfer."""
# bmRequestType = 0x40 (Vendor-defined request, host-to-device direction)
bm_request_type = 0x40
b_request = REQUEST_SET_TARGET
# Value parameter requires position in quarter-microseconds (input * 4)
w_value = int(position * 4)
w_index = int(servo1)
try:
# usb.core.Device.ctrl_transfer(bmRequestType, bRequest, wValue, wIndex, data_or_wLength, timeout)
device.ctrl_transfer(
bm_request_type, b_request, w_value, w_index, data_or_wLength=0, timeout=5000
)
except usb.core.USBError as e:
print(f"USB Transfer failed: {e}", file=sys.stderr)
def set_target_two(device, position, servo2):
"""Sends the target position to a specific servo channel using a control transfer."""
# bmRequestType = 0x40 (Vendor-defined request, host-to-device direction)
bm_request_type = 0x40
b_request = REQUEST_SET_TARGET
# Value parameter requires position in quarter-microseconds (input * 4)
w_value = int(position * 4)
w_index = int(servo2)
try:
# usb.core.Device.ctrl_transfer(bmRequestType, bRequest, wValue, wIndex, data_or_wLength, timeout)
device.ctrl_transfer(
bm_request_type, b_request, w_value, w_index, data_or_wLength=0, timeout=5000
)
except usb.core.USBError as e:
print(f"USB Transfer failed: {e}", file=sys.stderr)
servo0 = 0
servo1 = 1
servo2 = 2
def main():
print("Searching for Pololu Maestro device...")
device = find_maestro_device()
if device is None:
print("Error: Maestro device not found. Check physical connections or permissions.")
sys.exit(1)
print("Device found and initialized successfully.")
try:
while True:
user_input = input("Enter position (or 'q' to quit): ").strip()
if user_input.lower() == "q":
break
try:
position = int(user_input)
set_target_zero(device, position, 0)
set_target_zero(device, position, 1)
except ValueError:
print("Invalid input. Please enter an integer number.")
except KeyboardInterrupt:
print("\nExiting program.")
finally:
# PyUSB handles closing the device and recycling handles implicitly on exit,
# but clearing configurations ensures safe detachment.
usb.util.dispose_resources(device)
if __name__ == "__main__":
main()
That is the source code. When I place a positive integer on the bash prompt, everything works and well.
Then, I try to reverse the move to a previously known position via a negative integer and the SBC shuts down.
Seth
