Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
135 changes: 135 additions & 0 deletions PythonExample/AmazingHand_ChangeID.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
import time
from rustypot import Scs0009PyController


# Configuration
SERIAL_PORT = "COM5" # Change to your serial port
BAUDRATE = 1000000
TIMEOUT = 2.0
TARGET_NEW_ID = 2 # Desired new motor ID

# EEPROM Lock values (boolean)
EEPROM_UNLOCKED = False # Unlock EEPROM to allow writes
EEPROM_LOCKED = True # Lock EEPROM to protect settings

SCAN_RANGE = range(1, 11)


def main():
print("=" * 70)
print("Permanent Motor ID Change (EEPROM Lock/Unlock)")
print("=" * 70)
print(f"Target new ID: {TARGET_NEW_ID}\n")

# Initialize controller
print("Step 1: Initializing controller...")
try:
controller = Scs0009PyController(
serial_port=SERIAL_PORT,
baudrate=BAUDRATE,
timeout=TIMEOUT,
)
print("✓ Controller initialized\n")
except Exception as e:
print(f"✗ Failed to initialize: {e}")
return

# Scan for motor
print("Step 2: Scanning for motor...")
current_id = None
for motor_id in SCAN_RANGE:
try:
result = controller.ping(motor_id)
if result:
current_id = motor_id
print(f"✓ Found motor at ID {current_id}\n")
break
except Exception:
pass

if current_id is None:
print("✗ No motor found")
return

if current_id == TARGET_NEW_ID:
print(f"Motor already has ID {TARGET_NEW_ID}")
return

# Change ID with EEPROM lock/unlock
print(f"Step 3: Changing ID from {current_id} to {TARGET_NEW_ID}...")

try:
# Step 1: Disable torque (REQUIRED for EEPROM writes)
print(" a) Disabling torque...")
controller.write_torque_enable(current_id, 0)
print(" ✓ Torque disabled")
time.sleep(0.5)

# Step 2: Unlock EEPROM
print(" b) Unlocking EEPROM...")
controller.write_lock(current_id, EEPROM_UNLOCKED)
print(" ✓ EEPROM unlocked")
time.sleep(0.5)

# Step 3: Write new ID
print(f" c) Writing new ID {TARGET_NEW_ID} to EEPROM...")
controller.write_id(current_id, TARGET_NEW_ID)
print(" ✓ ID written to EEPROM")
time.sleep(1.0) # Wait for EEPROM write to complete

# Step 4: Lock EEPROM to protect settings
print(" d) Locking EEPROM to protect settings...")
controller.write_lock(TARGET_NEW_ID, EEPROM_LOCKED)
print(" ✓ EEPROM locked")
time.sleep(0.5)

# Step 5: Verify the change
print(f" e) Verifying new ID {TARGET_NEW_ID}...")
time.sleep(0.5)
result = controller.ping(TARGET_NEW_ID)

if result:
print(f"\n✓ SUCCESS! Motor ID permanently changed to {TARGET_NEW_ID}\n")

# Re-enable torque
print(" f) Re-enabling torque...")
controller.write_torque_enable(TARGET_NEW_ID, 1)
print(" ✓ Torque enabled")

print("\n" + "=" * 70)
print(f"COMPLETE: Motor ID is now {TARGET_NEW_ID}")
print("EEPROM has been locked - settings are protected.")
print("This ID will persist after power cycling!")
print("=" * 70)

print("\nVERIFICATION: Power cycle the motor to confirm")
print("1. Disconnect power from the motor")
print("2. Wait 5 seconds")
print("3. Reconnect power")
print("4. Run scanner - motor should still be at ID", TARGET_NEW_ID)

else:
print(f"\n✗ Failed to verify new ID {TARGET_NEW_ID}")

except Exception as e:
print(f"\n✗ Error during ID change: {e}")
print("\nTrying to re-lock EEPROM for safety...")
try:
# Try to lock with both possible IDs
try:
controller.write_lock(current_id, EEPROM_LOCKED)
except:
pass
try:
controller.write_lock(TARGET_NEW_ID, EEPROM_LOCKED)
except:
pass
print("EEPROM lock attempted")
except:
pass
import traceback
traceback.print_exc()


if __name__ == "__main__":
main()
7 changes: 5 additions & 2 deletions PythonExample/AmazingHand_Demo.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,11 @@


def main():

c.write_torque_enable(1, 1) #1 = On / 2 = Off / 3 = Free

