Basic Motor Torque Control Application
Last updated
from smd.red import * # Import the SMD Red Python library
from serial.tools.list_ports import comports # Used to detect available serial (COM) ports
from platform import system # Used to identify the current operating system
import time # For time delays
# Function to automatically detect the correct USB port where SMD Red is connected
def USB_Port():
ports = list(comports()) # Get list of all serial ports
usb_names = {
"Windows": ["USB Serial Port"],
"Linux": ["/dev/ttyUSB"],
"Darwin": ["/dev/cu."] # macOS serial devices typically start with /dev/cu.
}
os_name = system()
for port, desc, _ in ports:
# Return the first matching port based on platform-specific device names
if any(name in port or name in desc for name in usb_names.get(os_name, [])):
return port
return None # If no matching port is found, return None
# Main function that sets up and runs the torque control loop
def main():
port = USB_Port()
if not port:
print("No port found.") # Exit if no SMD Red is detected
return
master = Master(port) # Create a Master object to communicate with the SMD Red
motor_id = 1 # Set the motor ID (default is 1)
# Attach the SMD Red module and configure it
master.attach(Red(motor_id)) # Attach the motor
master.set_shaft_cpr(motor_id, 6533) # Set encoder resolution (not used in torque mode, but good practice)
master.set_shaft_rpm(motor_id, 100) # Set motor's nominal speed (not critical for torque mode)
# Set torque control parameters (PID: P=3.0, I=0.1, D=0.0)
master.set_control_parameters_torque(motor_id, 3.0, 0.1, 0.0)
# Enable Torque mode
master.set_operation_mode(motor_id, OperationMode.Torque)
# Enable the motor torque output
master.enable_torque(motor_id, True)
# Loop to continuously read user input and set torque
while True:
try:
# Read torque input from user
current = float(input("Enter desired torque current (-100 to 100): "))
# Send torque value to the motor
master.set_torque(motor_id, current)
# Read and print actual measured current from the motor
measured = master.get_torque(motor_id)
print(f"Set: {current:.2f}, Measured: {measured:.2f}\n")
time.sleep(0.2) # Small delay for stability
except KeyboardInterrupt:
# On Ctrl+C, safely disable torque and exit the loop
master.enable_torque(motor_id, False)
break
# Entry point of the script
if __name__ == "__main__":
main()#include <Acrome-SMD.h>
#define BAUDRATE 115200 // Serial communication speed
#define ID 1 // ID of the SMD Red module
Red master(ID, Serial, BAUDRATE); // Create SMD Red object
int currentLimit = 100; // Max allowed current
bool torqueEnabled = true; // Motor torque status
void setup() {
Serial.begin(115200); // Start serial monitor
master.begin(); // Initialize communication with SMD Red
master.setOperationMode(TorqueControl); // Set operation mode to Torque Control
master.torqueEnable(1); // Enable motor torque
}
void loop() {
// Read joystick X and Y values from module 1
int joystickX = master.getJoystickX(1);
int joystickY = master.getJoystickY(1);
// Adjust current limit based on joystick direction
if (joystickX > 50 || joystickY > 50) {
currentLimit++;
} else if (joystickX < -50 || joystickY < -50) {
currentLimit--;
}
// Send torque setpoint to motor
master.setpoint(3, currentLimit - 50); // Adjust for offset
int current = master.getTorque(); // Read current draw from motor
// Debug output
Serial.print("Motor Current: "); Serial.println(current);
Serial.print("Current Limit: "); Serial.println(currentLimit);
// Safety: Disable motor if current exceeds limit
if (current >= currentLimit) {
master.torqueEnable(0); // Disable torque
torqueEnabled = false;
Serial.println("Motor disabled due to overcurrent!");
}
delay(100); // Small delay for stability
}