> For the complete documentation index, see [llms.txt](https://docs.acrome.net/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.acrome.net/smd-kits/starter-kit/what-you-can-build/motor-rotation-based-on-turn-input-value.md).

# Motor Rotation Based on Turn Input Value

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.

## **Key Components:**

1. **USB Connection and Serial Communication**:
   1. The program first detects the available USB serial port by checking the connected devices. This is done using the `serial` module and the `comports()` method. The program checks for the USB Serial Port on Windows, `/dev/ttyUSB` on Linux, and `/dev/tty.usbserial` or `/dev/tty.usbmodem` on macOS, depending on the operating system.
2. **Motor Control with SMD Red**:
   1. The motor control is handled by the `smd.red` library, which provides an interface to communicate with the motor using the Red controller. The `Master` and `Red` objects are used to establish communication with the motor and send commands to it.
3. **Motor Rotation Logic**:
   1. The motor rotation is based on the encoder counts per revolution (CPR). The variable `steps_per_turn` represents the CPR, which is typically a value like `6533` for many motors.
   2. The function `rotate_motor(turns)` takes the number of turns as input, calculates the corresponding target position (in encoder steps), and then continuously rotates the motor until the target position is reached.
   3. The `m.set_velocity()` function is used to set the speed of the motor, and the motor stops once the desired position is achieved.
4. **User Input**:
   1. The program prompts the user to input the number of turns they wish the motor to rotate. The `rotate_motor()` function then handles the rotation based on this input.
5. **Threading and Time Control**:
   1. The program uses a simple `while` loop with `time.sleep(0.01)` to periodically check the motor’s position. This ensures the motor rotates in a controlled manner, and the loop continues until the target position is reached.

## 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
```

## Code

```python
import serial
from smd.red import Master, Red
from threading import Thread
import time
from serial.tools.list_ports import comports
from platform import system

def USB_Port():
	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()
	if ports:
		for port, desc, hwid in sorted(ports):
			if any(name in port or name in desc for name in usb_names.get(os_name, [])):
				return port
		print("Current ports:")
		for port, desc, hwid in ports:
			print(f"Port: {port}, Description: {desc}, Hardware ID: {hwid}")
	else:
		print("No port found")
	return None
	
port = USB_Port()
m = Master(port)
motor = m.attach(Red(0))

def rotate_motor(turns):
    steps_per_turn = 6533  # Set according to the encoder CPR value
    target_position = turns * steps_per_turn  # Calculate the target position
    current_position = m.get_position(0)  # get motor position

    # Rotate the motor until the target position is reached.
    m.set_velocity(id=0, sp=10000)  # Set to maximum speed
    while abs(m.get_position(0) - current_position) < target_position:
        time.sleep(0.01)  # Wait for a short time
    
    m.set_velocity(id=0, sp=0)  # Stop the motor
    
turns = input("Enter the number of turns: ")
rotate_motor(int(turns))
print("It has been rotated as many times as the number of turns entered. Number of turns:"+turns)
```
