> 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-applications/basics/distance-auto-stop.md).

# Distance Auto Stop

This project showcases a dynamic motor control system utilizing the [ACROME SMD](/electronics/smd-red.md) 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.

**About Tools and Materials:**

[SMD Red](https://docs.acrome.net/electronics/smd-red) ([Purchase Here](https://www.robotshop.com/products/acrome-smd-red-smart-brushed-motor-driver-with-speed-position-and-current-control-modes))

[SMD USB Gateway](https://docs.acrome.net/electronics/gateway-modules/usb-gateway-module) ([Purchase Here](https://www.robotshop.com/products/acrome-usb-gateway-module-acrome-smd-products))

[Arduino Gateway Module](/electronics/gateway-modules/arduino-gateway-module.md) ([Purchase Here](https://www.robotshop.com/products/acrome-arduino-gateway-shield-module-acrome-smd-products))

[BDC Motor](/electronics/electrical-motors/brushed-dc-motors-bdc.md) ([Purchase Here](https://www.robotshop.com/products/acrome-12v-brushed-dc-motor-with-built-in-encoder-100-rpm-speed))

[Ultrasonic Distance Sensor Module](/electronics/add-on-modules/ultrasonic-distance-sensor-module.md) ([Purchase Here](https://www.robotshop.com/products/acrome-ultrasonic-distance-sensor-add-on-module-acrome-smd-products))

### **Step 1: Hardware & Software Overview** <a href="#step-1-hardware-and-software-overview" id="step-1-hardware-and-software-overview"></a>

**Project Key Components**

1. [**ACROME SMD Red Platform**](/electronics/smd-red.md)\
   The [ACROME SMD](/electronics/smd-red.md) platform serves as the control hub, interfacing with the motor and reading sensor data.
2. [**Ultrasonic Distance Sensor**](/electronics/add-on-modules/ultrasonic-distance-sensor-module.md)\
   A distance sensor is used to measure the object's position in real-time.
3. [BDC Motor](/electronics/electrical-motors/brushed-dc-motors-bdc.md)\
   The motor is controlled using velocity commands, allowing for smooth acceleration and deceleration.

### **Key Features**

1. **Distance-Based Motor Control**\
   The motor dynamically adjusts its speed based on proximity.
2. **Smooth Interpolation**\
   The velocity decreases gradually instead of abrupt stops, ensuring smoother operation.
3. **Real-Time Feedback**\
   The system logs current distance and velocity values for monitoring.

## **Step 2: Assemble**

**Getting Started**

1. **Hardware Setup**
   * Connect the [SMD Red ](/electronics/smd-red.md)to the PC or Arduino board using [USB Gateway Module](/electronics/gateway-modules/usb-gateway-module.md) or [Arduino Gateway Module](/electronics/gateway-modules/arduino-gateway-module.md).
   * Connect the [Ultrasonic Distance Sensor ](/electronics/add-on-modules/ultrasonic-distance-sensor-module.md)to the SMD using an RJ-45 cable.
   * Make sure that the SMD is powered and all connections are correct.

#### **Project Wiring Diagram**

<figure><img src="/files/QECW7JdGd4JmBmuTXzMo" alt=""><figcaption></figcaption></figure>

## Step 3: Run & Test

1. **Run the Script**
   * Run the script on your computer. This will establish communication with the SMD and initiate control of the [Ultrasonic Distance Sensor](/electronics/add-on-modules/ultrasonic-distance-sensor-module.md).

## Codes

{% tabs %}
{% tab title="Python Code" %}
{% code lineNumbers="true" %}

```python
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}")
```

{% endcode %}
{% endtab %}

{% tab title="Arduino Code" %}
{% code lineNumbers="true" %}

```cpp
#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);
}
```

{% endcode %}
{% endtab %}
{% endtabs %}

### **Conclusion**

This project highlights the [ACROME SMD Red](/electronics/smd-red.md) 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.
