This project showcases a dynamic motor control system utilizing the ACROME SMD platform. The project integrates hardware, real-time processing, and dynamic scaling to achieve precision control. The goal is to create a motorized system where the speed decreases as the motor approaches an object and stops completely when it gets very close. This is achieved using distance measurements and velocity interpolation.
Make sure that the SMD is powered and all connections are correct.
Project Wiring Diagram
Step 3: Run & Test
Run the Script
Run the script on your computer. This will establish communication with the SMD and initiate control of the Ultrasonic Distance Sensor.
from smd.red import *
from serial.tools.list_ports import comports
from platform import system
# Serial Communication Settings
baudrate = 115200 # Baud rate for communication
module_id = 0 # ID of the SMD module
distance_sensor_id = 1 # ID of the distance sensor module
motor_id = 0 # ID of the motor module
# Distance Thresholds and Motor Speed Settings
middle_distance = 20 # Medium distance threshold (cm)
near_distance = 5 # Close distance threshold (cm)
max_speed = 100 # Maximum motor speed
def detect_usb_port():
"""
Scans and identifies a compatible USB port for the current operating system.
Returns:
str: The detected USB port or None if no suitable port is found.
"""
ports = list(comports())
usb_names = {
"Windows": ["USB Serial Port"],
"Linux": ["/dev/ttyUSB"],
"Darwin": [
"/dev/tty.usbserial",
"/dev/tty.usbmodem",
"/dev/tty.SLAB_USBtoUART",
"/dev/tty.wchusbserial",
"/dev/cu.usbserial",
"/dev/cu.usbmodem",
"/dev/cu.SLAB_USBtoUART",
"/dev/cu.wchusbserial",
]
}
os_name = system()
print(f"Operating System: {os_name}")
if ports:
for port in ports:
if any(name in port.device or name in port.description for name in usb_names.get(os_name, [])):
print(f"USB device detected on port: {port.device}")
return port.device
print("No suitable USB device found. Available ports:")
for port in ports:
print(f"Port: {port.device}, Description: {port.description}, HWID: {port.hwid}")
else:
print("No ports detected!")
return None
# Initialize the USB port and SMD module
SerialPort = detect_usb_port()
if SerialPort is None:
print("No suitable USB port found.")
exit(1)
master = Master(SerialPort, baudrate)
master.attach(Red(module_id))
# Motor Configuration
master.set_shaft_cpr(motor_id, 6533) # Set encoder counts per revolution
master.set_shaft_rpm(motor_id, 100) # Set maximum RPM
master.enable_torque(motor_id, 1) # Enable motor torque
# Function for Speed Interpolation
def interpolate_speed(distance):
"""
Calculates the motor speed based on distance using linear interpolation.
Args:
distance (float): The measured distance from the sensor.
Returns:
float: The calculated speed.
"""
if distance < near_distance:
return 0 # Stop the motor
elif near_distance <= distance < middle_distance:
return max(10, max_speed * (distance - near_distance) / (middle_distance - near_distance)) # Smooth acceleration
else:
return max_speed # Full speed
# Main Control Loop
while True:
distance = master.get_distance(module_id, distance_sensor_id)
if distance is not None:
speed = interpolate_speed(distance)
master.set_duty_cycle(motor_id, speed)
if speed == 0:
print("Motor Stopped")
elif speed == max_speed:
print("Motor Running at Max Speed")
else:
print(f"Motor Running at Speed: {speed}")
#include <Acrome-SMD.h>
#define ID 0
#define CPR 6533
#define BAUDRATE 115200
Red master(ID, Serial, BAUDRATE);
void setup() {
master.begin();
master.torqueEnable(1);
Serial.begin(115200);
}
void loop() {
int distance = master.getDistance(1);
Serial.print("Distance: ");
Serial.println(distance);
// Define velocity scaling parameters
int maxVelocity = 1000; // Maximum velocity
int minVelocity = 0; // Minimum velocity
int stopDistance = 20; // Distance at which motor should start slowing down
int fullStopDistance = 5; // Distance at which motor completely stops
// Check if motor needs to slow down or stop
int velocity;
if (distance > stopDistance) {
// Full speed if distance is greater than stop threshold
velocity = maxVelocity;
} else if (distance > fullStopDistance) {
// Gradually reduce velocity as distance decreases
velocity = map(distance, fullStopDistance, stopDistance, 0, maxVelocity);
} else {
// Completely stop the motor when very close
velocity = 0;
}
// Set motor to velocity mode and set velocity
master.setOperationMode(2);
master.setpoint(2, velocity);
// Small delay to prevent overwhelming the system
delay(50);
}
Conclusion
This project highlights the ACROME SMD Red platform's versatility in creating advanced motor control systems. By combining real-time distance sensing with velocity interpolation, it provides a robust solution for a range of applications.