# Enable torque for all 8 motors
for motor_id in range(1, 9):
c.write_torque_enable(motor_id, 1) #1 = On / 2 = Off / 3 = Free

t0 = time.time()

while True:
Expand Down
3 changes: 2 additions & 1 deletion PythonExample/AmazingHand_FingerTest.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@
def main():


c.write_torque_enable(1, 1)
c.write_torque_enable(ID_1, 1)
c.write_torque_enable(ID_2, 1)
#1 = On / 2 = Off / 3 = Free

while True:
Expand Down
126 changes: 126 additions & 0 deletions PythonExample/AmazingHand_ScanMotor.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
import time
from rustypot import Scs0009PyController


# Configuration
SERIAL_PORT = "COM5" # Change to your serial port
TIMEOUT = 0.5

# Common baudrates for Feetech servos
BAUDRATES = [1000000, 500000, 115200, 57600, 38400, 19200, 9600]

# Scan only a few IDs for faster testing (expand if needed)
QUICK_SCAN_RANGE = range(1, 11) # IDs 1-10
FULL_SCAN_RANGE = range(0, 254) # All possible IDs


def scan_for_motors(controller, scan_range, baudrate):
"""Scan for motors on the bus."""
found_motors = []

for motor_id in scan_range:
try:
result = controller.ping(motor_id)
if result:
found_motors.append(motor_id)
print(f" ✓ Motor found at ID {motor_id}")
except Exception:
pass

return found_motors


def main():
"""Main function to scan for motors."""
print("=" * 70)
print("AmazingHand Motor Scanner")
print("=" * 70)
print(f"\nSerial Port: {SERIAL_PORT}")
print(f"Timeout: {TIMEOUT}s")

print("\nAttempting to detect motors at different baudrates...")
print("This may take a moment...\n")

all_found_motors = {}

for baudrate in BAUDRATES:
print(f"\n{'='*70}")
print(f"Trying baudrate: {baudrate}")
print(f"{'='*70}")

try:
controller = Scs0009PyController(
serial_port=SERIAL_PORT,
baudrate=baudrate,
timeout=TIMEOUT,
)
print(f"Controller initialized at {baudrate} baud")

# Quick scan first (IDs 1-10)
print(f"Quick scan (IDs {QUICK_SCAN_RANGE.start}-{QUICK_SCAN_RANGE.stop-1})...")
found_motors = scan_for_motors(controller, QUICK_SCAN_RANGE, baudrate)

if found_motors:
all_found_motors[baudrate] = found_motors
print(f"\n✓ Found {len(found_motors)} motor(s) at {baudrate} baud: {found_motors}")

# Get more info about the first motor
motor_id = found_motors[0]
try:
# Try to read model number
print(f"\nReading details for motor ID {motor_id}:")
position = controller.read_present_position(motor_id)
print(f" - Present Position: {position:.4f} rad ({position * 180/3.14159:.1f}°)")

voltage = controller.read_present_voltage(motor_id)
print(f" - Present Voltage: {voltage:.2f}V")

temperature = controller.read_present_temperature(motor_id)
print(f" - Temperature: {temperature}°C")

except Exception as e:
print(f" - Could not read detailed info: {e}")
else:
print(f"No motors found in quick scan range")

except Exception as e:
print(f"✗ Error at baudrate {baudrate}: {e}")

# Summary
print("\n" + "=" * 70)
print("SCAN SUMMARY")
print("=" * 70)

if all_found_motors:
print("\nMotors detected:")
for baudrate, motor_ids in all_found_motors.items():
print(f" Baudrate {baudrate}: Motor IDs {motor_ids}")

# Recommend settings
recommended_baudrate = list(all_found_motors.keys())[0]
recommended_ids = all_found_motors[recommended_baudrate]
print(f"\n✓ RECOMMENDED SETTINGS:")
print(f" Serial Port: {SERIAL_PORT}")
print(f" Baudrate: {recommended_baudrate}")
print(f" Detected Motor IDs: {recommended_ids}")
else:
print("\n⚠ No motors detected!")
print("\nTroubleshooting:")
print(" 1. Check that the motor is connected to the controller")
print(" 2. Verify the motor is powered (check power LED)")
print(" 3. Ensure the USB cable is properly connected")
print(" 4. Try connecting only ONE motor at a time")
print(" 5. Check that no other program is using the serial port")

print("=" * 70)


if __name__ == "__main__":
try:
main()
except KeyboardInterrupt:
print("\n\nScan cancelled by user.")
except Exception as e:
print(f"\n\nUnexpected error: {e}")
import traceback
traceback.print_exc()