This program demonstrates a simple motor control application using Python. The main objective of the script is to rotate a motor by a specific number of turns, which is determined by the user input. The motor's position is tracked, and it continues to rotate until the desired number of turns is achieved.
SMDThe SMD acts as a bridge between the script and the modules. It is responsible for interpreting the commands sent by the script and translating them into actions that read input from the Button Module and actuate the BDC motor, the RGB LED Module and the Buzzer Module.
BDC Motor
The motor is controlled using velocity commands, allowing for smooth acceleration and deceleration.
Project Key Features
Establishes a connection with the SMD Red motor using the Master and Red classes from the smd.red library.
Allows users to specify the number of turns for the motor, using an encoder with a predefined steps-per-turn value.
Continuously monitors the motor’s position and stops it once the desired rotation is achieved.
Sets the motor velocity dynamically, starting with maximum speed and stopping precisely at the target position.
Designed to work efficiently within multi-threaded applications for real-time motor control.
Connect the 100 RPM BDC Motor with Encoder to the motor ports of the SMD using an RJ-45 cable.
Make sure that the SMD is powered and all connections are correct.
Project Wiring diagram
Step 3: Run & Test
Run the Script
Execute the script to initiate the Motor Rotation Based on Turn Input Value project.
Enter different turn values in the control interface to observe the motor behavior.
Input a positive value to rotate the motor clockwise (CW).
Input a negative value to rotate the motor counterclockwise (CCW).
Input zero (0) to stop the motor.
Observe how the motor speed dynamically adjusts based on the magnitude of the input value.
Customize and Experiment
• Modify input values in the script to control the speed and rotation direction.
• Experiment with different PWM signal ranges to fine-tune motor performance.
• Implement acceleration profiles to create smoother speed transitions.
• If using an encoder, integrate it for closed-loop control and precise motor positioning.
Example Usage:
When the program is executed, it will ask the user to input the number of turns:
Enter the number of turns: 5
After the user inputs the value (e.g., 5), the motor will rotate the equivalent number of turns. The program will print a message once the motor has completed the rotation:
It has been rotated as many times as the number of turns entered. Number of turns: 5
Codes
from serial.tools.list_ports import comports
from platform import system
from smd.red import *
import time
# Serial Communication Settings
baudrate = 115200 # Baud rate for communication
motor_id = 0 # Motor module ID
steps_per_turn = 6533 # Encoder counts per revolution
def detect_usb_port():
"""
Detects and returns the correct USB port for communication.
Returns:
str: The detected USB port or None if no suitable port is found.
"""
ports = list(comports())
usb_names = {
"Windows": ["USB Serial Port"], # Windows-specific port names
"Linux": ["/dev/ttyUSB"], # Linux-specific port names
"Darwin": [ # macOS-specific port names
"/dev/tty.usbserial",
"/dev/tty.usbmodem",
"/dev/tty.SLAB_USBtoUART",
"/dev/tty.wchusbserial",
"/dev/cu.usbserial",
]
}
os_name = system() # Detect the operating system
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 # Return the first matching port
print("No suitable USB device found.")
return None
# Initialize USB port and SMD module
serial_port = detect_usb_port()
if not serial_port:
print("No compatible USB port found. Check your connection.")
exit(1)
print(f"Using serial port: {serial_port}")
# Initialize SMD Master module and attach the motor
master = Master(serial_port, baudrate)
master.attach(Red(motor_id))
# Configure motor settings
master.set_operation_mode(motor_id, 2) # Set motor to Velocity Control Mode
master.enable_torque(motor_id, True) # Enable motor torque
master.set_shaft_rpm(motor_id, 100) # Set motor RPM
master.set_shaft_cpr(motor_id, steps_per_turn) # Set encoder CPR value
def rotate_motor(turns):
"""
Rotates the motor by the specified number of turns.
Args:
turns (int): Number of turns the motor should rotate.
"""
target_position = turns * steps_per_turn # Calculate target encoder position
current_position = master.get_position(motor_id) # Get current motor position
if current_position is None:
print("Failed to get motor position. Check motor connection.")
return
print("Motor is rotating...")
master.set_velocity(motor_id, 10000) # Set motor to maximum speed
# Wait until the motor reaches the target position
while abs(master.get_position(motor_id) - current_position) < target_position:
time.sleep(0.01) # Short delay for position update
master.set_velocity(motor_id, 0) # Stop the motor
print("Motor rotation completed.")
# Get user input for the number of turns and rotate the motor
turns = int(input("Enter the number of turns: "))
rotate_motor(turns)
#include <Acrome-SMD.h>
// Define motor parameters
#define MOTOR_ID 0 // Motor module ID
#define BAUDRATE 115200 // Serial communication baud rate
#define STEPS_PER_TURN 6533 // Encoder counts per revolution
// Initialize SMD Master and Motor
Master master(&Serial, BAUDRATE);
Red motor(MOTOR_ID);
void setup() {
Serial.begin(BAUDRATE);
Serial.println("SMD Red Motor Control Initialized.");
// Attach motor to master
master.attach(motor);
// Configure motor settings
motor.setOperationMode(2); // Set to Velocity Control Mode
motor.enableTorque(true); // Enable motor torque
motor.setShaftRpm(100); // Set motor RPM
motor.setShaftCpr(STEPS_PER_TURN); // Set encoder counts per revolution
}
void rotateMotor(int turns) {
long targetPosition = turns * STEPS_PER_TURN; // Calculate target position
long currentPosition = motor.getPosition(); // Get current position
if (currentPosition == -1) {
Serial.println("Error: Unable to get motor position.");
return;
}
Serial.print("Rotating motor for ");
Serial.print(turns);
Serial.println(" turns.");
motor.setVelocity(10000); // Set motor velocity
// Wait until the motor reaches the target position
while (abs(motor.getPosition() - currentPosition) < abs(targetPosition)) {
delay(10); // Small delay for position update
}
motor.setVelocity(0); // Stop the motor
Serial.println("Motor rotation completed.");
}
void loop() {
if (Serial.available() > 0) {
String input = Serial.readStringUntil('\n'); // Read input from Serial
int turns = input.toInt(); // Convert input to integer
if (turns != 0) {
rotateMotor(turns);
} else {
Serial.println("Invalid input. Enter a nonzero integer.");
}
}
}