# ACROME SMD

Welcome to Acrome Smart Motion Devices docs!

SMD (Smart Motion Devices) is a **modular** product platform designed to simplify the develop of robotics and automation systems in terms of **electronics, software and mechanics**.

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

You can **design and build** many different robotic systems using the wide range of SMD products. **Robust and modular** hardware allows repeated use for different needs and scenarios

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

SMD is suitable for users of all levels, from **beginners to professionals**.The SMD platform has libraries for different coding languages. Therefore, you can constantly use the SMD platform as you develop yourself in the field of robotics

<table data-header-hidden><thead><tr><th width="239" valign="top"></th><th width="170" valign="top"></th><th width="356" valign="top"></th></tr></thead><tbody><tr><td valign="top"><strong>Operating System / Environment</strong></td><td valign="top"><strong>Compatible Gateway</strong></td><td valign="top"><strong>Notes</strong></td></tr><tr><td valign="top">Windows 10 / 11</td><td valign="top">USB Gateway</td><td valign="top">Ideal for development with GUI, SDK, Blockly, ROS support limited(via WSL/Docker)</td></tr><tr><td valign="top">macOS 11+</td><td valign="top">USB Gateway</td><td valign="top">Supports serial comm. via USB, Blockly Support, ROS support limited(via Docker)</td></tr><tr><td valign="top">Ubuntu / Debian / Arch</td><td valign="top">USB Gateway</td><td valign="top">Perfect for ROS, scripting, SDK, Blockly Support</td></tr><tr><td valign="top">Raspberry Pi OS / Ubuntu</td><td valign="top">USB Gateway</td><td valign="top">Lightweight, Python &#x26; Blockly ready, Blockly Support, ROS support </td></tr><tr><td valign="top">JetPack (Ubuntu)</td><td valign="top">USB Gateway</td><td valign="top">AI + motion fusion, ROS support, Blockly Support</td></tr><tr><td valign="top">Arduino IDE</td><td valign="top">Arduino Gateway</td><td valign="top">Basic UART, embedded control</td></tr><tr><td valign="top">Arduino / MicroPython</td><td valign="top">Arduino Gateway</td><td valign="top">UART-over-USB, wireless use</td></tr><tr><td valign="top">STM32CubeIDE / PlatformIO</td><td valign="top">Manual UART Wiring</td><td valign="top">Advanced only, manual UART</td></tr><tr><td valign="top">Arduino IDE / PlatformIO</td><td valign="top">Arduino Gateway</td><td valign="top">Fast embedded control</td></tr><tr><td valign="top">Debian Linux</td><td valign="top">USB Gateway</td><td valign="top">Industrial Linux robotics, Blockly Support, ROS support </td></tr></tbody></table>

**Note:** The table above applies to all products in the **SMD family**, including SMD Red, SMD Blue, and SMD Green.

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

Electronic components of the SMD platform are divided into three groups: **Gateway modules, Motor Driver Cards** and **Add-on Modules**.While gateway modules provide connection with the computer or Arduino, the motor driver cards drive different types of motors. Add-on modules connected to motor driver cards collect data from the environment with various sensors and components and give feedback.

<figure><img src="/files/1HKlpNuoGDPpmjFb7EJH" alt=""><figcaption></figcaption></figure>

With USB Gateway and Arduino Gateway, you can connect SMD products to **Raspberry Pi, Jetson, PC** and **Arduino**. SMD motor driver cards drive the motor with the **processor** on it. This alleviates the **processing load** of the connected computer or microcontrollers.

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

SMD cards can be connected to each other in a **daisychain**. While motor driver cards communicate with the **RS485** protocol, add-on modules connected to the driver cards communicate with the **I2C** protocol.

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

SMD mechanical parts consist of **plates, joints, wheels** and **mounts**. By combining these parts, you can quickly implement your projects. When designing mechanical parts, responding to the **user's demands** and **long-term use** were prioritized.

\ <br>

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

**3D designs** of electronic and mechanical parts of the SMD platform can be accessed through this document. With these designs, you will spend minimal effort while designing your robotic system and you can design without purchasing.

## Quick links

{% embed url="<https://acrome.net>" %}

{% embed url="<https://www.robotshop.com/es/collections/acrome?srsltid=AfmBOorqAuu3ddyq-b40rO6oylhyn1bQYpu6xqzrjEyOXtUm_g-VhUJl>" %}

## Get Started

We've put together some helpful guides for you to get setup with our product quickly and easily.

{% embed url="<https://www.instructables.com/member/Acrome+Robotics/>" %}

{% content-ref url="/pages/NfUItuNduzWzSCY8vJle" %}
[Reach Us](/help/reach-us)
{% endcontent-ref %}


# SMD Red

The Brushed DC Motor Driver

The **Acrome** **SMD Red** is engineered to deliver revolutionary solutions in robotics and motion systems involving brushed DC motors. Designed with a modular, plug-and-play approach, SMD Red enables users—from makers to educators—to unleash their creativity and focus entirely on their motion-based projects.

At its core, SMD Red’s strength lies in its compatibility with a wide ecosystem of Acrome Smart Motion Devices (SMD modules), enabling seamless integration for a wide range of robotic and automation applications. Whether you're building a basic mobile platform or developing a more complex, sensor-driven system, SMD Red adapts to your needs with ease and efficiency

## <mark style="color:red;">ACROME SMD Red - BDC Motor Driver</mark>

{% embed url="<https://www.youtube.com/watch?v=uJNtaVi0orM>" %}

## <mark style="color:red;">Key Features</mark>

* **Seamless Integration** – Fully plug-and-play with all Acrome Smart Motion Device (SMD) add-on modules.
* **Scalable Networking** – Supports daisy-chaining via RJ-45 for synchronized multi-device communication.
* **Intelligent PID Autotuner** – Built-in Cohen-Coon-based tuning engine ensures optimal motor control under various load conditions.
* **Modular I/O Architecture** – Smart RJ-11 ports for effortless sensor and actuator integration.
* **Integrated Power Distribution** – On-board regulation with pass-through power terminals for clean system expansion.
* **Cross-Platform Development** – Compatible with Python SDK, Arduino, Blockly UI, and command-line interfaces.

## <mark style="color:red;">Benefits at a Glance</mark>

* **Modular & Synchronized Design** – Architected for scalable, distributed robotics applications.
* **Automated Precision Tuning** – PID autotune delivers fast, adaptive control without manual tweaking.
* **Simplified Cabling** – Dual daisy-chaining (data + power) minimizes wire clutter and setup time.
* **Full-Stack Software Support** – From beginner Blockly users to advanced Python and embedded developers.

## <mark style="color:red;">Intelligent Capabilities</mark>

#### PID Autotune Engine

The integrated autotuning engine calculates optimal P, I, D parameters using the **Cohen-Coon method**, offering:

* Improved control performance under varying loads
* Faster response and higher accuracy
* Automatic tuning within \~30 seconds

#### Synchronization Architecture

Each SMD Red can connect multiple modules via **RJ-11**, while the **RJ-45** bus allows multiple SMD Reds to operate synchronously in networked robotic systems. The RS-485-based protocol ensures high-speed, reliable communication.

#### On-Board Power Distribution

Easily power multiple SMD Reds in a chain with **daisy-chain-compatible power terminals**, reducing wiring complexity and enhancing system stability.

## <mark style="color:red;">Control & Feedback</mark>

**Precision Motor Control with Real-Time Insights**

SMD Red delivers an advanced control architecture that combines fine-grained motor configuration with live system diagnostics — all accessible through intuitive register settings. Whether you're building a robotic arm, a mobile platform, or a smart actuator system, SMD Red empowers you with full authority over motion behavior.

Monitor your motor’s status in real time with read-only feedback registers:

* **Present Position**: Current encoder count (absolute tick value)
* **Present Velocity**: Instantaneous speed (ticks per 100 ms)
* **Present Torque**: Actual current draw in mA (indicates load or resistance)

This real-time visibility is critical for diagnostics, closed-loop feedback, data logging, or adaptive control strategies.

All registers are accessible via the **Acrome Python SDK**, **Arduino libraries**, or **custom serial protocols**. This flexibility makes it easy to build anything from beginner experiments to industrial-grade motion systems.

## <mark style="color:red;">Motor Operation Modes</mark>

Configure how the motor responds using the Operation Mode register:

**0x00 – Position Control**\
Drives the motor to a precise target position.\
Ideal for robotic joints, linear axes, and precision mechanisms.

**0x01 – Velocity Control**\
Maintains a constant rotational speed.\
Suitable for wheels, conveyors, and continuous motion systems.

**0x02 – Torque Control**\
Regulates motor torque by controlling current output.\
Useful for force-sensitive applications like grippers, presses, or tensioning systems.\
To start or stop the motor, toggle the **Torque Enable** register:\
`1` → Motor output enabled\
`0` → Motor safely disabled (required before modifying critical parameters)

**0x03 – PWM Mode**\
Directly controls the motor output using a user-defined PWM duty cycle.\
This mode bypasses closed-loop control and sends raw PWM signals to the motor, giving full manual control over power delivery.\
Ideal for advanced users who require custom control behavior, signal testing, or integration with external controllers.

## <mark style="color:red;">Intelligent Autotuning</mark>

Manually tuning a PID controller can be tedious and error-prone. SMD Red simplifies this with an integrated **Autotuner**.

By setting the **Autotuner Enable** register to `1`, the system automatically performs PID calibration using the **Cohen-Coon method** — a proven control algorithm.\
&#x20;\- Completion in \~30 seconds\
\- Optimized P, I, D values for your specific load and application\
\- Works for position and velocity modes

This enables seamless adaptation for changing dynamics without manual calculation or trial-and-error.

## <mark style="color:red;">Command Setpoints & Safety Limits</mark>

Each control mode accepts a **setpoint**:

* **Position Setpoint**: Encoder tick value
* **Velocity Setpoint**: Speed (ticks per 100 ms)
* **Torque Setpoint**: Desired current (mA)

Define **limit thresholds** to prevent unsafe behavior:

* **Current Limit**: Max current draw (0–65535 mA) to avoid overheating or overload
* **Velocity Limit**: Max speed limit (ticks/100 ms) for safe operation
* **Position Limits**: Define physical range boundaries for travel

These constraints ensure safe, reliable operation — especially in high-risk or autonomous systems.

## <mark style="color:red;">Hardware Specifications</mark>

For more detailed information, please refer to the SMD RED datasheet.

{% file src="/files/SeHXZSg6egifvNyvpnPm" %}

## <mark style="color:red;">Supported Modules</mark>

<table><thead><tr><th width="278.79998779296875">Module</th><th>Description</th><th data-hidden></th></tr></thead><tbody><tr><td>Ambient Light Sensor Module</td><td>Detects surrounding light intensity</td><td></td></tr><tr><td>Button Module</td><td>Simple digital input trigger</td><td></td></tr><tr><td>Buzzer Module</td><td>Emits audio signals for alerts or feedback</td><td></td></tr><tr><td>IMU Module</td><td>Measures orientation and acceleration (gyroscope + accel)</td><td></td></tr><tr><td>Joystick Module</td><td>Manual directional control input</td><td></td></tr><tr><td>Potentiometer Module</td><td>Analog input for tuning or manual adjustment</td><td></td></tr><tr><td>Reflectance Sensor Module</td><td>Ideal for line-following robot applications</td><td></td></tr><tr><td>RGB LED Module</td><td>Visual output for feedback and signaling</td><td></td></tr><tr><td>Servo Module</td><td>Controls servo motors for angle-based motion</td><td></td></tr><tr><td>Ultrasonic Distance Sensor</td><td>Measures distance for obstacle detection and avoidance</td><td></td></tr></tbody></table>

## <mark style="color:red;">Inputs and Outputs</mark>

#### Ports of SMD Red

SMD RED has two power ports, two RJ-45 ports for the connection between SMD REDs, one I2C port for sensor connection and an actuator port. Ports are shown in the image below, a detailed map can be seen at[#detailed-port-map-of-smd-red](#detailed-port-map-of-smd-red "mention").

<figure><img src="/files/XrZDiyj08X0GijWGtNuZ" alt=""><figcaption><p>SMD Red Ports</p></figcaption></figure>

#### Detailed Port Map of SMD Red

<figure><img src="/files/TrGDh6SKN9AbrZoY9F50" alt=""><figcaption><p>SMD Red V2.2 Pinout</p></figcaption></figure>

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

#### SMD Red LED Color Indications

<table><thead><tr><th width="149">LED Color</th><th width="231.20001220703125">Meaning</th><th width="369.4000244140625">Details</th><th data-hidden></th></tr></thead><tbody><tr><td>🟡 <strong>Yellow</strong></td><td>No EEPROM Save Detected</td><td>Stays on until user performs EEPROM save. Also appears after Factory Reset. If still lit after saving, EEPROM may have issues. Not considered an error by itself.</td><td></td></tr><tr><td>⚪ <strong>White</strong></td><td>IDLE / Firmware Status</td><td>Solid: IDLE mode. Blinking fast (every 50ms): No valid firmware or hardware mismatch. Blinking slow (every 150ms): Scanning modules.</td><td></td></tr><tr><td>🟢 <strong>Green</strong></td><td>Ready / Motor Active</td><td>Indicates the motor driver is active and ready to drive. Should be on when the motor is running.</td><td></td></tr><tr><td>🔵 <strong>Blue</strong></td><td>Autotuning Active</td><td>Blinks during PID tuning. Torque must be enabled. It is normal to see blue and green together during this state.</td><td></td></tr><tr><td>🔴 <strong>Red</strong></td><td>Overcurrent / Current Limit</td><td>Turns on when the motor draws excessive current or exceeds the defined current limit. Can resume by toggling torque off and on.</td><td></td></tr><tr><td>🟣 <strong>Purple</strong></td><td>Communication Issue</td><td>Appears when communication fails between modules or host device.</td><td></td></tr><tr><td>🟦 <strong>Cyan</strong></td><td>User Indicator</td><td>Blinks when <code>userIndicator</code> is triggered by user code. Not shown unless explicitly activated.</td><td></td></tr></tbody></table>

## <mark style="color:red;">Software Compatibility</mark>

SMD Red is compatible with multiple software environments:

* **SMD Blockly** – Visual programming environment for beginners
* **Python SDK** – Advanced scripting for real-time control and logic
* **Flutter Mobile App** – Wireless control via smartphone or tablet
* **CLI Access** – Direct low-level command-line communication

## <mark style="color:red;">Example Use Cases</mark>

* Two-wheel differential drive robots with encoder feedback
* PID-based motion control experiments
* Pan-tilt camera or sensor platforms
* Sensor-guided obstacle avoidance
* Mobile robot with joystick input and RGB LED feedback

Here is a demonstration of daisy-chain and cable management used for "Synchronizing Linear Motors" application:

<figure><img src="/files/PVBuIiGloxOQv962rbW4" alt=""><figcaption><p>Here is a demonstration of daisy chain and cable management used for Synchronizing Linear Motors Application</p></figcaption></figure>

## <mark style="color:red;">Summary</mark>

SMD Red is more than just a motor controller—it's a **scalable, modular, and smart development platform** for anyone working in robotics, automation, or STEM education. By combining hardware simplicity with software versatility, SMD Red raises the bar for motion control solutions.

From your first mobile robot to an advanced synchronized system, **SMD Red is built to grow with your ideas.**

Setup File:

{% file src="/files/1cZH04euEUHbJ0n4lmHS" %}

#### Step Files:

{% file src="/files/32Bc31SarqEszYLja3dQ" %}


# Boardoza Pulse & Acrome SMD Integration

This section details the communication topology, signal processing flow, and hardware abstraction layers between the Boardoza Pulse S32-S3 master control unit and Acrome SMD Red smart motor drivers.

The system utilizes a distributed control architecture, leveraging the industrial RS485 differential signaling standard to ensure robust data transmission in electrically noisy environments.

### Operation Logic and Signal Flow Diagram

The data flow is structured into three primary phases: Command Generation (Master), Physical Layer Conversion (Gateway), and Actuation (Slave).

#### 1. Master Control Unit (MCU): Boardoza Pulse S32-S3

The Boardoza Pulse acts as the central processing unit (CPU) of the system. It is responsible for trajectory generation, kinematic calculations, and high-level decision-making logic.

* Function: Kinematics solving and command packet generation.
* Interface: UART (Universal Asynchronous Receiver-Transmitter).
* Physical Output: Transmits serial data at TTL logic levels (typically 3.3V) via the J4 Connector.
* Technical Detail: The MCU calculates the target position, velocity, or torque profile and transmits this data via the TX (Transmit) line at a predefined baud rate.

#### 2. Signal Conditioner (Gateway Interface)

This component serves as the physical layer (PHY) bridge. It converts the Single-Ended TTL UART signals from the MCU into Differential RS485 signals suitable for industrial transmission.

* Function: Protocol translation and signal conditioning `(UART TTL ↔ RS485 Differential)`.
* Engineering Rationale: Standard TTL signals are susceptible to attenuation and Electromagnetic Interference (EMI) over long distances. The Gateway encodes the data as a voltage difference between lines A and B. This differential structure utilizes Common Mode Rejection to nullify external noise, ensuring signal integrity over longer cable runs.

#### 3. Smart Actuator (Slave Node): Acrome SMD Red

The Acrome SMD Red is the terminal execution unit. It listens to the RS485 bus, parses incoming data packets, and manages the power stage to drive the motor.

* Function: Packet parsing, address verification, and Power Stage Switching.
* Input Interface: RS485 (Half-Duplex).
* Process: The driver continuously monitors the bus. Upon receiving a valid data packet (verified via Checksum) that matches its unique Node ID, the internal processor interprets the command and applies the necessary PWM signals to the MOSFET bridge to energize the motor coils.

***

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

### Design Justification: Why this Architecture?

From an engineering perspective, this topology is selected based on the following design criteria:

1. Signal Integrity: Motors generate significant inductive noise and switching transients. The differential nature of RS485 provides high immunity against this EMI, preventing data corruption.
2. Scalability: The bus topology allows for a modular design. Multiple drives can be added to the system using a Daisy-chain configuration without altering the core hardware of the controller.
3. Distributed Processing: Computational load is decentralized. The Boardoza Pulse handles the "Motion Planning," while the high-frequency current control loops and PID algorithms are executed locally on the Acrome SMD.


# Coding Guide

This detailed guide teaches you exactly how to write your first code for SMD Red from scratch, suitable for beginners with no coding experience. You'll learn step-by-step, clearly and thoroughly, how to program motors and modules.

***

### What is SMD Red?

**SMD Red** is a smart controller designed to simplify controlling Brushed DC motors, servos, and various sensors. It receives commands from your computer (Raspberry Pi using Python) or microcontroller (Arduino using Arduino IDE) and translates these commands into actions performed by your robot.

***

### Important: Understanding IDs

* **SMD Red ID:** Every SMD Red controller has a unique ID number. Initially, these IDs might be the same, but you must assign unique IDs when using multiple controllers in one project.
* **Module ID:** Every connected sensor, servo, or other module has a predefined ID, which is generally fixed but can be physically rearranged.
* **Motor ID:** Motors do not have individual IDs. Instead, they use the ID of the SMD Red controller they're attached to.

To manage and test your SMD Red boards and modules, It is recommended to use the [**SMD UI**](https://docs.acrome.net/software/smd-ui). This software allows you to:

* Verify the IDs of connected modules and controllers
* Change SMD Red IDs to unique values for project usage
* Test functionality of motors and modules

***

### Part 1: Coding with Python (Using VS Code)

#### Step 1: Install Required Tools

1. **Python**: Download from [python.org](https://python.org/). Choose the latest version and install it.
2. **Visual Studio Code (VS Code)**: Download from [code.visualstudio.com](https://code.visualstudio.com/). This will be your coding editor.

#### Step 2: Install Python Packages

Open VS Code, then open a new terminal ("Terminal" → "New Terminal"). Run this command:

```bash
pip3 install acrome-smd
pip3 install pyserial flask flask-cors acrome-smd
```

#### Step 3: Writing Your First Python Program (Detailed Explanation)

Open VS Code, create a file called `robot_control.py`. Below is a simple and detailed starter program:

```python
# Import necessary libraries from SMD Red
from smd_red import Master

# Establish connection to SMD Red controller via USB
master = Master("/dev/ttyUSB0")

# Motor Control Example:
# Set motor speed (50 means half speed forward, -50 means half speed backward)
master.set_motor(0, 50)  # Controls motor connected to SMD Red ID 0

# Wait for 2 seconds, motors keep moving
import time
time.sleep(2)

# Stop motor
master.set_motor(0, 0)

# Servo Control Example:
# Move servo motor to specific angle (90 degrees)
master.set_servo(0, 4, 90)  # Servo module ID 4 on SMD Red ID 0

# Sensor Reading Example:
# Read data from sensor connected with module ID 5
sensor_data = master.get_sensor_data(0, 5)
print("Sensor data:", sensor_data)
```

#### Explanation of Code:

* **Master connection:** Links your computer to the SMD Red controller.
* **Motor commands:** Uses the ID of SMD Red to send commands directly to connected motors.
* **Servo commands:** Require specifying the SMD Red ID and servo module ID.
* **Sensor commands:** Require specifying the SMD Red ID and sensor module ID to get sensor data.

***

### Part 2: Coding with Arduino IDE

#### Step 1: Install Arduino IDE

Download Arduino IDE from [arduino.cc](https://arduino.cc/), install and open it.

#### Step 2: Install SMD Red Arduino Library

* In Arduino IDE, navigate to `Sketch → Include Library → Manage Libraries`
* Search for **"Acrome-SMD"**, then install it.

#### Step 3: Wiring Arduino and SMD Red

* Connect Arduino to SMD Red using an Arduino Gateway module (RX/TX pins).

![](/files/OKgvWLUGkjSFXPcGtibv)          ![](/files/Xkpiw37l5CwLetn7q6Mi)

* Connect SMD Red boards via RJ11 cables and modules via RJ45 cables.

#### Step 4: Detailed Arduino Programming Example

Open Arduino IDE and create a new sketch:

```cpp
// Include Acrome SMD Red library
#include <Acrome-SMD.h>
#define BAUDRATE 115200

// Initialize communication with SMD Red board ID 0
Red smd(0, Serial, BAUDRATE);

void setup() {
  // Start serial communication at the defined baud rate
  Serial.begin(BAUDRATE);

  // Start communication with SMD Red
  smd.begin();

  // Set operation mode for controlling motor speed (PWM mode)
  smd.setOperationMode(PWMControl);

  // Enable motor torque (power)
  smd.torqueEnable(1);
}

void loop() {
  // Move motor forward at half speed
  smd.setpoint(0, 50);
  delay(2000);  // Wait for 2 seconds

  // Stop the motor
  smd.setpoint(0, 0);
  delay(2000);

  // Servo example: Move servo (module ID 4) to 90 degrees
  smd.setServo(0, 4, 90);
  delay(1000);

  // Read data from a sensor (module ID 5)
  int sensor_value = smd.getSensorData(0, 5);
  Serial.print("Sensor data: ");
  Serial.println(sensor_value);
  delay(1000);
}
```

#### Explanation of Arduino Code:

* **Library Import:** Adds the necessary commands to control SMD Red.
* **Setup:** Initializes communication, sets operation modes, and enables power to motors.
* **Loop:** Repeatedly executes motor movement, servo positioning, and sensor data reading.

***

### Tips for Beginners

* Clearly verify and set unique SMD Red IDs using the[ SMD UI](/software/smd-ui) app.
* Test each module separately before combining them.
* Regularly test your code and debug using Serial Monitor or Python print statements.

***

### Troubleshooting Tips ([SMD Red Troubleshooting Guide](/electronics/smd-red/troubleshooting-guide))

* Double-check connections (USB, RJ11, RJ45).
* Verify module and SMD Red IDs using the [SMD UI](/software/smd-ui) app.
* If errors occur, revisit installation and wiring steps.


# Raspberry Pi Setup Guide

> ⚠️ **Audience:** This guide is written for complete beginners. No prior experience with coding, electronics, or Raspberry Pi is required.

***

### Introduction

Welcome to the official SMD Red Robot Guide using Raspberry Pi. This document will walk you through every single step required to:

* Set up your computer environment
* Assemble your robot and connect Raspberry Pi and SMD Red hardware
* Program and test your robot using Python code and a web interface

By following this guide step by step, you'll successfully build a fully functional smart robot that can:

* Drive using DC motors
* Rotate pan/tilt servos
* Detect objects using sensors
* Be controlled via Wi-Fi through a mobile or web app

***

### 1. User PC Setup

Before configuring the robot itself, your computer must be ready to write, edit, and transfer code to the Raspberry Pi.

#### 1.1 Install Python

* Visit: [https://www.python.org](https://www.python.org/)
* Download the latest version compatible with your operating system.
* During installation, make sure to enable **“Add Python to PATH”**.
* After installation, verify Python works by opening a terminal/powershell and running:

```bash
python --version
```

Expected output: `Python 3.x.x`

#### 1.2 Install acrome-smd Library

This library allows you to write Python programs that talk to the SMD Red hardware.

```bash
pip install acrome-smd
```

> 💡 Run this on both your **PC** and **Raspberry Pi** later. This step ensures compatibility and development flexibility.

#### 1.3 (Optional) Install Visual Studio Code

Recommended if you want a user-friendly interface for writing Python code.

* Download from: [https://code.visualstudio.com](https://code.visualstudio.com/)

#### 1.4 Install Raspberry Pi Imager

This tool lets you install the operating system onto the Raspberry Pi’s SD card.

* Download from: <https://www.raspberrypi.com/software>
* We will use this in the next step to flash Raspberry Pi OS.

***

### 2. Robot Assembly + Raspberry Pi Setup

#### 2.1 Required Hardware

Here’s everything you’ll need physically:

* Raspberry Pi 3B+
* MicroSD card (16GB or larger)
* [USB Gateway Module ](/electronics/gateway-modules/usb-gateway-module)(USB-A on one end, RJ11 port on the other)
* 1–2x SMD Red Drivers
* 2x [DC motors](/electronics/electrical-motors/brushed-dc-motors-bdc) with wheels (for driving)
* 2x [Servo motors ](/electronics/add-on-modules/servo-module)(for pan/tilt)
* 1x[ Ultrasonic sensor](/electronics/add-on-modules/ultrasonic-distance-sensor-module) (distance measurement)
* RJ11 cables: To daisy-chain SMD Red modules and connect Gateway
* RJ45 cables: To connect modules (e.g., motors/servos) to SMD Red
* 12V power supply: Powers SMD Red and motor modules
* 5V USB-C: Powers the Raspberry Pi
* Screws, jumper wires, zip ties: For physical mounting and wiring

#### 2.2 Wiring Overview

* USB-A from USB Gateway → Raspberry Pi USB port
* RJ11 from USB Gateway → SMD Red 0 RJ11 IN
* RJ11 SMD Red 0 → SMD Red 1 → SMD Red 2 (daisy-chained)
* Power connectio&#x6E;**:** Each SMD Red unit requires a separate **power-to-power cable** connection for power supply.
* RJ45 from SMD Red to DC motor, servo, sensor modules

> 🧠 **RJ11 cables** carry communication between controller boards (SMD Reds), and between the Gateway and first SMD Red.\
> 🧠 **RJ45 cables** carry signals and power to individual hardware modules.

#### 2.3 Flash the OS and Configure Raspberry Pi

* Launch Raspberry Pi Imager
* Select: Raspberry Pi OS (Lite – 64-bit)
* Click the gear icon for Advanced Options:
  * Enable SSH (use password authentication)
  * Set Username: `pi`, Password: `raspberry`
  * Enter your Wi-Fi name and password
  * Set Hostname: `smd-robot`
* Choose SD card and click **Write**
* Safely eject and insert into your Raspberry Pi

#### 2.4 Access Raspberry Pi Terminal

To configure and program your Raspberry Pi, you need terminal access.

**🟢 Option 1: Headless (Preferred)**

No monitor/keyboard required. Access via Wi-Fi.

Steps:

* Power on Raspberry Pi
* From your computer:

```bash
ssh pi@smd-robot.local
```

> If that fails, get your Pi’s IP address from your router and run:

```bash
ssh pi@<your_ip_address>
```

**🔵 Option 2: HDMI + Keyboard**

Plug a monitor and keyboard directly to the Pi.

Steps:

* Power on
* Login with:
  * Username: `pi`
  * Password: `raspberry`
* Open terminal and run:

```bash
sudo raspi-config
```

Use this menu to configure Wi-Fi and hostname manually if needed.

***

### 3. Programming and Code Upload

Once your Pi is online and you have terminal access, you can upload your robot code.

#### 3.1 Update Raspberry Pi and Install Tools

Run these commands:

```bash
sudo apt update && sudo apt upgrade -y
sudo apt install python3-pip hostapd dnsmasq network-manager -y
```

> These install Python tools and network support, required for running and debugging the robot, or enabling offline hotspot.

#### 3.2 Install SMD Red Python Library on Raspberry Pi

```bash
pip install acrome-smd
```

> Needed to communicate with the SMD Red hardware using Python.

#### 3.3 Send Your Python Code from PC to Pi

Use the following command on your computer:

```bash
scp python.py requirements.txt pi@smd-robot.local:/home/pi/
```

> This sends your project files securely to the Pi.

#### 3.4 Install Required Python Libraries

On Raspberry Pi:

```bash
pip install -r requirements.txt --break-system-packages
```

> This includes Flask (for web server), pyserial (for USB communication), and others.

#### 3.5 Set Up Autostart (Optional But Recommended)

If you want your robot to launch automatically on boot:

1. Create a systemd service file:

```bash
sudo nano /etc/systemd/system/run_script.service
```

2. Paste the following:

```ini
[Unit]
Description=SMD Robot Service
After=network.target

[Service]
ExecStart=/usr/bin/python3 /home/pi/python.py
WorkingDirectory=/home/pi
User=pi
Group=pi
Restart=always

[Install]
WantedBy=multi-user.target
```

3. Activate the service:

```bash
sudo systemctl daemon-reload
sudo systemctl enable run_script.service
sudo systemctl start run_script.service
```

> Now your robot program will automatically start every time your Raspberry Pi is turned on!

***

### 4. Run and Test Your Robot

#### 4.1 Manual Test

Run your Python script:

```
python3 python.py
```

Expected output:

```
Connected to /dev/ttyUSB0
Flask server running at 0.0.0.0:5000
```

> If you see this, your Pi has found the USB Gateway and is running the robot web server.

#### 4.2 Open Web Control Interface

On your phone or computer browser (same Wi-Fi):

```
http://smd-robot.local:5000
```

You should see:

* 🟢 Buttons to move the robot forward/backward/turn
* 🎛 Sliders to control pan/tilt servos
* 📏 Sensor readout (ultrasonic distance)
* 🔘 Linear motor control (if connected)

***

### 5. Troubleshooting Table ([SMD Red Troubleshooting Guide](/electronics/smd-red/troubleshooting-guide))

| Problem               | Cause                          | Solution                          |
| --------------------- | ------------------------------ | --------------------------------- |
| USB Gateway not found | Faulty cable or power          | Try different port or cable       |
| No /dev/ttyUSB\*      | USB Gateway not recognized     | Reboot Pi, reinsert device        |
| SMDs unresponsive     | RJ11 cables disconnected       | Ensure cables are seated tightly  |
| Motors don’t move     | Modules not connected via RJ45 | Check RJ45 cables and IDs         |
| Script crash          | Python package missing         | Run pip install again             |
| Web not loading       | Flask not running              | Run script manually or check logs |

***

### 6. Final Checklist

Before moving forward:

* [x] Raspberry Pi configured and connected
* [x] USB Gateway properly plugged into Pi
* [x] RJ11 cables connecting all SMD Red modules
* [x] RJ45 cables linking modules to SMD Red
* [x] Python code copied to Pi and dependencies installed
* [x] Robot script starts manually or automatically
* [x] Web UI reachable via browser

🎉 **Congratulations! You now have a complete robot platform ready to expand and explore!**


# Arduino Setup Guide

This detailed and beginner-friendly guide walks you through every step needed to build, connect, program, and troubleshoot a robot using the **SMD Red** motor controller and an **Arduino** board. Whether you're a student, teacher, hobbyist, or engineer, this guide is designed to be practical and accessible.

***

### Introduction

The **SMD Red** is a smart motor controller that lets you easily drive motors, control servos, and read sensor data. It communicates with Arduino through an RS-485 connection via the **Arduino Gateway Module**, making it powerful yet easy to use even for beginners.

This guide explains everything you need to:

* Build your robot with SMD Red and Arduino
* Wire all components correctly
* Write and upload code using Arduino IDE
* Understand how the SMD Red system works
* Test and troubleshoot each part step by step

Even if you've never built a robot or written a line of code, this guide will help you go from zero to a working robot confidently.

***

### 1. User PC Setup

#### Install Arduino IDE and SMD Library

1. Download Arduino IDE from [arduino.cc](https://www.arduino.cc/en/software).
2. Install and open the IDE.
3. Navigate to `Sketch > Include Library > Manage Libraries`.
4. Search for `Acrome-SMD` and click **Install**.

#### &#x20;Install [SMD UI](/software/smd-ui) for:

* Verify the IDs of connected modules and controllers
* Change SMD Red IDs to unique values for project usage
* Test functionality of motors and modules

✅ Your computer is now ready to program your robot.

***

### 2. Robot Assembly + Arduino Setup

#### 🔌 Connecting SMD Red to Arduino

* Use the [**Arduino Gateway Module**](/electronics/gateway-modules/arduino-gateway-module) — a red shield that plugs directly into your Arduino Uno/Mega headers.
* Plug an **RJ-11 cable** from the Gateway Module to the first SMD Red Motor Driver Board.

#### Connecting Modules

* Connect modules (e.g., motors, servos, sensors) to the SMD Red using **RJ-45 cables**.

#### Module IDs

Each SMD module comes with a **module ID** that identifies it. These IDs are hardware-based and may vary between module versions. Use the [**SMD UI**](https://docs.acrome.net/software/smd-ui) to:

* Detect which modules are connected
* Confirm or discover module IDs
* Test functionality

📌 If multiple modules share the same ID, they must be connected to different SMD Red controllers to prevent conflict.

#### Daisy-Chaining Multiple SMD Reds

* Use **RJ-11** cables to connect additional SMD Reds.
* Each SMD Red must have a **unique ID** (0, 1, 2, ...).
* Use [**SMD UI** ](/software/smd-ui)to:
  * Assign and verify SMD Red IDs
  * Monitor and test all connected modules

#### ⚡ Powering Your System

* Plug a 12V DC adapter into the power port of the SMD Red.

***

### 3. Programming and Code Upload

To control the SMD Red from Arduino, you'll write and upload C++ code using the Arduino IDE. Here’s a breakdown of how it works:

#### Program Flow

1. **Include the library** for SMD Red: `#include <Acrome-SMD.h>`
2. **Define the serial baud rate** (default is 115200).
3. **Create a Red object**, defining which SMD Red you’re connecting to.
4. In `setup()`, initialize the communication, choose control mode, and enable torque.
5. In `loop()`, send commands to control motors.

#### Example Code: Basic Motor Control

```cpp
#include <Acrome-SMD.h>
#define BAUDRATE 115200

Red red(0, Serial, BAUDRATE);  // SMD Red ID 0 on Serial port

void setup() {
  red.begin();                       // Start communication
  red.setOperationMode(PWMControl); // Set PWM speed control mode
  red.torqueEnable(1);              // Turn motor output ON
}

void loop() {
  red.setpoint(0, 50);  // Run motor 0 forward at 50% power
  delay(1000);
  red.setpoint(0, 0);   // Stop motor
  delay(1000);
}
```

#### Code Explained

* `Red red(...)`: Creates a connection to SMD Red ID 0
* `begin()`: Establishes communication
* `setOperationMode(PWMControl)`: Sets control mode to PWM (speed)
* `torqueEnable(1)`: Enables motor power output
* `setpoint(0, 50)`: Sends command to motor 0 to run at 50% forward
* `delay(1000)`: Waits for 1 second before stopping

💡 You can add more `setpoint()` lines or change the speed/direction with values from -100 to 100.

***

### 4. Run and Test Your Robot

#### Uploading the Code

1. Connect Arduino to your PC using USB.
2. In Arduino IDE, go to `Tools > Port` and select the correct COM port.
3. Click the **Upload** button to flash your code.

#### Verifying Operation

* After uploading, the motor should spin forward for 1 second, then stop.

***

### 5. Troubleshooting Table ([SMD Red Troubleshooting Guide](/electronics/smd-red/troubleshooting-guide))

| Problem                 | Possible Cause               | Recommended Fix                           |
| ----------------------- | ---------------------------- | ----------------------------------------- |
| Nothing is moving       | No power to SMD Red          | Connect 12V adapter                       |
| Upload error in IDE     | TX/RX conflict with Serial   | Disconnect SMD Red before uploading       |
| Module not detected     | Wrong ID / cable loose       | Verify using SMD UI                       |
| Motor spins wrong way   | Wiring reversed              | Swap motor wires or use negative setpoint |
| Sensor returns 0 always | Wrong module ID or bad cable | Check ID with SMD UI and replug cable     |

***

### 6. Final Checklist

* [x] Arduino IDE installed
* [x] Acrome-SMD library installed
* [x] Arduino Gateway Module attached
* [x] RJ-11 cable connected to SMD Red
* [x] Modules connected via RJ-45
* [x] 12V power supply connected
* [x] SMD Red IDs confirmed via SMD UI
* [x] Code uploaded and working

🎉 **You’re done!** Your robot is now fully operational using Arduino + SMD Red. Start adding new features like servo control, sensor-based actions, or AI-assisted navigation!


# Troubleshooting Guide

A comprehensive guide to identifying and resolving issues when working with the SMD Red motor driver.

## 1. Connection & Detection Issues

**Problem:** SMD Red is not recognized over USB\
**Possible Causes:**

* Faulty USB cable or port
* Missing or incompatible USB driver
* Incorrect serial port used in the code

**Solutions:**

* Use the `USB_Port()` function from the SDK to auto-detect the correct port.
* Try with another cable and USB port.
* Ensure drivers like FTDI or CH340 are properly installed (especially on Windows).
* Restart the computer and try reconnecting the device.
* Confirm the LED indicator is active.

<table><thead><tr><th width="131.39996337890625">LED Color</th><th width="230.4000244140625">Meaning</th><th width="385.4000244140625">Details</th><th data-hidden></th></tr></thead><tbody><tr><td>🟡 <strong>Yellow</strong></td><td>No EEPROM Save Detected</td><td>Stays on until user performs EEPROM save. Also appears after Factory Reset. If still lit after saving, EEPROM may have issues. Not considered an error by itself.</td><td></td></tr><tr><td>⚪ <strong>White</strong></td><td>IDLE / Firmware Status</td><td>Solid: IDLE mode. Blinking fast (every 50ms): No valid firmware or hardware mismatch. Blinking slow (every 150ms): Scanning modules.</td><td></td></tr><tr><td>🟢 <strong>Green</strong></td><td>Ready / Motor Active</td><td>Indicates the motor driver is active and ready to drive. Should be on when the motor is running.</td><td></td></tr><tr><td>🔵 <strong>Blue</strong></td><td>Autotuning Active</td><td>Blinks during PID tuning. Torque must be enabled. It is normal to see blue and green together during this state.</td><td></td></tr><tr><td>🔴 <strong>Red</strong></td><td>Overcurrent / Current Limit</td><td>Turns on when the motor draws excessive current or exceeds the defined current limit. Can resume by toggling torque off and on.</td><td></td></tr><tr><td>🟣 <strong>Purple</strong></td><td>Communication Issue</td><td>Appears when communication fails between modules or host device.</td><td></td></tr><tr><td>🟦 <strong>Cyan</strong></td><td>User Indicator</td><td>Blinks when <code>userIndicator</code> is triggered by user code. Not shown unless explicitly activated.</td><td></td></tr></tbody></table>

**Problem:** `attach(Red(ID))` fails or gives timeout

* Make sure the correct `ID` is used for the SMD Red connected.
* Use `scan_modules()` to detect all available modules.

## 2. Motor Not Moving or Moving Incorrectly

**Problem:** Motor doesn’t respond to control commands\
**Check:**

* Torque is enabled
* Operation mode is set
* CPR is configured
* Firmware and API version compatibility:\
  Make sure the firmware and API are on the same major version (e.g., `2.*.*`).\
  You can verify this using the command:

```
get_firmware_version()
```

**Problem:** Motor rotates in the opposite direction

* Invert the duty cycle (e.g., use `-value`)
* Physically switch motor wires if possible
* Adjust inversion settings in software logic

**Problem:** Motor vibrates or moves erratically

* Double-check the power supply
* Lower the control frequency or PID gains
* Reduce mechanical load temporarily to test

## 3. Torque Enable and Operation Mode Setup

**Always ensure this sequence:**

1. `attach(Red(smd_id))`
2. `set_operation_mode()`
3. `set_shaft_cpr()`
4. `enable_torque()`

**Common Mistakes:**

* Enabling torque before setting mode/CPR
* Setting wrong operation mode (e.g., using `POSITION` for a brushed DC motor)
* Forgetting to re-enable torque after changing settings

## 4. Position, Velocity, and Torque Control Issues

**Problem:** No movement in position control

* Make sure target setpoint differs from current position
* Use correct unit: ticks, not degrees
* CPR must match the encoder used

**Problem:** Velocity setpoint has no effect

* Confirm that the velocity mode is selected
* Check if PID tuning is appropriate for your load

**Problem:** In torque control, motor draws too much current

* Set a proper `current_limit`
* Check for mechanical resistance or misalignment

## 5. Encoder and Feedback Problems

**Problem:** `get_position()` returns 0 or constant values

* Encoder might not be connected
* CPR not configured correctly
* Shaft may not be moving

**Problem:** Sudden jumps or noisy feedback

* Use shielded cables
* Avoid running encoder wires near power lines
* Add averaging/filtering logic in your application

## 6. Servo Control Issues

**Problem:** Servo doesn't move or jitters

* Make sure it's in `POSITION` mode
* Torque must be enabled
* CPR value should be appropriate (e.g., 4096 for 0–180° servos)

**Problem:** Set position command is ignored

* Use `set_position(module_id, angle, smd_id)`
* Ensure the angle is within valid range (0–180 degrees, mapped to ticks)

## 7. Watchdog and Safety Triggers

**Problem:** Motor stops after a few seconds

* Watchdog might be enabled and not refreshed
* Disable it during development using:

```python
master.set_watchdog(module_id, 0, smd_id)
```

**Problem:** Motor disabled after overload

* Check `get_error_flags()` for overcurrent or overtemperature
* Use `clear_errors()` if needed

## 8. Python SDK Usage Mistakes

**Common Errors:**

* Passing wrong `module_id` or `smd_id`
* Forgetting to attach the device
* Mixing up control modes (e.g., calling `set_duty_cycle` in `POSITION` mode)
* Not handling exceptions (wrap critical code in `try/except`)

## 9. Communication and Timing Issues

**Problem:** Communication timeout

* Try reducing loop frequency
* Add delays between high-frequency read/write operations
* Use `get_driver_info()` and `scan_modules()` to debug

**Problem:** Conflict with another serial device

* Ensure the port is not in use by other software (e.g., Arduino IDE)

## 10. Diagnostic and Debugging Tools

Use the following SDK functions to debug:

* `get_driver_info(smd_id)`
* `scan_modules(smd_id)`
* `get_position(module_id, smd_id)`
* `get_velocity(module_id, smd_id)`
* `get_current(module_id, smd_id)`
* `get_error_flags(module_id, smd_id)`

## 11. Environmental and Hardware Considerations

* Keep motor away from heat sources or enclosed areas
* Avoid long unshielded cables for encoders
* Check power supply stability under load
* Ensure RJ-11 connectors are fully seated

## 12. Best Practices and Preventive Tips

* Always initialize devices in proper order: attach → configure → enable
* Use retry logic when reading feedback
* Log sensor and motor states for debugging
* Perform PID tuning under real load conditions
* Keep firmware and SDK up-to-date
* Avoid forcing motors when torque is disabled

## Feedback

Found this page helpful? [Let us know](https://docs.acrome.net/help/reach-us) what you think.


# Copy of SMD Red

The Brushed DC Motor Driver

## <mark style="color:red;">ACROME SMD Red - BDC Motor Driver</mark>

{% embed url="<https://www.youtube.com/watch?v=uJNtaVi0orM>" %}

SMD Red is designed to bring revolutionary solutions to the robotics and motion systems with brushed DC motors, allowing users to be more creative and focus on their project.

The key feature of SMD Red is its compatibility with a wide range of applications through the use of different SMD modules and brushed DC motor. This flexibility and modularity easily meets the requirements of many possible motion projects. All these facilities allow the user to design any mobile system without any hassle.

SMD Red opens a new door to the world of robotics for makers with its scalability and comprehensive control of motor systems. SMD Red allows many SMD sensor modules to be used together in a synchronised network via its RJ-45 bus connector. Thus, makers can shape and enlarge their project according to the needs, without having to worry about messy cable management. This feature enhances  experience with motorised robotic projects and much more.

Each SMD Red has on-board power connectors, providing a convenient solution for daisy-chaining power lines of other SMD Reds or components of the mobile system. This approach makes power management of the project easier for makers, and allows seamless operation and integration.

In summary, SMD Red is not only a motor driver board, it is much more with smart solutions for motor control projects, mobile systems, educational projects and where imagination can extend. It sets a new standard of adaptability, scalability, modularity in the robotics and maker world, aiming to be a milestone and indispensable for projects.

### Features

The SMD Red is designed with features that simplify and improve the process of building a project. These features are mainly:

#### PID Autotune Function

PID autotune function fairly optimizes the performance of the DC motor, by using Cohen-Coon method to calculate PID parameters for multiple motor driving modes such as position control and velocity control mode. This function of SMD Red is effective since it uses multiple measurements according to the current load of motor system.

#### Synchronization Capability

SMD Red can be daisy-chained via RJ-11 connectors, and and connected to numerous SMD modules via RJ-45 connectors. This interconnection and communication increases the versatility of the systems and allows full synchronisation of the robotic system, using RS-485, one of the most preferred protocols with many advantages.

### Benefits

There are many benefits and reasons that make SMD Red an excellent choice for motion, mobile, robotics and educational projects.

* Versatile project development with modular and synchronised design solution
* PID auto-tune function that optimises the motor control experience
* Daisy-chaining that allows multiple motor control systems with various SMD modules to input and output various data to enrich the projects

Here is a demonstration of daisy-chain and cable management used for "Synchronizing Linear Motors" application:

<figure><img src="/files/PVBuIiGloxOQv962rbW4" alt=""><figcaption><p>Here is a demonstration of daisy chain and cable management used for Synchronizing Linear Motors Application</p></figcaption></figure>

## <mark style="color:red;">Inputs and Outputs</mark>

### Ports of SMD Red

SMD RED has two power ports, two RJ-45 ports for the connection between SMD REDs, one I2C port for sensor connection and an actuator port. Ports are shown in the image below, a detailed map can be seen at[#detailed-port-map-of-smd-red](#detailed-port-map-of-smd-red "mention").

<figure><img src="/files/XrZDiyj08X0GijWGtNuZ" alt=""><figcaption><p>SMD Red Ports</p></figcaption></figure>

### Detailed Port Map of SMD Red

<figure><img src="/files/TrGDh6SKN9AbrZoY9F50" alt=""><figcaption><p>SMD Red V2.2 Pinout</p></figcaption></figure>

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

## <mark style="color:red;">Registers</mark>

### Board Registers

#### Device ID

Device ID is the first thing to configure when developing a project with SMDs. The ID of an SMD Red is 0 as default. This value can be changed within range of 0 - 254, 0xFF reserved for broadcast commands.&#x20;

{% hint style="danger" %}
Reset the [#torque-enable](#torque-enable "mention") register before attempting to change the device ID, otherwise, request will be ignored for safety reasons. Device ID can't be changed while a motor is in operation.
{% endhint %}

It is crucial to change the ID of any SMD before daisy-chaining them, because SMD systems doesn't detect duplicated, overlapping IDs, meaning that if the user connects two or more SMDs without changing ID, since all of them has an ID of 0, system will not identify each card, resulting inability of controlling each SMD individually.

You can click for related functions to this register for [Python](https://github.com/Acrome-Smart-Motor-Driver/python-library?tab=readme-ov-file#update_driver_idself-id-int-id_new-int) and [Arduino](https://github.com/Acrome-Smart-Motor-Driver/SMD-Arduino-Library?tab=readme-ov-file#red---setdeviceid) library.

#### Baud Rate

SMD Red allows the user to select a baud rate from a wide range of 1527 - 6250000 bits/s. This makes it possible to develop various projects with specific requirements. The default baud rate of SMD Red is 115200 bits/s, which is a stable and widely accepted starting point.

{% hint style="danger" %}
Reset the [#torque-enable](#torque-enable "mention") register before attempting to change the baud rate of the SMD, otherwise, request will be ignored for safety reasons.
{% endhint %}

The user should ensure that the baud rate of each SMD in a system is the same to ensure synchronised communication

It is recommended that users to select known baud rates to ensure compatibility and reliability of communication. This selection is also important to avoid communication errors.

You can click for related functions to this register for [Python](https://github.com/Acrome-Smart-Motor-Driver/python-library?tab=readme-ov-file#update_master_baudrateself-br-int) and [Arduino](https://github.com/Acrome-Smart-Motor-Driver/SMD-Arduino-Library?tab=readme-ov-file#red---setbaudrate) library.

#### Error Flags

The error flags register is where the error codes are stored as bits. It serves as a tool for error management, which allows the user to identify errors on SMD.&#x20;

Specific error bits can be cleared with [#error-clear-command](#error-clear-command "mention").

Here are the error flags and their explanations:

1. **Input Voltage Error:** This flag is set when the input voltage rises above/falls below the minimum/maximum voltage limit that has been set by the user. If this flag is set, it causes the [#torque-enable](#torque-enable "mention") register to be disabled, resulting in the motor stopping.
2. **Overheat Error:** This flag is set when the temperature exceeds the temperature limit that has been set by the user. If this flag is set, it causes the [#torque-enable](#torque-enable "mention") register to be disabled, resulting in the motor stopping.
3. **Overload Error:** This flag is set when the current exceeds the current limit that has been set by the user. If this flag is set, it causes the [#torque-enable](#torque-enable "mention") register to be disabled, resulting in the motor stopping.
4. **Encoder Error:** This flag is set when the SMD is unable to gather data over a specified time from encoder. If this flag is set, it causes the [#torque-enable](#torque-enable "mention") register to be disabled, resulting in the motor stopping.
5. **Communication Error:** This flag is set when the SMD receives a faulty package. It doesn't affect the operation of the motor and the modules. It is an indicator for the user to understand if there are any communication problems.
6. **Flash Error:** This flag is set when the SMD encounters any difficulty while reading or writing data to EEPROM. It informs the user to check if there are any misconfigurations. In case of EEPROM reading failure, SMD will reset to the factory default.

All these flags allow the user to effectively determine the errors of the SMD when needed, so, the user will be able to take action to solve according to the error flag.

Here is a reference table of error flags register:&#x20;

<figure><img src="/files/EfK7y0S5MM19rE06oIxJ" alt=""><figcaption><p>Reference table of error flags register</p></figcaption></figure>

#### Hardware and Software Version

The hardware and software version registers allow the user to obtain information about the SMD system. If the user ever needs technical support, it is helpful to know the hardware version of the SMD. It is important to mind the hardware version of the SMD when looking for technical details of the SMD.

The software version information is essential to check if there are any updates to the functions of the SMD. The user can see the software version and check the source and updates of Acrome SMD, thus, knowing if it is necessary to update the software version of the SMD.

You can click for related functions to this register for [Python](https://github.com/Acrome-Smart-Motor-Driver/python-library?tab=readme-ov-file#get_driver_infoself-id-int) library.

***

### Control Registers

#### Operation Mode

The operation mode register is used to set the operation mode of the motor that connected to the SMD. SMD Red's different motor operation modes allow the user to select the required mode for projects with specific motor control needs.

Here are the motor operation modes:

1. **Position Control Mode (Default):** The position mode is enabled by setting the operation made register to 0x00. In position mode, the motor performs movements based on parameters configured for specific positions, such as degrees. This mode allows the user to precisely change the position of the motor . It is preferred in systems that require precise and sensitive motor movements, such as robotic arms.
2. **Velocity Control Mode:** The velocity mode is enabled by setting the operation made register to 0x01. In velocity mode, the motor operates at the configured speed. This mode allows the user to set the speed of the motor in terms of RPM. It is preferred in systems where a constant speed is required, such as conveyor belts, elevators.
3. **Torque Control Mode:**  The torque mode is enabled by setting the operation made register to 0x02. In torque mode, the motor operates to match a torque level. This mode allows the user to set the current that will be used by the motor, resulting in a specific torque level. It is preferred in systems where is a certain torque level is required, such as drilling machines, robotic material lift arms.

These various motor operation modes provide the opportunity to develop a wide range of applications and to meet the needs of the users and their projects. The simplicity of selecting the required motor operation mode allows the user to focus on the features of their project while maintaining the integration and synchronisation of the between the SMDs.

You can click for related functions to this register for [Python](https://github.com/Acrome-Smart-Motor-Driver/python-library?tab=readme-ov-file#set_operation_modeself-id-int-mode-operationmode) and [Arduino](https://github.com/Acrome-Smart-Motor-Driver/SMD-Arduino-Library?tab=readme-ov-file#red---setoperationmode) library.

#### Torque Enable

The torque enable register allows the user to directly control motor operation by simply changing this register. For this register, '1' means that the motor connected to the SMD will operate on command, '0' means that the motor will not operate and will stop its process if it is turned to the '0' value while it was '1'.

{% hint style="warning" %}
Many other register changes require the torque enable register to be resetted. This means that the motor must not move to change features of the SMD, to avoid accidents with motion systems.
{% endhint %}

You can click for related functions to this register for [Python](https://github.com/Acrome-Smart-Motor-Driver/python-library?tab=readme-ov-file#enable_torqueself-id-int-en-bool) and [Arduino](https://github.com/Acrome-Smart-Motor-Driver/SMD-Arduino-Library?tab=readme-ov-file#red---torqueenable) library.

#### Autotuner Enable

The autotuner enable register controls the operation of the PID auto-tune function. The motor auto-tuning function can be run simply by changing this register from '0' to '1'. This will activate the PID auto-tune function, which takes approximately 30 seconds to determine the optimum P, I and D parameters for specific motor control modes of the SMD.

You can click for related functions to this register for [Python](https://github.com/Acrome-Smart-Motor-Driver/python-library?tab=readme-ov-file#pid_tunerself-id-int) and [Arduino](https://github.com/Acrome-Smart-Motor-Driver/SMD-Arduino-Library?tab=readme-ov-file#red---tune) library.

#### Current Limit

The current limit is the upper limit for stopping motor operation. This value can be set by the user in mA (milliamperes) in the range of 0 - 65535. The motor that connected to the SMD will automatically stop if the supply current rises above the current limit. This feature ensures the system integrity and safety.

{% hint style="info" %}
The current limit register operates independently of the [#operation-mode](#operation-mode "mention"), so it is not necessary to operate in current control mode to set a current limit for the motor operation.
{% endhint %}

#### Velocity Limit

The velocity limit is the upper limit for stopping motor operation. This value can be set by the user in terms of encoder ticks within 100 milliseconds time, in the range of the 0 - 65535. The motor that connected to the SMD will automatically stop if the encoder tick value within 100 milliseconds rises above the determined value. This feature allows the user to configure the system according to the project requirements.

{% hint style="warning" %}
The velocity limit feature applies only in the velocity control mode.
{% endhint %}

You can click for related functions to this register for [Python](https://github.com/Acrome-Smart-Motor-Driver/python-library?tab=readme-ov-file#set_velocity_limitself-id-int-vl-int) and [Arduino](https://github.com/Acrome-Smart-Motor-Driver/SMD-Arduino-Library?tab=readme-ov-file#red---setvelocitylimit) library.

#### Minimum - Maximum Position

The user can set the minimum and maximum position limits of the motor that connected to the SMD. This feature is essential for position control based applications both in terms of functionality and safety.

You can click for related functions to this register for [Python](https://github.com/Acrome-Smart-Motor-Driver/python-library?tab=readme-ov-file#set_position_limitsself-id-int-plmin-int-plmax-int) and [Arduino](https://github.com/Acrome-Smart-Motor-Driver/SMD-Arduino-Library?tab=readme-ov-file#red---setpositionlimits) library.

#### Position Control Setpoint

The position control setpoint is the value at which the motor is to be positioned. This value can be set by the user in the range of 0 - 65535, in terms of encoder ticks.

You can click for related functions to this register for [Python](https://github.com/Acrome-Smart-Motor-Driver/python-library?tab=readme-ov-file#set_positionself-id-int-sp-int) and [Arduino](https://github.com/Acrome-Smart-Motor-Driver/SMD-Arduino-Library?tab=readme-ov-file#red---setpoint) library.

#### Velocity Control Setpoint

The velocity control setpoint is the speed value to which the motor is wanted to be driven. This value can be set by the user in the range of 0 - 65535, in terms of RPM.

You can click for related functions to this register for [Python](https://github.com/Acrome-Smart-Motor-Driver/python-library?tab=readme-ov-file#set_velocityself-id-int-sp-int) and [Arduino](https://github.com/Acrome-Smart-Motor-Driver/SMD-Arduino-Library?tab=readme-ov-file#red---setpoint) library.

#### Torque Control Setpoint

The torque control reference is the value of the current to be drawn by the motor. This value can be set by the user in the range 0 - 5000 in mA (milliamperes).

You can click for related functions to this register for [Python](https://github.com/Acrome-Smart-Motor-Driver/python-library?tab=readme-ov-file#set_torqueself-id-int-sp-int) and [Arduino](https://github.com/Acrome-Smart-Motor-Driver/SMD-Arduino-Library?tab=readme-ov-file#red---setpoint) library.

#### 35. Present Position

The present position register provides the real-time position of the motor in terms of encoder ticks. It allows the user to enhance various position control based applications.

You can click for related functions to this register for [Python](https://github.com/Acrome-Smart-Motor-Driver/python-library?tab=readme-ov-file#get_positionself-id-int) and [Arduino](https://github.com/Acrome-Smart-Motor-Driver/SMD-Arduino-Library?tab=readme-ov-file#red---getposition) library.

#### 36. Present Velocity

The present velocity register provides a real-time measurement of the velocity of the motor, in terms of encoder ticks per 100 ms (milliseconds). It grants more control over the motor and enhances velocity control based applications.

You can click for related functions to this register for [Python](https://github.com/Acrome-Smart-Motor-Driver/python-library?tab=readme-ov-file#get_velocityself-id-int) library.

#### 37. Present Torque

The present torque register provides a real-time measurement of the current drawn by the motor in terms of mA (milliampers), it translates to a certain torque value in the motor control system. It is essential for various motor control applications which are certain torque values required.

You can click for related functions to this register for [Python](https://github.com/Acrome-Smart-Motor-Driver/python-library?tab=readme-ov-file#get_torqueself-id-int) and [Arduino](https://github.com/Acrome-Smart-Motor-Driver/SMD-Arduino-Library?tab=readme-ov-file#red---getcurrent) library.

***

### PID Parameter Registers

All parameters explained below can be set and changed by the user and also can be automatically determined by the PID auto-tune function.

1. #### Position - Velocity - Torque Control 'P' Gain

   The 'P' (proportional) gain parameter is the initial and most critical gain of the PID system. It is responsible for providing an immediate response to the current error of the system, and ensures that the system reaches to the desired setpoint.

   The 'P' gain can be set by the user for each control mode available.
2. #### Position  - Velocity - Torque Control 'I' Gain

   The 'I' (integral) gain parameter is the gain that improves the response of the system, and is generally used to solve the "steady-state error" by integrating the error and eliminating the offset that can be caused by sensor inaccuracies, friction, etc. It plays a corrective role in control systems.

   The 'I' gain can be set by the user for each control mode available.
3. #### Position - Velocity - Torque Control 'D' Gain

   The 'D' (derivative) gain parameter is the gain that helps the system to improve stability and damp the oscillations of the system output. It also suppresses noises that affects the control system.&#x20;

   The 'D' gain can be set by the user for each control mode available.
4. #### Position - Velocity - Torque Control Deadband

   The deadband value determines the threshold at which the system will not respond to the error. This situation generally solves the oscillation that caused by small errors by increasing the tolerance of the control system.

   The deadband value can be set by the user for each control mode available.
5. #### Position - Velocity - Torque Control Feed Forward

   The feed forward value is the value that adds up to the system output according to the input value. It acts as a pre-action to compensate for predicted errors before they impact output of the system in a unintended way.

   The feedforward value can be set by the user for each control mode available.
6. #### Position - Velocity - Torque Control Output Limit

   The output limit determines the maximum output limit that can be calculated by the PID controller system. It is used as a precaution to prevent the system from outputting a higher result than intended. This ensures that the system fulfils its purpose as defined by the user.

   The output limit value can be set by the user for each control mode available.

Each motor control mode has its own parameter set functions. The function names are different in the Python library according to the motor control mode, but in Arduino library the motor control mode is a parameter of a main parameter setting function. See the links below for detailed explanations:

For Python, [Position](https://github.com/Acrome-Smart-Motor-Driver/python-library?tab=readme-ov-file#set_control_parameters_positionself-id-int-pnone-inone-dnone-dbnone-ffnone-olnone) - [Velocity](https://github.com/Acrome-Smart-Motor-Driver/python-library?tab=readme-ov-file#set_control_parameters_velocityself-id-int-pnone-inone-dnone-dbnone-ffnone-olnone) - [Torque](https://github.com/Acrome-Smart-Motor-Driver/python-library?tab=readme-ov-file#set_control_parameters_torqueself-id-int-pnone-inone-dnone-dbnone-ffnone-olnone) parameter setting functions.

For Arduino, [parameter setting function](https://github.com/Acrome-Smart-Motor-Driver/SMD-Arduino-Library?tab=readme-ov-file#red---setcontrolparameters).

***

### <mark style="color:red;">SMD Module Registers</mark>

#### Buzzer

The buzzer register allows the user to control the [Buzzer Module](/electronics/add-on-modules/buzzer-module). It simply controlls the buzzer on the module, the user can also provide a frequency value for the buzzer to play.

You can click for related functions to this register for [Python](https://github.com/Acrome-Smart-Motor-Driver/python-library?tab=readme-ov-file#set_buzzerself-id-int-module_id-int-note_frequency-int) library.

#### IMU

The IMU (Inertial Measurement Unit) registers allow the user to check the roll and pitch values. The values are obtained from the [IMU Module](/electronics/add-on-modules/imu-module). These values are most commonly used in motor control systems and where balance is an important concern.

1. **Present Roll Register:**
   * This register stores the roll value, which is the rotation of the sensor around its longitudinal axis.
2. **Present Pitch Register:**
   * This register stores the roll value, which is the rotation of the sensor around its lateral axis.

You can click for related functions to these registers for [Python](https://github.com/Acrome-Smart-Motor-Driver/python-library?tab=readme-ov-file#imu-module) and [Arduino](https://github.com/Acrome-Smart-Motor-Driver/SMD-Arduino-Library?tab=readme-ov-file#red---getrollangle) library.

#### Ambient Light Intensity

The ambient light intensity register allows the user to obtain light intensity data from the [Ambient Light Sensor Module](/electronics/add-on-modules/ambient-light-sensor-module), in terms of Lux. It can be used in various applications where light sensitivity is a requirement.

You can click for related functions to this register for [Python](https://github.com/Acrome-Smart-Motor-Driver/python-library?tab=readme-ov-file#get_lightself-id-int-module_id-int) and [Arduino](https://github.com/Acrome-Smart-Motor-Driver/SMD-Arduino-Library?tab=readme-ov-file#red---getlight) library.

#### Button Status

The button status register allows the user to obtain the button data from the [Button Module](/electronics/add-on-modules/button-module). This register returns '1' if the button is pressed and '0' if it is not pressed at the moment. A button is the most used component in all kinds of projects.

You can click for related functions to this register for [Python](https://github.com/Acrome-Smart-Motor-Driver/python-library?tab=readme-ov-file#get_buttonself-id-int-module_id-int) and [Arduino](https://github.com/Acrome-Smart-Motor-Driver/SMD-Arduino-Library?tab=readme-ov-file#red---getbutton) library.

#### Present Distance

The present distance register allows the user to obtain the distance data from the [Ultrasonic Distance Sensor Module](/electronics/add-on-modules/ultrasonic-distance-sensor-module), in terms of cm (centimeters). Distance is especially important in mobile robot systems and many other types of projects.

You can click for related functions to this register for [Python](https://github.com/Acrome-Smart-Motor-Driver/python-library?tab=readme-ov-file#get_distanceself-id-int-module_id-int) and [Arduino](https://github.com/Acrome-Smart-Motor-Driver/SMD-Arduino-Library?tab=readme-ov-file#red---getdistance) library.

#### Joystick

The joystick registers contain the joystick X, joystick Y and joystick button data and allow to retrieve the data from the [Joystick Module](/electronics/add-on-modules/joystick-module). The user can acces this data and use for various purposes in applications and projects.

1. **Joystick X Register:**

   This register contains the X-axis data of the joystick mounted on the joystick module. This value varies in the range of \[-100, 100]. '-100' represents the left side of the joystick X-axis, '100' represents the right side of the joystick X-axis.
2. **Joystick Y Register:**

   This register contains the Y-axis data of the joystick mounted on the joystick module. This value varies in the range of \[-100, 100]. '-100' represents the lower side of the joystick Y-axis, '100' represents the upper side of the joystick Y-axis.
3. **Joystick Button Register:**

   This register contains the button status of the joystick button. This value is either '0' or '1', it is '1' when it is pressed. It can be used as a normal independent button in applications.

All of these registers are commonly used in applications that require navigational inputs for motor control or interfaces, etc. They allow the user to use the data in different project ideas, providing a much more dynamic control capability.

You can click for related functions to this register for [Python](https://github.com/Acrome-Smart-Motor-Driver/python-library?tab=readme-ov-file#joystick-module).

The functions for joystick are seperated in the Arduino library, so the functions are [joystick-X](https://github.com/Acrome-Smart-Motor-Driver/SMD-Arduino-Library?tab=readme-ov-file#red---getjoystickx), [joystick-Y](https://github.com/Acrome-Smart-Motor-Driver/SMD-Arduino-Library?tab=readme-ov-file#red---getjoysticky) and [joystick button](https://github.com/Acrome-Smart-Motor-Driver/SMD-Arduino-Library?tab=readme-ov-file#red---getjoystickbutton).

#### QTR

The QTR (Reflectance Sensor) registers contain left, middle and right QTR data and allow to get the data from the [Reflectance Sensor Module](/electronics/add-on-modules/reflectance-sensor-module).

The data from the module comes as an array, ordered as left - middle - right QTR sensors. QTR data is often used in projects such as line following, maze solving robots, etc. The user is free to use the reflectance data coming from the QTR sensors in any project that needs to differentiate the contrast between two colors, as each color reflects light differently.

You can click for related functions to this register for [Python](https://github.com/Acrome-Smart-Motor-Driver/python-library?tab=readme-ov-file#get_qtrself-id-int-module_id-int) and [Arduino](https://github.com/Acrome-Smart-Motor-Driver/SMD-Arduino-Library?tab=readme-ov-file#red---getqtr) library.

## <mark style="color:red;">Protocol Overview</mark>

The protocol is working on a UART interface at up to 9M baud. Each package transmitted from the master device needs to be followed by a delay of minimum 1-byte-long of the selected baud rate at the time. However, a 2-byte-long delay is recommended to tolerate any possible timing issues since UART is an asynchronous communication interface.

Each package must have a preliminary information part before data bytes and an MPEG2 CRC32 value at the end of the package. These values are disclosed in Table 1. The whole communication protocol is based on little-endian architecture.

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

**Note:** If the user wants to broadcast a command to all the slave devices in the communication line, Device ID field should set to 0xFF. When a broadcast massage is transmitted, no reply will be received from any of the Actuators on the bus.

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

**Ping Command**

When the Actuator receives a package with a ping command, it will reply to the user with a ping package. The only difference between two packages is the 4th byte of the package that has been sent to the Actuator is the status register of the device.

**Write Command**

When the user wants to change the registers of the Actuator, the user should send a package that contains information about the required register pointers and register values with this command. The user should place pointer values and register data in the data field of the package template according to the given example below.

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

**Read Command**

When the user wants to read the registers of the Actuator, the user should send a package that contains information about the required register pointers with this command. The user should place pointer values in the data field of the package template according to the given example below.<br>

<figure><img src="/files/8DkbTJNIgOmclgBCK5LE" alt=""><figcaption></figcaption></figure>

**EEPROM Write Command**

When the user wants to save already-written data to the non-volatile memory of the Actuator, should send a package with this command. Actuators do not respond this command. Execution of this command takes about 300ms since writing to flash memory is a relatively slow operation. Keeping torque output disabled is recommended but not mandatory while sending this command.

**Reboot Command**

When the user wants to reboot the device, should send a package with this command. The device will be rebooted immediately and all parameters on the RAM will be replaced with the values that stored on the EEPROM.

**Factory Reset Command**

When the user wants to replace all parameters with the default ones, should send a package with this command. When this command is sent, Actuator is going to reset all parameters to their out-of-factory values, including ones that are saved to the EEPROM.

#### **Error Clear Command**

When the user wants to clear any errors on the Actuator, should send a package with this command. Users should set the status field of the package with the flags of the errors that will be cleared. To clear all errors, the user should set the status field to 0xFF. For details of error flags, see the Status register description.

**ACK Flag**

When the user wants to get a reply from Actuator after write command, should set the 7th bit of the command register. If the user sends ACK, the Actuator will return all of its parameters as the reply. Ping packages always get replies from the Actuators.

## <mark style="color:red;">PID Autotuner</mark>

PID (Proportional-Integral-Derivative) control is a widely employed algorithm in diverse control systems, regulating variables like temperature, flow, pressure, and more. Autotuning, a crucial aspect of PID control, involves automatically adjusting the controller's parameters to enhance its performance. The benefits of autotuning PID controllers are numerous and impactful:

1. **Improved Control Performance:** Autotuning optimizes the PID controller's parameters, including proportional, integral, and derivative gains. This optimization results in a controller that can achieve faster and more precise control of the process variable. By fine-tuning these parameters automatically, the system can respond more effectively to changes in the controlled variable.
2. **Reduced Setup Time:** Autotuning eliminates the need for manual tuning, significantly reducing the time and effort required to set up a PID controller. Instead of relying on trial-and-error methods, autotuning algorithms systematically adjust the controller's parameters, streamlining the setup process and making it more efficient.
3. **Better Response to Process Changes:** Autotuning equips PID controllers to adapt dynamically to changes in the controlled process, such as variations in load or operating conditions. This adaptability ensures that the controller remains stable and responsive, minimizing the need for frequent manual adjustments. The ability to respond swiftly to process changes contributes to the overall robustness of the control system.
4. **Enhanced Stability and Efficiency:** The combined effect of improved performance, reduced setup time, and adaptability to process changes contributes to the overall stability and efficiency of the control system. Autotuning helps maintain control in a variety of operating conditions, leading to more reliable and effective regulation of the controlled variable.

In summary, autotuning PID controllers play a vital role in optimizing control system performance. By automating the parameter tuning process, these controllers achieve faster response times, reduce setup efforts, and adapt seamlessly to dynamic process conditions. The result is a more stable, efficient, and robust control system capable of delivering precise and reliable control across a range of applications.

### Minimum output required for motor motion

The minimum voltage requirement for an electric motor is a critical consideration in ensuring proper startup and continuous operation. The minimum voltage is essential for initiating the motor's rotation and sustaining the necessary current flow to generate the magnetic field crucial for producing torque.

Here are key points to elaborate on this concept:

1. **Initiating Rotation:**
   * The electric motor relies on an initial surge of current to create the magnetic field required for torque generation. This is particularly crucial during the startup phase when the motor transitions from a standstill to rotation.
2. **Generating Torque:**
   * To produce torque, the motor must maintain a sufficient magnetic field. This is achieved by ensuring that the current flowing through the motor is at an adequate level. Below a certain voltage threshold, the current may be insufficient, leading to a failure to generate the necessary magnetic field, causing the motor to either not start or stall if already running.
3. **Preventing Stalling:**
   * In the case of an already running motor, if the supplied voltage drops below the minimum required level, the motor may stall. Stalling occurs when the motor cannot overcome the load or friction opposing its rotation due to insufficient current.
4. **Ensuring Reliable Operation:**
   * To prevent these undesirable scenarios, it is crucial to provide the motor with a voltage equal to or higher than the specified minimum. This ensures that the motor receives the necessary current to establish and sustain the magnetic field, allowing for reliable and efficient operation.

In summary, the minimum voltage requirement for an electric motor is a fundamental parameter for ensuring proper functionality, preventing stalling, and promoting reliable operation. Adhering to the specified minimum voltage guidelines is essential for optimizing motor performance and longevity in various applications.

### Cohen Coon

The Cohen-Coon tuning method, developed by Norm Cohen and Bernard Coon in the 1960s, is another valuable approach for autotuning PID controllers. Like the Ziegler-Nichols method, Cohen-Coon relies on a step response test to determine optimal proportional, integral, and derivative gains for the controller. This method is considered more conservative than Ziegler-Nichols, prioritizing stability.

Here are the key steps involved in the Cohen-Coon method:

1. **Maximum Speed Calculation:**
   * Calculate the maximum speed that the motor can reach. It's crucial to operate at half power to avoid damage to the motor and the system.
2. **Dead Time (td) Calculation:**
   * Determine the dead time (td) in the system. Dead time is the time delay between a change in the controller output and the corresponding change in the process variable (PV).
3. **Time Constant (𝜏) Calculation:**
   * Calculate the time constant (𝜏), representing the time difference between the intersection at the end of dead time and the PV reaching 63% of its total change. This is a critical parameter in determining the system dynamics.
4. **Gp Calculation:**
   * Calculate the process gain (Gp), which is the change in the PV divided by the change in the controller output (CO), both expressed as percentages. This quantifies the sensitivity of the system to changes in the controller output.
   * Gp = change in PV \[in %] / change in CO \[in %]

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

5. **Set Controller Gains:**
   * Set the proportional, integral, and derivative gains of the PID controller to the recommended values based on the Cohen-Coon method.

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

The Cohen-Coon method is known for being more conservative compared to Ziegler-Nichols, resulting in a controller that is generally more stable. However, it's essential to note that while these tuning methods provide a good starting point, fine-tuning may still be required based on specific system characteristics and performance requirements. Ultimately, the choice between Ziegler-Nichols and Cohen-Coon depends on the desired trade-off between aggressive response and stability in a given control system.

### Autotuner Method

The users can use the Cohen-Coon PID Autotuner Method to easily determine the coefficients of the PID for the optimal motor control.

Here is a summary of the autotuner method and its configuration:

**Cohen-Coon Method**

* **Autotuner Method Register Setting:** 0x03
* **Description:** Opting for the Cohen-Coon method instructs the Actuator to autotune its control parameters according to the Cohen-Coon method. This method, like Ziegler-Nichols, often involves a step response test but is generally considered more conservative, emphasizing stability. Users should set the Autotuner method register to 0x03 to initiate the Cohen-Coon tuning process.

Before selecting either method, users must ensure that both torque and the Autotuner are enabled. This ensures that the Actuator is ready to undergo the autotuning process and that the resulting parameters align with the chosen method.

By providing users with a choice between Ziegler-Nichols and Cohen-Coon methods, the Actuator accommodates different preferences and requirements for tuning its control parameters, allowing for customization based on the specific needs of the control system.

## SMD Red Hardware Specifications

Here is a table of Hardware Specifications including Microcontrol Unit, Peripherals, Programmer, I/O Port Pins, Communication Ports, LEDs and Buttons, Input Power Source, Power Fuses and Dimensions.

<figure><img src="/files/68OzrcbmzORjr6RVZf3Q" alt=""><figcaption><p>SMD Red Hardware Specifications</p></figcaption></figure>

Setup File:

{% file src="/files/1cZH04euEUHbJ0n4lmHS" %}

#### Step Files:

{% file src="/files/32Bc31SarqEszYLja3dQ" %}


# SMD Blue

The Stepper DC Motor Driver

The **Acrome SMD Blue** is a compact and powerful motion control device designed specifically for driving **stepper motors** with high precision and stability. Developed by **Acrome**, it enables smooth, reliable motion control for applications that require accurate positioning, such as **robotic arms, CNC systems, 3D printers**, and various **automation platforms**.

With support for **step, direction, and enable signals**, SMD Blue ensures compatibility with a wide range of external stepper motor drivers. It communicates via **RS-485** and features **RJ-11 ports**, allowing users to connect a variety of **plug-and-play add-on modules** such as distance sensors, joystick controllers, RGB LEDs, and more—without the need for complex wiring or configuration.

SMD Blue is compatible with both **visual programming tools like SMD Blockly** and **text-based environments such as Python**, making it ideal for students, educators, researchers, and developers alike.

Whether you're building a precise linear motion system or developing advanced motion control algorithms, **SMD Blue delivers the flexibility, performance, and modularity you need for stepper-based motion systems.**

<figure><img src="/files/roXm4W5FKmEFSd7VfbGs" alt=""><figcaption><p>Top of the Board</p></figcaption></figure>

<figure><img src="/files/zU5LjUJHp1zyakDkTzmc" alt=""><figcaption><p>Bottom of the Board</p></figcaption></figure>


# SMD Green

The Brushless DC Motor Driver

The **Acrome SMD Green** is a high-efficiency and compact smart driver module, purpose-built for controlling **Brushless DC (BLDC) motors** with precision, stability, and responsiveness. Engineered by **Acrome**, SMD Green brings advanced motion control to a wide range of applications — from mobile robots and electric vehicles to precision tools and autonomous platforms.

Supporting **hall-sensor-based commutation**, **speed control**, and **torque regulation**, SMD Green delivers smooth and dynamic motor operation, while ensuring accurate feedback and reliable control even under demanding conditions. It communicates over **RS-485** using Acrome’s modular protocol and offers **RJ-11 and RJ-45** connectors for seamless integration with other SMD modules and motor drivers.

Thanks to its plug-and-play architecture, SMD Green allows quick connection to compatible **add-on modules** such as distance sensors, encoders, joysticks, and LEDs — eliminating the hassle of manual wiring or signal routing. With **onboard power pass-through**, multiple SMDs can be daisy-chained to build larger systems with minimal cable complexity.

SMD Green is fully compatible with both **visual programming environments** like **SMD Blockly**, and **text-based platforms** such as Python or Arduino. This makes it ideal for **educational labs**, **researchers**, and **engineers** looking to experiment or deploy brushless motor solutions efficiently.

Whether you're building a fast-response mobile robot or a precision-controlled brushless drive, **SMD Green** offers the reliability, modularity, and software integration required for professional-grade brushless motor control.


# Gateway Modules

Acrome's **Gateway Modules** are communication bridges designed to enable seamless interaction between user devices (such as PCs or microcontrollers) and Acrome’s **Smart Motion Devices (SMDs)**. These modules act as **protocol translators**, converting signals from USB or UART interfaces into **RS-485**, the robust and noise-resistant protocol used by all SMDs.

Thanks to these gateways, users can develop and control motion systems using a variety of platforms—from full-featured PCs to simple Arduino boards—without dealing with complex wiring or low-level communication handling.

Acrome provides multiple gateway solutions, each tailored to different user needs and hardware environments.

## [USB Gateway Module](/electronics/gateway-modules/usb-gateway-module)

The USB Gateway Module allows **computers (Windows/macOS/Linux)** to connect directly to SMDs via a **USB-to-RS-485** interface. It is the most commonly used gateway for programming and debugging motion applications using platforms like **Python** or **SMD Blockly**.

## [Arduino Gateway Module](#arduino-gateway-module)

The Arduino Gateway Module is designed to enable **Arduino-compatible microcontrollers** to interface with SMDs using **UART (TX/RX) communication**. It converts UART signals to RS-485, allowing open-source Arduino platforms to control Acrome motion modules in real time.

## Why Use Gateway Modules?

* **Protocol Conversion**: Automatically convert USB or UART to RS-485.
* **Modular Integration**: Easily connect and control multiple SMDs through a single gateway.
* **Cross-Platform**: Compatible with PCs, embedded systems, and microcontrollers.
* **Plug & Play**: RJ-11 connectors for quick and error-free hardware setup.
* **Reliable Communication**: RS-485 ensures stable data transfer even in noisy environments.

## Use Cases

| Platform            | Gateway Module         | Application Example                                                      |
| ------------------- | ---------------------- | ------------------------------------------------------------------------ |
| Windows/macOS/Linux | USB Gateway Module     | Programming DC motors and reading distance sensors via Python or Blockly |
| Raspberry Pi        | USB Gateway Module     | Controlling RGB LED modules or reacting to button/joystick inputs        |
| Arduino             | Arduino Gateway Module | Creating interactive robot demos using ultrasonic sensors and LEDs       |


# Arduino Gateway Module

The **Arduino Gateway Module** is a custom-designed interface that enables **Arduino-compatible boards** to communicate with Acrome's **Smart Motion Devices (SMDs)**. Acting as a protocol bridge, it translates serial communication signals from the Arduino into a format compatible with Acrome's RS-485-based ecosystem.

This gateway allows developers, educators, and researchers to use widely adopted Arduino platforms to control SMD modules such as motors, servos, distance sensors, LEDs, and more—unlocking the flexibility of open-source development within a modular motion control framework.

Whether you are building an automation prototype or teaching mechatronics using Arduino boards, the Arduino Gateway Module provides a **simple, reliable, and scalable interface** for motion and sensor integration.

### **Photos**

![](/files/SrcOLF9cxX6X7cbB15gq)          ![](/files/0fu1ShU8EKxUy4h0rx5s)

![](/files/BKHwhzgTt0D22zw68Kbo)          ![](/files/v9PfNYkP8DJ5Qkbi35Xi)

## Technical Specifications

<table><thead><tr><th width="240.39996337890625">Feature</th><th width="474">Description</th><th data-hidden></th></tr></thead><tbody><tr><td>Communication</td><td>UART (Serial TX/RX to RS-485 converter)</td><td></td></tr><tr><td>Compatible Boards</td><td>Arduino Uno, Mega, Leonardo, and similar</td><td></td></tr><tr><td>Power Supply</td><td>5V (powered from Arduino or external supply)</td><td></td></tr><tr><td>SMD Interface</td><td>RJ-11 connector (RS-485 to SMDs)</td><td></td></tr><tr><td>Communication Speed</td><td>9600, 57600, 115200(default baudrate), 921600, 1115200, 3000000 bps</td><td></td></tr><tr><td>Protocol Translation</td><td>UART ↔ RS-485 (for Acrome device support)</td><td></td></tr><tr><td>Status Indicators</td><td>TX / RX LED indicators</td><td></td></tr><tr><td>Form Factor</td><td>Shield or cable-based module</td><td></td></tr></tbody></table>

### **Renders**

![](/files/OKgvWLUGkjSFXPcGtibv)          ![](/files/Xkpiw37l5CwLetn7q6Mi)

**Manual File:**

{% file src="/files/5nyprvsIo1F3QDcFAnpv" %}

**Step File:**

{% file src="/files/IoJWLgA0BbKRnBRDxvB6" %}


# USB Gateway Module

The **USB Gateway Module** is a compact hardware interface designed to establish seamless communication between a computer and Acrome’s Smart Motion Devices (SMDs). Acting as a **bridge between the digital and physical worlds**, it enables reliable, high-speed serial communication through a standard USB connection.

At its core, the USB Gateway functions as a **USB-to-UART/RS-485 converter**, translating commands from the computer into a format that SMD modules can understand—and vice versa. This makes it a **critical component** for developing real-time motion control applications.

The module connects to an SMD via a **standard RJ-11 cable**, simplifying the wiring and setup process. Whether you're controlling motors, reading sensors, or executing coordinated motion commands, the USB Gateway ensures **low-latency, robust communication**, even in continuous operation.

To assist with debugging and user feedback, the module includes **built-in TX and RX LEDs**. These indicators provide real-time visualization of data transfer, making it easy to verify communication status at a glance.

Whether you're building an educational demo, a research-grade automation platform, or a personal robotics project, the USB Gateway Module is your reliable link between software logic and physical motion.

### Photos

![](/files/SpyyyH3VUDsQsRrUazjV)          ![](/files/7awJn7aIW5KT49gtR4JD)

&#x20;                                         ![](/files/WlOFyxCTmEGRp5wZdadz)

## Technical Specifications

<table><thead><tr><th width="210.39996337890625">Feature</th><th width="449.800048828125">Description</th><th data-hidden></th></tr></thead><tbody><tr><td>Communication</td><td>USB 2.0 (Serial over USB)</td><td></td></tr><tr><td>Supported OS</td><td>Windows, macOS, Linux</td><td></td></tr><tr><td>Baud Rate</td><td>9600, 57600, 115200(default baudrate), 921600, 1115200, 3000000 bps</td><td></td></tr><tr><td>Protocol</td><td>UART (used to communicate with SMD modules), RS-485</td><td></td></tr><tr><td>Power Source</td><td>USB powered</td><td></td></tr><tr><td>Plug &#x26; Play</td><td>Yes</td><td></td></tr><tr><td>Compatibility</td><td>Compatible with all Acrome SMD modules</td><td></td></tr><tr><td>LED Indicators</td><td>TX / RX communication activity</td><td></td></tr></tbody></table>

### Render

<figure><img src="/files/DIxnFrorjVtnyW74xV5n" alt="" width="563"><figcaption></figcaption></figure>

**Manual File:**

{% file src="/files/o5ob71CZA3ArQSlkCDD9" %}

**Step File:**

{% file src="/files/FYM8aoqsWN5skUp97oDb" %}


# Electrical Motors

Electric motors form the foundation of any motion control or robotic system. At Acrome, we specialize in two primary motor technologies—Brushed DC Motors and Stepper Motors—each selected for their unique strengths in dynamic motion and precise positioning. These motor types are optimized for a wide range of applications, from mobile robotic platforms to high-precision automation tasks in education, research, and industry.

## Brushed DC Motors

Brushed DC motors are commonly used for applications that require continuous rotation, variable speed, and real-time feedback via encoders. These motors are favored for their simplicity, responsiveness, and ease of integration into educational and prototyping platforms.

### Key Features:

* Speed and direction control via duty cycle
* Encoder-based feedback for precision control
* Compact and cost-effective
* Ideal for mobile robots, wheels, and motion demos

### Integration:

* Controlled using **SMD Red** controller
* Encoder feedback supported via onboard inputs
* Compatible with **SMD Blockly**, **Python SDK**, and **Flutter App**

### Example Applications:

* Two-wheel differential drive robots
* Closed-loop speed control experiments
* Obstacle avoidance using motor + distance sensor

## Stepper Motors

Stepper motors are used in systems that require **high-precision positioning**. These motors rotate in discrete steps, offering accurate control without the need for feedback sensors. Stepper motors are ideal for educational mechatronics projects, CNC machines, and 3D printers.

### Key Features:

* Open-loop control with precise step angles
* Reliable for repeatable motion tasks
* Microstepping support for smooth operation
* Suitable for linear or rotary motion

### Integration:

* Controlled using **SMD Blue** controller
* Step/Direction/Enable pins used for control
* Compatible with **Arduino Gateway**, **Python SDK**, and advanced robotic frameworks

### Example Applications:

* Linear actuator control with set distances
* Multi-axis motion systems (e.g., XY plots)
* Pick-and-place mechanisms


# Brushed DC Motors (BDC)

The **Acrome 12V Brushed DC Motor** with **Built-in Encoder** is a reliable and efficient motor designed for robotics, automation, and industrial applications. With a **100 RPM** speed and an **integrated encoder**, it provides precise motion control and feedback, making it ideal for closed-loop systems. Its **compact size**, **durability**, and **high torque output** make it a great choice for various electromechanical projects.

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

## **Technical Specifications**

| **Specification**               | **Value**                                        |
| ------------------------------- | ------------------------------------------------ |
| **Product Number**              | 4755                                             |
| **Nominal Voltage**             | 12 V                                             |
| **Gear Ratio**                  | \~102.08:1                                       |
| **No-Load Speed**               | \~100 RPM                                        |
| **No-Load Current**             | \~200 mA                                         |
| **Stall Torque**                | \~34 kg·cm (≈470 oz·in)                          |
| **Stall Current**               | \~5.5 A                                          |
| **Rated Power**                 | \~8 W                                            |
| **Max Efficiency Power Output** | \~3.8 W @ \~87 RPM                               |
| **Max Efficiency**              | \~44% at \~42 kg·mm                              |
| **Encoder Resolution**          | 64 CPR on motor shaft → 6533 CPR on output shaft |
| **Shaft Type**                  | D-shaped, 6 mm diameter, 16 mm length            |
| **Dimensions**                  | Ø37 mm × \~73 mm length                          |
| **Weight**                      | \~210 g                                          |


# Stepper DC Motors

**Introduction** ACROME's Stepper DC Motor combines the precise positioning of stepper motors with the continuous rotation capability of DC motors. This hybrid solution offers unique advantages for applications requiring both precision and sustained motion.

<figure><img src="/files/2Trp5DWwEUKSgm09HEIA" alt=""><figcaption></figcaption></figure>

### **Key Features**

* Dual-mode operation (stepper and DC modes)
* Position holding capability when stopped
* Smooth continuous rotation at variable speeds
* Integrated encoder feedback (on select models)
* Programmable current limits for both modes

### **Technical Specifications**

* Voltage Range: 12-36V DC
* Phase Current: Up to 3A (stepper mode)
* Continuous Current: Up to 5A (DC mode)
* Step Resolution: Configurable from full-step to 1/32 microstepping
* Communication Interfaces: UART, I2C, and STEP/DIR inputs
* Built-in Motion Controller: Supports trapezoidal and S-curve profiles

### **Wiring Configuration**

1. Power Connections:
   * Main Power: 12-36V to VCC and GND
   * Logic Power: 5V to VDD (optional for standalone operation)
2. Motor Connections:
   * 4-wire bipolar configuration (A+, A-, B+, B-)
3. Control Interfaces:
   * STEP and DIR pins for pulse control
   * PWM and DIR for DC mode speed control
   * Serial ports for advanced configuration

### **Configuration Software**

ACROME provides Windows/Linux configuration tools for:

* Current limit adjustment
* Microstepping setup
* Acceleration profiles
* PID tuning for DC mode
* Saving configurations to onboard EEPROM

### **Protection Features**

* Overcurrent protection (both modes)
* Thermal shutdown
* Undervoltage lockout
* Short-circuit protection
* Stall detection (with auto-recovery)

### **Applications**

* CNC machines requiring both precise positioning and continuous motion
* Automated test equipment
* Hybrid robotics systems
* Conveyor systems with positioning requirements
* Camera sliders and pan-tilt mechanisms


# Brushless DC Motor (BLDC)


# Linear Actuator with Feedback

This linear actuator is designed for **precise linear motion** in compact automation applications. Equipped with an internal **potentiometer for position feedback**, it allows for closed-loop control systems. The 75 lbs (≈ 333 N) force rating makes it suitable for light-to-medium load applications such as robotic arms, adjustable platforms, and smart enclosures.

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

## Specifications

| Parameter               | Value                             |
| ----------------------- | --------------------------------- |
| **Force**               | 75 lbs (333 N)                    |
| **Stroke Length**       | Options: 2", 4", 6", 8", 10", 12" |
| **Speed (No Load)**     | 0.6 in/s (≈15 mm/s) at 12 V       |
| **Input Voltage**       | 12 V DC                           |
| **Rated Current**       | \~2 A                             |
| **Stall Current**       | \~3 A                             |
| **Feedback Type**       | 10 kΩ Linear Potentiometer        |
| **Position Resolution** | \~0.5 mm                          |
| **Duty Cycle**          | 20%                               |
| **IP Rating**           | IP54                              |
| **Gear Ratio**          | 20:1                              |
| **Connector**           | 6-wire cable (motor + pot)        |

## Wiring

| Wire Color | Function                     |
| ---------- | ---------------------------- |
| Red        | Motor +                      |
| Black      | Motor –                      |
| White      | Potentiometer GND            |
| Green      | Potentiometer Signal (wiper) |
| Yellow     | Potentiometer VCC (\~5V)     |
| Blue       | (Optional) Not used          |

## Dimensions

* **Body Length (retracted):** \~105 mm + stroke
* **Fully Extended Length:** Retracted length + stroke
* **Mounting Holes:** 6.3 mm diameter clevis ends
* **Weight:** \~500 g (varies by stroke)

## Use Cases

* Robotics (arm extension/retraction)
* Smart furniture (adjustable desk legs, drawers)
* Lab automation systems
* Controlled enclosure doors or hatches


# Add-on Modules

The SMD family stands out for its modular, daisy-chained and rich electronics. Flexibility is as important as modularity, and 10 different types of add-on modules that can be connected in any order. All these different types of sensors ensure that the users have all the possibilities to turn their ideas into projects.

## ID Config

All add-on modules have an **ID Config** part on their boards. The **ID Config** feature allows the system to handle more than one module of the same type. This feature comes in handy when the user wants to use up to 5 of the same module. For example, more than one Ultrasonic Distance Sensor Module or Reflectance Sensor Module can be used in mobile robots especially such as line following robots or object avoidance robots, in order to prevent collisions.

The ID numbers are listed below the ID connector pins.

<figure><img src="/files/wMHFPcTAs2soKbtArui5" alt=""><figcaption><p>ID Config Pins</p></figcaption></figure>

{% hint style="info" %}
The ID of each module is "1" as default, even if there is no jumper on the ID Config area.
{% endhint %}

These pins can be connected in vertical doubles to select the desired ID for the module, with a 2 pin jumper. The name of the module will change as the ID changes, such as `Distance_3` for [Ultrasonic Distance Sensor Module](/electronics/add-on-modules/ultrasonic-distance-sensor-module) or `Light_5` for [Ambient Light Sensor Module](/electronics/add-on-modules/ambient-light-sensor-module).

## RJ-45 Connectors

The RJ-45 connectors on add-on modules offer many possibilities for many scenarios. The RJ-45 cable can provide both power and data between SMD and add-on modules, it perfectly solves the cable tangle, solving two problems at once.

RJ-45 connectors make it easy to connect add-on modules back to back. In addition, the click-lock feature keeps the connection secure both in terms of data and mechanically. The RJ-45 cables in the SMD product family are available in a variety of lengths. These are 7.5 cm, 20 cm and 35 cm RJ-45 cables. Different lengths provide different options for building a system. Also, RJ-45 cables are flat, making them easier to pass through any place.

## Input Add-on Modules

Input sensors are the most important sensors when it comes to understanding and interacting with the environment. Input sensors are the majority in the world of sensors due to the need of continuous data collection and monitoring. Any kind of system can be controlled in a reasonable and stable way thanks to the input sensors.

{% hint style="info" %}
There are <mark style="color:red;">**7 input add-on modules**</mark> in the SMD family.
{% endhint %}

<table data-view="cards"><thead><tr><th align="center"></th><th data-hidden data-card-cover data-type="image">Cover image</th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td align="center">Ambient Light Sensor Module</td><td><a href="/files/GxZw1elwhyUZOuTL7r2U">/files/GxZw1elwhyUZOuTL7r2U</a></td><td><a href="/pages/fKIStzOqDX1QM9Q5U4To">/pages/fKIStzOqDX1QM9Q5U4To</a></td></tr><tr><td align="center">Button Module</td><td><a href="/files/NwJy00OnEKajteECiXc2">/files/NwJy00OnEKajteECiXc2</a></td><td><a href="/pages/oOC231qxGDO8Pvwwgte3">/pages/oOC231qxGDO8Pvwwgte3</a></td></tr><tr><td align="center">IMU Module</td><td data-object-fit="contain"><a href="/files/SL361Quv1YZ7uPoIuuOf">/files/SL361Quv1YZ7uPoIuuOf</a></td><td><a href="/pages/o5qeysTK43wnLI6R2gLr">/pages/o5qeysTK43wnLI6R2gLr</a></td></tr><tr><td align="center">Potentiometer Module</td><td><a href="/files/fU21J6VJDYI7MaTaiqqF">/files/fU21J6VJDYI7MaTaiqqF</a></td><td><a href="/pages/ZuwnI7S2beAl4mWizEHL">/pages/ZuwnI7S2beAl4mWizEHL</a></td></tr><tr><td align="center">Reflectance Sensor Module</td><td><a href="/files/4sDo8VisGb86dZs8xG8g">/files/4sDo8VisGb86dZs8xG8g</a></td><td><a href="/pages/EODZpgCAsIqmvM0spIyP">/pages/EODZpgCAsIqmvM0spIyP</a></td></tr><tr><td align="center">Ultrasonic Distance Sensor Module</td><td data-object-fit="contain"><a href="/files/aY7JJXk85Ns1cRShmaRF">/files/aY7JJXk85Ns1cRShmaRF</a></td><td><a href="/pages/SdX9Ord2jwYmyck6NgNF">/pages/SdX9Ord2jwYmyck6NgNF</a></td></tr><tr><td align="center">Joystick Module</td><td data-object-fit="contain"><a href="/files/RRMlwIoDZPLgYRHDi81W">/files/RRMlwIoDZPLgYRHDi81W</a></td><td><a href="/pages/pyScGUU6EvcWoMlUCaFu">/pages/pyScGUU6EvcWoMlUCaFu</a></td></tr></tbody></table>

### Output Add-on Modules

Output sensors are essential for physically interacting with the environment. They generally take a system input from the input sensors or an input created by the user through software. Any electronic device that has physically sensable outputs is an output sensor.

{% hint style="info" %}
There are <mark style="color:red;">**3 output add-on modules**</mark> in the SMD family.
{% endhint %}

<table data-view="cards"><thead><tr><th align="center"></th><th data-hidden data-card-cover data-type="image">Cover image</th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td align="center">Buzzer Module</td><td><a href="/files/Elm40Crhv83xfwg73jje">/files/Elm40Crhv83xfwg73jje</a></td><td><a href="/pages/liJOj0hVzlqVel3FXGFI">/pages/liJOj0hVzlqVel3FXGFI</a></td></tr><tr><td align="center">RGB LED Module</td><td><a href="/files/5fAf4F0JAoq8vQ2iBkUE">/files/5fAf4F0JAoq8vQ2iBkUE</a></td><td><a href="/pages/NCGxgyTCYPkOn7i8uCyE">/pages/NCGxgyTCYPkOn7i8uCyE</a></td></tr><tr><td align="center">Servo Module</td><td><a href="/files/M72jdpkGgRWBpCBjp6zR">/files/M72jdpkGgRWBpCBjp6zR</a></td><td><a href="/pages/WaBjA3nFQ8lfF39bKINx">/pages/WaBjA3nFQ8lfF39bKINx</a></td></tr></tbody></table>

Due to the definition of output sensors, the 100 RPM brushless DC motor is also an output sensor, even though it is not an add-on module.

{% content-ref url="/pages/bE5XOmbmqkcEeHfpsfHN" %}
[Shops](/help/shops)
{% endcontent-ref %}


# Ambient Light Sensor Module

<figure><img src="/files/uvuDsdCnrwqqhMqe47kj" alt=""><figcaption><p>Ambient Light Sensor Module</p></figcaption></figure>

Here is the [datasheet of the ambient light sensor (IN-S32GTLS)](https://www.inolux-corp.com/datasheet/IR/Sensor/Ambient%20Light%20Sensor/IN-S32GTLS_V1.0.pdf) on the module.

<mark style="color:red;">The Ambient Light Sensor Module</mark> is a light-sensitive measurement device suitable for a variety of applications, including educational settings and mobile robotics. It can be used in scenarios where light measurement is required, such as in Braitenberg robots, energy-saving light systems, and automatic brightness adjusting systems. It is an ideal tool for creating interactions connected to environmental changes.

The light measurement is expressed in lux and is processed by a resistance calculation inside the microcontroller.

<figure><img src="/files/8eDezp3KXkmYWt2SufCk" alt=""><figcaption></figcaption></figure>

#### Step Files:

{% file src="/files/fbCRmTPK45zPn1sIWzxt" %}

**Here are some of the sample projects that include this module:**

<details>

<summary><a href="/pages/YlM3cOhzbmqDllKRav2e">Autonomous Lighting</a>  (including: <a href="/pages/SaDm6XqjUUnmIkF4QTsk">SMD RED</a> + <a href="/pages/NCGxgyTCYPkOn7i8uCyE">RGB LED Module</a> + <a href="/pages/fKIStzOqDX1QM9Q5U4To">Ambient Light Sensor Module</a>)</summary>

The Python-based “Automatic LED Turn On/Off” application integrates an SMD Motor Driver, an add-on LED Module, and an Ambient Light Sensor Module to form an intelligent lighting system. This project automatically adjusts the LED’s state according to ambient light conditions, offering an energy-efficient solution suitable for diverse environments.

</details>

<details>

<summary><a href="/pages/ECUu5pgXchI0TyzJTyMV">Chrome Dino Game Player</a>  (including: <a href="/pages/SaDm6XqjUUnmIkF4QTsk">SMD RED</a> + <a href="/pages/NCGxgyTCYPkOn7i8uCyE">RGB LED Module</a> + <a href="/pages/fKIStzOqDX1QM9Q5U4To">Ambient Light Module</a> + 100 RPM BDC Motor with Encoder)</summary>

The innovative Python project, "Chrome Dino Game Player," merges hardware and software to elevate the classic Chrome Dino Game. Through the integration of an SMD Motor Driver, a DC Motor, and an add-on Ambient Light Module, this project aims to deliver a dynamic and immersive gaming experience.

</details>

{% hint style="info" %}
Ready to integrate? You can purchase the <mark style="color:red;">**The Ambient Light Sensor Module**</mark> directly from our [Online Store](https://www.robotshop.com/products/acrome-ambient-light-sensor-add-on-module-acrome-smd-products). Worldwide shipping is available for engineering samples and production batches.
{% endhint %}


# Button Module

<figure><img src="/files/LcPsjdsRXm7qYGKhih3S" alt=""><figcaption><p>Button Module</p></figcaption></figure>

Here is the [datasheet of the button (TS04)](https://www.cuidevices.com/product/resource/ts04.pdf) on the module.

<mark style="color:red;">The Button Module</mark> offers direct interaction with electronics through physical touch, providing a simple and effective solution for creating interactions in projects, especially in educational purposes. For instance, it can be used to turn on an LED while the button is pressed. Additionally, it can be used in complex projects as an interaction device.

The button on the module physically completes the circuit when it is pressed, sending a '1' data to the microcontroller and a '0' data when not pressed. This process allows the button to interact with the system as intended.

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

#### Step Files:

{% file src="/files/GhTJ88iwrgvT43hbeq6J" %}

**Here are some of the sample projects that include this module:**

<details>

<summary><a href="/pages/Qdk4WhQ0d8XyT7bQqoO4">Action - Reaction</a>  (including: <a href="/pages/SaDm6XqjUUnmIkF4QTsk">SMD RED</a> + <a href="/pages/NCGxgyTCYPkOn7i8uCyE">RGB Module</a> + <a href="/pages/oOC231qxGDO8Pvwwgte3">Button Module</a>)</summary>

The interactive Python project named "LED Turn On/Off" utilizes an SMD Motor Driver, an add-on LED Module, and a Push Button Module to enable users to control the LED's state. It is tailored to offer an engaging hands-on experience for those keen on integrating Python programming with hardware control, showcasing fundamental input and output interactions in a straightforward manner.

</details>

<details>

<summary><a href="/pages/icfc38IW0QGr5Fr6FhqU">Rev Up The Engine</a> (including: <a href="/pages/SaDm6XqjUUnmIkF4QTsk">SMD RED</a> + <a href="/pages/oOC231qxGDO8Pvwwgte3">Button Module</a> + DC Motor)</summary>

The "Rev Up The Engine" application is an engaging Python-based project that integrates hardware components and programming to simulate the sensation of revving up a motorized engine. This project makes use of an SMD Motor Driver, a DC Motor, and a Push Button Module, enabling users to control the engine's speed by pressing and holding a button.

</details>

{% hint style="info" %}
Ready to integrate? You can purchase the <mark style="color:red;">**The Button Module**</mark> directly from our [Online Store](https://www.robotshop.com/products/acrome-button-add-on-module-acrome-smd-products?pr_prod_strat=e5_desc\&pr_rec_id=e23ece12f\&pr_rec_pid=8120246796449\&pr_ref_pid=8121226592417\&pr_seq=uniform). Worldwide shipping is available for engineering samples and production batches.
{% endhint %}


# Buzzer Module

<figure><img src="/files/3Ojfzqhc1P4JN8XQg9c7" alt=""><figcaption><p>Buzzer Module</p></figcaption></figure>

Here is the [datasheet of the buzzer (PKMCS0909E4000-R1) ](https://www.mouser.com.tr/datasheet/2/281/PKMCS0909E4000-R1-1186610.pdf)on the module.

<mark style="color:red;">The Buzzer Module</mark> is an auditory feedback device. It is a perfect tool for educational purposes, alarm - security systems, musical systems and many other projects. Since it can emit sound with different frequencies, it can play different notes and create melodies.

The buzzer on the module is waiting for a input from the microcontroller. When a certain frequency provided, buzzer gets the required electrical signals and emit the sound with intended frequency.

#### Step Files:

{% file src="/files/ExADn6Dj1FMlwkOB7P3d" %}

**Here are some of the sample projects that include this module:**

<details>

<summary><a href="/pages/aebR8t69BB6YEeolPen4">Smart Doorlbell</a>  (including: <a href="/pages/SaDm6XqjUUnmIkF4QTsk">SMD RED</a> + <a href="/pages/NCGxgyTCYPkOn7i8uCyE">RGB Module</a> + <a href="/pages/SdX9Ord2jwYmyck6NgNF">Ultrasonic Distance Sensor Module</a> +<a href="/pages/liJOj0hVzlqVel3FXGFI"> Buzzer Module</a>)</summary>

The Python-based "Buzzer On/Off" application integrates an SMD Motor Driver, an add-on Buzzer Module, and an HC-SR04 Ultrasonic Sensor Module to form an interactive system that reacts to nearby objects. The project is crafted to demonstrate the practical application of combining hardware components with Python programming.

</details>

<details>

<summary><a href="/pages/7hMFDDofaE5qiyJ426sD">Seccurity System</a> (including: <a href="/pages/SaDm6XqjUUnmIkF4QTsk">SMD RED</a> + <a href="/pages/NCGxgyTCYPkOn7i8uCyE">RGB Module</a> + <a href="/pages/SdX9Ord2jwYmyck6NgNF">Ultrasonic Distance Sensor Module</a> +<a href="/pages/liJOj0hVzlqVel3FXGFI"> Buzzer Module</a>)</summary>

The "Security System" application is a Python-based project that leverages hardware components to create a simple yet effective security monitoring system. This project utilizes an SMD Motor Driver, an RGB LED Module, a Buzzer Module, and an HC-SR04 Ultrasonic Distance Module. The system is designed to activate an alarm and visual warning signals if the detected distance falls below a predetermined threshold.

</details>

{% hint style="info" %}
Ready to integrate? You can purchase the <mark style="color:red;">**The Buzzer Module**</mark> directly from our [Online Store](https://www.robotshop.com/products/acrome-buzzer-sound-add-on-module-acrome-smd-products). Worldwide shipping is available for engineering samples and production batches.[<br>](https://app.gitbook.com/o/fyc7MRDevnnOQSZQ7r8i/s/-LuxEcL3mxZNc5Aa92N6/electronics/add-on-modules/ambient-light-sensor-module)
{% endhint %}


# IMU Module

<figure><img src="/files/cziq6Z6fY5S7Qjx1n881" alt=""><figcaption><p>IMU Module</p></figcaption></figure>

Here is the [datasheet of the IMU (MPU6050)](https://invensense.tdk.com/wp-content/uploads/2015/02/MPU-6000-Datasheet1.pdf) on the module.

<mark style="color:red;">The IMU Module</mark> (Inertial Measurement Unit) allows the user to check the roll and pitch values. The values are obtained from the MPU6050 to the IMU module. These values are most commonly used in motor control systems and where balance is an important concern.&#x20;

The IMU module receives two parameters, roll and pitch. The roll parameter is the rotation of the IMU sensor around its longitudinal axis. The pitch parameter is the rotation of the sensor around its lateral axis. These parameters help the user to maintain precise control over any type of system.

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

#### Step Files:

{% file src="/files/HmRXicf4SAzzHxGAtSPW" %}

{% hint style="info" %}
Ready to integrate? You can purchase the <mark style="color:red;">**The IMU Module**</mark> directly from our [Online Store](https://www.robotshop.com/products/acrome-inertial-measurement-imu-add-on-module-acrome-smd-products). Worldwide shipping is available for engineering samples and production batches.
{% endhint %}


# Joystick Module

<figure><img src="/files/2Y7O8WvIH4i0ny7NbAQZ" alt=""><figcaption><p>Joystick Module</p></figcaption></figure>

<mark style="color:red;">The Joystick Module</mark> is a device that allows the user to precisely control any system . It gives a control possibility like a game controller. It has 2 potentiometers inside to measure the movement in analog value range of \[-100 , 100] in X and Y axis. There is also a button in the middle of the joystick which returns 1 when it is pressed and 0 when not pressed.

Joysticks are generally used in applications such as simulation control, robotic systems, pan tilt mechanisms and more.

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

#### Step Files:

{% file src="/files/hbnOG7QdadBMkDClIiLu" %}

{% hint style="info" %}
Ready to integrate? You can purchase the <mark style="color:red;">**The Joystick Module**</mark> directly from our [Online Store](https://www.robotshop.com/products/acrome-joystick-2-axis-add-on-module-acrome-smd-products). Worldwide shipping is available for engineering samples and production batches.
{% endhint %}


# Potentiometer Module

<figure><img src="/files/STPm78foNSqKwsJDvhXr" alt=""><figcaption><p>Potentiometer Module</p></figcaption></figure>

<mark style="color:red;">The Potentiometer Module</mark> is a tool used to convert voltage into analog values for use in many scenarios. The potentiometer serves like a rheostat, changing the resistance by turning the shaft and allowing voltage to be divided and read from a signal pin. The received voltage value is passed through a signal pin and converted to an analog value in the range of \[0, 255]. Thus, this value can be used in different ways in robotic systems.

The potentiometer module can be used in systems needed to adjust different levels of function such as LED brightness level, volume level or motor speed control.

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

#### Step Files:

{% file src="/files/qtYtp9SqtSqHGM7irVYP" %}

{% hint style="info" %}
Ready to integrate? You can purchase the <mark style="color:red;">**The Potentiometer Module**</mark> directly from our [Online Store](https://www.robotshop.com/products/acrome-potentiometer-knob-sensor-add-on-module-acrome-smd-products). Worldwide shipping is available for engineering samples and production batches.
{% endhint %}


# Reflectance Sensor Module

<figure><img src="/files/w6Ow2R6SKIJgCFbHclVu" alt=""><figcaption><p>Reflectance Sensor Module</p></figcaption></figure>

Here is the [datasheet of the reflectance sensor (CNY70)](https://www.vishay.com/docs/83751/cny70.pdf) on the module.

<mark style="color:red;">The Reflectance Sensor Module</mark> is a tool that used to detect contrast on a surface. It works by detecting the reflectance of a surface using infrared light and differentiating the contrast by measuring the amount of reflected light to the ratio of emitted light. The most distinguishable surface colors are black and white, as in line-following robot parkours.&#x20;

The module has 3 reflectance sensors on it, positioned as left - middle - right, each sensor returns an analog value in the range of \[0, 255] to express the contrast level. This feature makes it a valuable tool to build a line follower robot system combined with PID controller.

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

#### Step Files:

{% file src="/files/DjiQTkUkDNOBzYD2xxBd" %}


# RGB LED Module

<figure><img src="/files/cEidmzJytXq7q0QAstp2" alt=""><figcaption><p>RGB LED Module</p></figcaption></figure>

<mark style="color:red;">The RGB LED Module</mark> is a simple yet essential tool as an indicator. It can emit light in 3 separate colors, red, green and blue. Each color gets an input in the range of \[0, 255] as a level of its intensity. The color values can be mixed in order to create any color.

The module can be used as a status indicator in many systems, when an operation is completed or there is an unexpected occurrence, RGB LED can be used to indicate the situation in a selected color. Thus, it will make easier to understand the system behavior without directly interacting and debugging it.

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

#### Step Files:

{% file src="/files/xDnj2aEB9XBdPWFrkCAQ" %}

**Here are some of the sample projects that include this module:**

<details>

<summary><a href="/pages/Ospbj3cQUzGmX2IUx3Rf">Blink</a> (including: <a href="/pages/SaDm6XqjUUnmIkF4QTsk">SMD RED</a> + <a href="/pages/NCGxgyTCYPkOn7i8uCyE">RGB Module</a>)</summary>

The Python-based LED Blink application, incorporating the SMD Motor Driver and LED Module Add-on, offers users the ability to manage LED blinking through Acrome SMD. Created for ease of use, this project serves as an excellent introduction for individuals interested in experimenting with hardware control using Python.

</details>

<details>

<summary><a href="/pages/Qdk4WhQ0d8XyT7bQqoO4">Action - Reaction</a>  (including: <a href="/pages/SaDm6XqjUUnmIkF4QTsk">SMD RED</a> + <a href="/pages/NCGxgyTCYPkOn7i8uCyE">RGB Module</a> + <a href="/pages/oOC231qxGDO8Pvwwgte3">Button Module</a>)</summary>

The interactive Python project named "LED Turn On/Off" utilizes an SMD Motor Driver, an add-on LED Module, and a Push Button Module to enable users to control the LED's state. It is tailored to offer an engaging hands-on experience for those keen on integrating Python programming with hardware control, showcasing fundamental input and output interactions in a straightforward manner.

</details>

<details>

<summary><a href="/pages/YlM3cOhzbmqDllKRav2e">Autonomous Lighting</a>  (including: <a href="/pages/SaDm6XqjUUnmIkF4QTsk">SMD RED</a> + <a href="/pages/NCGxgyTCYPkOn7i8uCyE">RGB Module</a> + <a href="/pages/fKIStzOqDX1QM9Q5U4To">Ambient Light Sensor Module</a>)</summary>

The Python-based “Automatic LED Turn On/Off” application integrates an SMD Motor Driver, an add-on LED Module, and an Ambient Light Sensor Module to form an intelligent lighting system. This project automatically adjusts the LED’s state according to ambient light conditions, offering an energy-efficient solution suitable for diverse environments.

</details>

<details>

<summary><a href="/pages/7hMFDDofaE5qiyJ426sD">Seccurity System</a> (including: <a href="/pages/SaDm6XqjUUnmIkF4QTsk">SMD RED</a> + <a href="/pages/NCGxgyTCYPkOn7i8uCyE">RGB Module</a> + <a href="/pages/SdX9Ord2jwYmyck6NgNF">Ultrasonic Distance Sensor Module</a> +<a href="/pages/liJOj0hVzlqVel3FXGFI"> Buzzer Module</a>)</summary>

The "Security System" application is a Python-based project that leverages hardware components to create a simple yet effective security monitoring system. This project utilizes an SMD Motor Driver, an RGB LED Module, a Buzzer Module, and an HC-SR04 Ultrasonic Distance Module. The system is designed to activate an alarm and visual warning signals if the detected distance falls below a predetermined threshold.

</details>

{% hint style="info" %}
Ready to integrate? You can purchase the <mark style="color:red;">**The RGB LED Module**</mark> directly from our [Online Store](https://www.robotshop.com/products/acrome-rgb-led-add-on-module-acrome-smd-products). Worldwide shipping is available for engineering samples and production batches.
{% endhint %}


# Servo Module

<figure><img src="/files/XKfT97Qul7OTD9PgupVk" alt=""><figcaption><p>Servo Module</p></figcaption></figure>

<mark style="color:red;">The Servo Module</mark> is a critical component in motor control systems. Servo motors are used for precise motor control. They are mostly used in robotics where there are automated movements such as robotic arms, mobile robot vehicles etc. Servo motors generally get an analog value in terms of degrees in the range of \[0, 180], it is enough range of motion when two or more servos coupled together with joints, creating a lot of motion axis.&#x20;

The servo module can drive a servo motor precisely, so it allows the user to make pan-tilt camera mechanism, robotic arm, steering system in a mobile robot and so on.

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

### Pin Inputs and Outputs

Here is a I/O diagram of the SMD Servo Module to connect the servo motor correctly:

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

#### Step Files:

{% file src="/files/53uANwXG3ivgPIDADzau" %}

{% hint style="info" %}
Ready to integrate? You can purchase the <mark style="color:red;">**The Servo Module**</mark> directly from our [Online Store](https://www.robotshop.com/products/acrome-rc-servo-add-on-module-acrome-smd-products). Worldwide shipping is available for engineering samples and production batches.
{% endhint %}


# Ultrasonic Distance Sensor Module

<figure><img src="/files/0tf14UZ1MfgnRx7eZHIT" alt=""><figcaption><p>Ultrasonic Distance Sensor Module</p></figcaption></figure>

Here is the [datasheet of the distance sensor (HC-SR04)](https://cdn.sparkfun.com/datasheets/Sensors/Proximity/HCSR04.pdf) on the module.

<mark style="color:red;">The Ultrasonic Distance Sensor Module</mark> is a distance measurement tool. It uses a HC-SR04 ultrasonic distance sensor on it, which is an economical yet powerful sensor for its purpose. The working principle of the HC-SR04 is to send out sound waves and wait for them to return, meanwhile, the sensor holds a signal pin at high voltage level, which is '1' in bool, until the sent out sound waves are received. Thus, the user will be able to calculate the distance between the surface or object facing the sensor.&#x20;

The ultrasonic distance sensor can be used in many projects such as parking systems, object avoidance mobile robots, security systems, automated doors, production lines and much more.

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

#### Step Files:

{% file src="/files/WQ34JbJY1heEqfLOae8X" %}

**Here are some of the sample projects that include this module:**

<details>

<summary><a href="/pages/aebR8t69BB6YEeolPen4">Smart Doorlbell</a>  (including: <a href="/pages/SaDm6XqjUUnmIkF4QTsk">SMD RED</a> + <a href="/pages/NCGxgyTCYPkOn7i8uCyE">RGB Module</a> + <a href="/pages/SdX9Ord2jwYmyck6NgNF">Ultrasonic Distance Sensor Module</a> +<a href="/pages/liJOj0hVzlqVel3FXGFI"> Buzzer Module</a>)</summary>

The Python-based "Buzzer On/Off" application integrates an SMD Motor Driver, an add-on Buzzer Module, and an HC-SR04 Ultrasonic Sensor Module to form an interactive system that reacts to nearby objects. The project is crafted to demonstrate the practical application of combining hardware components with Python programming.

</details>

<details>

<summary><a href="/pages/7fVrgDa7I7T4nSyzwkQL">Automatıc Trash Bin</a> (including: <a href="/pages/SaDm6XqjUUnmIkF4QTsk">SMD RED</a> + <a href="/pages/SdX9Ord2jwYmyck6NgNF">Ultrasonic Distance Sensor Module</a> + DC Motor)</summary>

The Python-based "Automatic Trash Bin" application utilizes an SMD Motor Driver, a DC Motor, and an add-on HC-SR04 Ultrasonic Module to establish a hands-free and hygienic waste disposal solution. This innovative project enables the trash bin lid to open automatically upon a user's approach, enhancing convenience and promoting a touch-free experience.

</details>

<details>

<summary><a href="/pages/jnAu6t8QlU348w2FYRth">Radar</a> (including: <a href="/pages/SaDm6XqjUUnmIkF4QTsk">SMD RED</a> + <a href="/pages/SdX9Ord2jwYmyck6NgNF">Ultrasonic Distance Sensor Module</a> + DC Motor + 3D Printed Parts)</summary>

The "Radar" application is a captivating Python-based project that integrates hardware components, 3D printing, and programming to simulate a radar system. This project incorporates an SMD Motor Driver, a DC Motor, and an HC-SR04 Ultrasonic Distance Module mounted on the motor with 3D printed parts. As the motor rotates, the distance sensor gathers data and presents it in real-time on the user's screen, creating a radar-like visualization.

</details>

{% hint style="info" %}
Ready to integrate? You can purchase the <mark style="color:red;">**The Ultrasonic Distance Sensor Module**</mark> directly from our [Online Store](https://www.robotshop.com/products/acrome-ultrasonic-distance-sensor-add-on-module-acrome-smd-products). Worldwide shipping is available for engineering samples and production batches.
{% endhint %}


# Starter Kit

The <mark style="color:red;">**SMD Starter Kit**</mark> is designed to introduce you to the exciting world of motion control and mechatronics—without the need for prior experience. Whether you're a curious student, an enthusiastic hobbyist, or an educator building hands-on STEM content, this kit provides a smooth and intuitive entry point to smart motion systems.

<figure><img src="/files/cGu11nVvpT8w8rvaIhYs" alt="" width="563"><figcaption><p>SMD Starter Kit</p></figcaption></figure>

## Who Is It For?

* Students exploring robotics and automation for the first time
* Educators looking to implement hands-on STEM content
* Hobbyists and makers wanting to build motion-based projects
* Beginners seeking a plug-and-play introduction to Acrome’s SMD ecosystem

## What’s Inside the Box?

Everything you need to start building right away:

1x [SMD RED](/electronics/smd-red) Smart Brushed Motor Driver with Speed, Position and Current Control Modes

1x [12V Brushed DC Motor with built-in encoder](/electronics/electrical-motors/brushed-dc-motors-bdc), 100 RPM speed

1x 37mm Motor Mount (90 degrees) with anodized black paint

1x [USB Gateway Module](/electronics/gateway-modules/usb-gateway-module) for SMD Products

1x [Joystick Add-On Module](/electronics/add-on-modules/joystick-module) for SMD Products

1x 9x11 Plate for SMD Products

1x 12Vdc-5A SMPS Adapter

Note: A PC, Arduino (with additional SMD Arduino gateway) or controller with a USB host port (such as Raspberry Pi, Jetson etc.) is required to use the SMD products.

{% embed url="<https://youtu.be/Fhw1f_A2EUY>" %}
This video shows how to assamble the Starter Kit out of the box
{% endembed %}

## Learn by Doing

The Starter Kit is fully compatible with:

* **SMD Blockly** – Drag-and-drop programming for absolute beginners
* **Python SDK** – Code and customize projects with real-time feedback

Use official sample codes or create your own—from the very first minute, you’ll be in full control of your hardware.

## Key Features

* Beginner-friendly: No prior coding or electronics knowledge required
* Plug & Play: RJ-11 modular system—no wiring headaches
* Multi-platform: Works on Windows, macOS, and Linux
* Ideal for STEM: Teach motion control through hands-on learning

## Expand as You Go

Already finished your first few projects? The SMD Starter Kit is fully expandable. Add new modules like joysticks, servo motors, or line sensors without changing your setup. Build on what you’ve learned and evolve your system into a complete smart robot.

## Assembly Guide <a href="#assembly-guide" id="assembly-guide"></a>

A detailed step-by-step assembly guide is available as a PDF document:

{% file src="/files/QTYZ3fbADQL0rg7ss3l1" %}

## Codes

{% tabs %}
{% tab title="All Motor Control Modes Python" %}
{% code lineNumbers="true" %}

```python
from smd.red import *
from serial.tools.list_ports import comports
from platform import system
import math
import os
import time
import json
import logging
from datetime import datetime

logging.basicConfig(
    filename=f'motor_log_{datetime.now().strftime("%Y%m%d_%H%M%S")}.log',
    level=logging.INFO,
    format='%(asctime)s - %(levelname)s - %(message)s'
)

class MotorConfig:
    """Engine configuration class"""
    DEFAULT_CONFIG = {
        'CPR': 6533,
        'RPM': 100,
        'JOYSTICK_DEADZONE': 10,
        'MAX_SPEED': 100,
        'MIN_SPEED': -100,
        'UPDATE_INTERVAL': 0.1
    }

    @staticmethod
    def load_config(filename='Starter Kit/motor_config.json'):
        try:
            with open(filename, 'r') as f:
                return {**MotorConfig.DEFAULT_CONFIG, **json.load(f)}
        except FileNotFoundError:
            logging.warning("Configuration file not found, using default settings.")
            return MotorConfig.DEFAULT_CONFIG

class MotorModes:
    """Enum-like class for engine modes"""
    PWM = 0
    VELOCITY = 1
    POSITION = 2
    TORQUE = 3

    @staticmethod
    def get_mode_name(mode):
        modes = {
            0: "PWM Mode",
            1: "Speed ​​Mode",
            2: "Position Mode",
            3: "Torque Mode"
        }
        return modes.get(mode,"Unknown Mode")

class MotorController:
   """Main engine control class"""
    def __init__(self, port, motor_id=1):
        self.master = Master(port)
        self.id = motor_id
        self.config = MotorConfig.load_config()
        self.mode = 0
        self.setup_motor()
        self.last_update = time.time()
        
        # Durum değişkenleri
        self.motor_speed = 0
        self.angle_degrees = 0
        self.current_limit = 100
        self.current_value = 0
        self.previous_current = 0
        self.torque_status = True

    def setup_motor(self):
        """Engine start settings"""
        try:
            self.master.attach(Red(self.id))
            self.master.set_shaft_cpr(self.id, self.config['CPR'])
            self.master.set_shaft_rpm(self.id, self.config['RPM'])
            
            # Kontrol parametreleri
            self.master.set_control_parameters_velocity(self.id, 30.0, 5.0, 0.0)
            self.master.set_control_parameters_position(self.id, 0.5, 0.0, 20.0)
            self.master.set_control_parameters_torque(self.id, 3.0, 0.1, 0.0)
            
            self.master.enable_torque(self.id, True)
            logging.info("Engine started successfully")
        except Exception as e:
            logging.error(f"Engine start failure: {e}")
            raise

    def safe_joystick_read(self):
        """Secure joystick reading"""
        try:
            return self.master.get_joystick(self.id, 1)
        except Exception as e:
            logging.warning(f"Joystick reading error: {e}")
            return [0, 0, 0]

    def emergency_stop(self):
        """Emergency stop"""
        try:
            self.master.enable_torque(self.id, False)
            self.master.set_duty_cycle(self.id, 0)
            logging.info("Emergency stop was carried out")
        except Exception as e:
            logging.error(f"Emergency stop error: {e}")

    def handle_pwm_mode(self, joystick_x):
        """PWM mode handler"""
        self.master.set_operation_mode(self.id, OperationMode.PWM)
        if abs(joystick_x) > self.config['JOYSTICK_DEADZONE']:
            self.motor_speed = joystick_x
            self.master.set_duty_cycle(self.id, -self.motor_speed)
        else:
            self.master.set_duty_cycle(self.id, 0)
            self.motor_speed = 0
        return {"Motor Duty Cycle": self.motor_speed}

    def handle_velocity_mode(self, joystick_x, joystick_y):
        """Velocity​​ mode handler"""
        self.master.set_operation_mode(self.id, OperationMode.Velocity)
        if (joystick_x > 50 or joystick_y > 50) and self.motor_speed < self.config['MAX_SPEED']:
            self.motor_speed += 1
        elif (joystick_x < -50 or joystick_y < -50) and self.motor_speed > self.config['MIN_SPEED']:
            self.motor_speed -= 1
        self.master.set_velocity(self.id, -self.motor_speed)
        return {"Motor Speed": self.motor_speed}

    def handle_position_mode(self, joystick_x, joystick_y):
        """Position mode handler"""
        self.master.set_operation_mode(self.id, OperationMode.Position)
        if abs(joystick_x) < 10 and abs(joystick_y) < 10:
            try:
                current_position = self.master.get_position(self.id)
                self.angle_degrees = current_position * (360/self.config['CPR'])
            except:
                pass
        else:
            x = joystick_x / 100.0
            y = joystick_y / 100.0
            angle = math.atan2(y, x)
            previous_angle = self.angle_degrees
            self.angle_degrees = (math.degrees(angle) + 360) % 360
            
            if self.angle_degrees - previous_angle > 180:
                self.angle_degrees -= 360
                
            position = self.angle_degrees * (self.config['CPR']/360)
            self.master.set_position(self.id, position)
        
        return {"Engine Angle": f"{self.angle_degrees:.2f}°"}

    def handle_torque_mode(self, joystick_x, joystick_y):
        """Torque mode handler"""
        self.master.set_operation_mode(self.id, OperationMode.Torque)
        if joystick_x > 50 or joystick_y > 50:
            self.current_limit += 1
        elif joystick_x < -50 or joystick_y < -50:
            self.current_limit -= 1

        self.master.set_torque(self.id, self.current_limit - 50)
        
        try:
            self.previous_current = self.current_value
            self.current_value = self.master.get_torque(self.id)
        except:
            self.current_value = self.previous_current

        if self.current_value >= self.current_limit:
            self.current_value = self.current_limit
            
        return {
            "Motor Current": f"{self.current_value:.2f}",
            "Current Limit": self.current_limit
        }
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

def main():
    # USB port bulma
    port = USB_Port()
    if not port:
        logging.error("No port found")
        return

    # Motor kontrolcüsü oluşturma
    controller = MotorController(port)
    
    while True:
        try:
            # Joystick durumunu oku
            joystick_x, joystick_y, button = controller.safe_joystick_read()

            # Mod değişimi kontrolü
            if button:
                controller.mode = (controller.mode + 1) % 4
                logging.info(f"Chance Mode: {MotorModes.get_mode_name(controller.mode)}")
                time.sleep(0.5)  

            logging.info(f"Current mode: {MotorModes.get_mode_name(controller.mode)}")
            if controller.mode == MotorModes.PWM:
                status = controller.handle_pwm_mode(joystick_x)
            elif controller.mode == MotorModes.VELOCITY:
                status = controller.handle_velocity_mode(joystick_x, joystick_y)
            elif controller.mode == MotorModes.POSITION:
                status = controller.handle_position_mode(joystick_x, joystick_y)
            elif controller.mode == MotorModes.TORQUE:
                status = controller.handle_torque_mode(joystick_x, joystick_y)
            else:
                logging.error("Invalid mode selected")

            print(f"=== {MotorModes.get_mode_name(controller.mode)} ===")
            print("-" * 40)
            for key, value in status.items():
                print(f"{key}: {value}")
            print("-" * 40)

        except KeyboardInterrupt:
            logging.info("The program was terminated by the user")
            controller.emergency_stop()
            break
        except Exception as e:
            logging.error(f"Unexpected error: {e}")
            controller.emergency_stop()
            break

if __name__ == "__main__":
    main()
```

{% endcode %}
{% endtab %}

{% tab title="All Motor Control Modes Arduino" %}
{% code lineNumbers="true" fullWidth="false" %}

```cpp
#include <Acrome-SMD.h>
#define BAUDRATE   115200      
#define CPR        6533        
#define ID         1          
Red master(ID, Serial, BAUDRATE); 

int mode = 0;  // Motor control mode (0: PWM, 1: Velocity, 2: Position, 3: Torque)
int motorSpeed = 0;  
int currentLimit = 100; 
bool torqueEnabled = true;

void setup() {
  master.begin();               
  master.torqueEnable(1);       
  Serial.begin(115200);           
}

void loop() {
start();
}

void start(){
  int joystickX, joystickY, button;
  joystickX = (master.getJoystickX(1))?master.getJoystickX(1):0;
  joystickY = (master.getJoystickY(1))?master.getJoystickY(1):0;
  button = (master.getJoystickButton(1))?master.getJoystickButton(1):0;
  if (button) {
      delay(3000); 
      mode = (mode + 1) % 4;
      master.torqueEnable(0); delay(100);
      master.torqueEnable(1); delay(100);
    }
  switch (mode) {
    case 0: // PWM Control
      master.setOperationMode(PWMControl);
      if (abs(joystickX) > 10) {
        motorSpeed = joystickX;
        master.setpoint(0, -motorSpeed);
      } else {
        master.setpoint(0, 0);
      }
      Serial.println("*** MODE 1: PWM ***");
      Serial.print("Motor Duty Cycle: "); Serial.println(motorSpeed);
      break;

    case 1: // Velocity Control
      master.setOperationMode(VelocityControl);
      if (joystickX > 50 || joystickY > 50) {
        motorSpeed = constrain(motorSpeed + 1, -100, 100);
      } else if (joystickX < -50 || joystickY < -50) {
        motorSpeed = constrain(motorSpeed - 1, -100, 100);
      }
      master.setpoint(2, -motorSpeed);
      Serial.println("*** MODE 2: Velocity ***");
      Serial.print("Motor Speed: "); Serial.println(motorSpeed);
      break;

    case 2: // Position Control
      master.setOperationMode(PositionControl);
      if (abs(joystickX) > 10 || abs(joystickY) > 10) {
        float angle = atan2(joystickY / 100.0, joystickX / 100.0);
        float angleDegrees = fmod(degrees(angle) + 360.0, 360.0);
        int position = angleDegrees * (CPR / 360.0);
        master.setpoint(1, position);
        Serial.println("*** MODE 3: Position ***");
        Serial.print("Motor Angle: "); Serial.println(angleDegrees);
      }
      break;

    case 3: // Torque Control
      master.setOperationMode(TorqueControl);
      if (joystickX > 50 || joystickY > 50) {
        currentLimit++;
      } else if (joystickX < -50 || joystickY < -50) {
        currentLimit--;
      }
      master.setpoint(3, currentLimit - 50);
      int current = master.getTorque();
      Serial.println("*** MODE 4: Torque ***");
      Serial.print("Motor Current: "); Serial.println(current);
      Serial.print("Current Limit: "); Serial.println(currentLimit);

      if (current >= currentLimit) {
        master.torqueEnable(0);
        torqueEnabled = false;
        Serial.println("Motor movement disabled due to the current exceed!");
      }
      break;

    default:
      break;
  }
}
```

{% endcode %}

{% endtab %}
{% endtabs %}

{% hint style="info" %}
Ready to integrate? You can purchase the <mark style="color:$danger;">**SMD Starter Kit**</mark>  directly from our [Online Store](https://www.robotshop.com/products/acrome-smd-starter-kit-smd-red-smart-brushed-motor-driver-recommended-new-users?qd=17a713b5bb54afeb5cef9b15d8a5762e). Worldwide shipping is available for engineering samples and production batches.
{% endhint %}


# What You Can Build

Unleash the full potential of your DC motor setups using various control methods. With the Starter Kit, you can easily prototype and experiment with industry-relevant control algorithms. Below are the featured applications:

{% embed url="<https://www.youtube.com/watch?v=H_UvFjjW6U0>" %}
Position and Velocity Control with SMD Starter Kit
{% endembed %}

[**Motor Rotation Based on Turn Input Value**](/smd-applications/interactive/motor-rotation-based-on-turn-input-value)

Rotate the motor proportionally to an external sensor (e.g., potentiometer or gyroscope). Ideal for exploring sensor-feedback driven motor control.

**What You’ll Learn:**

* Mapping analog input to rotational output
* Real-time input-based motion control
* Practical sensor-motor integration

[**Basic Motor Speed Control Application**](/smd-applications/interactive/basic-motor-speed-control-application)

Dynamically adjust motor speed using analog or digital input signals such as a potentiometer, rotary encoder, or software interface.

**What You’ll Learn:**

* Open-loop speed control fundamentals
* Analog-to-PWM signal conversion
* Speed variation under different loads

[**Basic Motor Control Using PWM Input**](/smd-applications/interactive/basic-motor-control-application-using-pwm-input)

Control motor direction and speed with pulse-width modulation (PWM). This project introduces you to one of the most common control techniques used in embedded systems.

**What You’ll Learn:**

* Understanding PWM for motor actuation
* Bidirectional speed control using a single input
* Effects of duty cycle on motor behavior

[**Basic Motor Position Control Application**](/smd-applications/interactive/basic-motor-position-control-application)

Move the motor to a desired position using encoder feedback. Ideal for introducing the concepts of closed-loop control and precision actuation.

**What You’ll Learn:**

* Using encoders for position tracking
* PID basics for position control
* Practical application of reference-to-position logic

[**Basic Motor Torque Control Application**](/smd-applications/interactive/basic-motor-torque-control-application)

Simulate and apply precise torque to the motor for applications such as compliant control or mechanical testing setups.

**What You’ll Learn:**

* Torque estimation and feedback
* How to simulate mechanical loads
* Safe and smooth torque application techniques

[**Motor Rotation Based on Joystick Counting**](/smd-applications/interactive/motor-rotation-based-on-joystick-counting)

Control the motor’s rotation by counting incremental movements from a joystick. This project is excellent for creating discrete, step-based user interfaces.

**What You’ll Learn:**

* Handling digital incremental input
* Cumulative control mechanisms
* Implementing rotation based on user gestures

### &#x20;Why These Projects Matter

Each of these applications is designed to simulate real-world industrial control systems, making them ideal for:

* Engineering students
* Technical educators
* R\&D professionals
* DIY roboticists


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


# Basic Motor Speed Control Application

This program demonstrates a basic motor control application that adjusts the motor's speed based on user input. It communicates with the motor controller via USB and sets the motor speed (velocity) according to the user's specified value. This allows for simple motor speed control, where the user can input a desired speed, and the motor will rotate accordingly.

## Key Components:

1. **USB Port Detection**:
   1. The program starts by detecting the available USB serial port for communication with the motor. It uses the `serial` module to find connected serial devices.
   2. The program supports multiple platforms (Windows, Linux, and macOS) and automatically identifies the correct port based on the operating system.
2. **Motor Control with SMD Red**:
   1. The motor is controlled through the `smd.red` library, which allows sending commands to the motor via the Red controller.
   2. A `Master` object is used to establish communication with the motor, and the motor is attached using the `Red(ID)` method.
3. **Motor Speed Configuration**:
   1. The program allows the user to input a speed value (in RPM or another suitable unit). The motor's velocity is set to this value using the `m.set_velocity()` method.
   2. The motor's other parameters, such as the revolutions per minute (RPM) and control settings, are preconfigured for optimal operation.
4. **User Input**:
   1. The program prompts the user to input the desired motor speed, and then it sets the motor’s velocity accordingly. The speed is used to control how fast the motor will rotate.
5. **Feedback to User**:
   1. After setting the motor speed, the program confirms the set speed with a printed message: `"The engine rotates at speed {speed}."`

## Example Usage:

When you run the program, it will prompt you to enter the speed:

```
Speed: 150
```

After entering the speed, for example, 150, the motor will rotate at the set speed. The program will then print a message confirming the motor's speed:

```
The engine rotates at speed 150.
```

## Code

```python
from smd.red import *
from serial.tools.list_ports import comports
from platform import system
import math
import os

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)

ID = 0

m.attach(Red(ID))

m.set_shaft_cpr(ID, 6533)
m.set_shaft_rpm(ID, 100)
m.set_operation_mode(ID, OperationMode.Velocity)
m.set_control_parameters_velocity(ID, 30.0, 5.0, 0.0)
m.enable_torque(ID, True)

speed = input("Speed: ")

m.set_velocity(ID,float(speed))

print("The engine rotates at speed "+speed+".")
```


# Basic Motor Control Application Using PWM Input

This program demonstrates a fundamental motor control application, where the motor’s behavior is controlled through Pulse Width Modulation (PWM) input specified by the user. The script sets up the motor, establishes communication, and allows the user to input a PWM value to control the motor's rotation speed and direction. PWM is a common method to adjust motor speed in motor control applications.

## Key Components:

1. **USB Port Detection**:
   1. The script first identifies and connects to the appropriate USB serial port based on the operating system. It uses the `serial` module to scan for connected serial devices.
   2. The program is compatible with Windows, Linux, and macOS, using different naming conventions for the USB port depending on the OS.
2. **Motor Initialization and Configuration**:
   1. The `Master` and `Red` objects from the `smd.red` library are used to set up the motor and establish communication.
   2. The motor's essential parameters are initialized, such as counts per revolution (`set_shaft_cpr`) and shaft RPM (`set_shaft_rpm`).
3. **PWM Input for Motor Control**:
   1. After configuring the motor, the program prompts the user to input a PWM value, which will control the motor’s rotation speed and direction.
   2. PWM values can vary, with positive values for one direction and negative values for the opposite. This input is passed to the motor using `m.set_duty_cycle(0, -int(pwm))`.
   3. By inputting a PWM value, the user directly controls the motor’s duty cycle, affecting both the speed and direction.
4. **User Feedback**:
   1. After setting the PWM, the program prints a confirmation message indicating that the motor is running at the specified PWM level.

## Example Usage:

When you run the program, it will prompt you to enter a PWM value:

```
PWM: 50
```

After you input 50, the motor will start rotating at the specified PWM level. The program will then display the following message:

```
The motor is running with a PWM value of 50.
```

## Code:

```python
from smd.red import *
import math
import os

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)
m.attach(Red(0))

m.set_shaft_cpr(0,6533)
m.set_shaft_rpm(0,100)

motor_speed = 0
angle_degrees=0
current_limit = 100
current_value = 0
previous_current = 0

m.set_operation_mode(0, OperationMode.Velocity)
m.set_control_parameters_velocity(0, 30.0, 5.0, 0.0)
m.set_control_parameters_position(0, 0.5, 0.0, 20.0)
m.set_control_parameters_torque(0, 3.0, 0.1, 0.0)
m.enable_torque(0, True)

m.set_operation_mode(0, OperationMode.PWM)
pwm = input("PWM:")
m.set_duty_cycle(0, -int(pwm))

print(f"The motor is running with a PWM value of {pwm}.")
```


# Motor Rotation Based on Joystick  Counting

This Python code demonstrates a joystick-controlled motor rotation system that enables a user to count joystick inputs and control the motor's rotations accordingly. The application uses a **USB-connected motor controller** to read joystick inputs and perform precise motor movements based on the input count. Below is a step-by-step explanation of the code.

## Required Libraries and Modules

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

* **`serial`**: Handles USB serial communication with the motor controller.
* **`smd.red`**: Provides classes (`Master` and `Red`) for interacting with the motor controller and motor.
* **`threading.Thread`**: Enables multi-threading, allowing joystick input to be handled in parallel with other operations.
* **`time`**: Used for timing and delays.
* **`serial.tools.list_ports`**: Lists available USB ports on the system.
* **`platform.system`**: Detects the operating system (Windows, Linux, or macOS) for platform-specific USB handling.

## USB Port Detection Function

```python
def USB_Port():
    if system() == "Windows":
        ports = list(comports())
        if ports:
            for port, desc, hwid in sorted(ports):
                if 'USB Serial Port' in desc:
                    return port
        return None

    elif system() == "Linux":
        ports = list(serial.tools.list_ports.comports())
        if ports:
            for port, desc, hwid in sorted(ports):
                if '/dev/ttyUSB' in port:
                    return port

    elif system() == "Darwin":  # macOS
        ports = list(serial.tools.list_ports.comports())
        if ports:
            for port, desc, hwid in sorted(ports):
                if '/dev/tty.usbserial' in port or '/dev/tty.usbmodem' in port:
                    return port

    return None
```

* This function detects the USB port where the motor controller is connected:
  * **Windows**: Searches for ports labeled `USB Serial Port`.
  * **Linux**: Looks for ports starting with `/dev/ttyUSB`.
  * **macOS**: Searches for ports containing `/dev/tty.usbserial` or `/dev/tty.usbmodem`.
* If no suitable port is found, the function returns `None`.

## Motor Initialization

```python
port = USB_Port()
m = Master(port)
motor = m.attach(Red(0))
```

* **`USB_Port()`**: Detects the USB port for the motor controller.
* **`Master(port)`**: Establishes communication with the motor controller on the detected port.
* **`m.attach(Red(0))`**: Attaches a motor with ID `0`.

## Motor Parameter Configuration

```python
m.set_shaft_rpm(0, 100)
m.set_shaft_cpr(0, 6533)
m.set_control_parameters_velocity(0, 10, 1, 0) 
m.set_operation_mode(0, 2)
```

* **`set_shaft_rpm(0,`** 10&#x30;**`)`**: Sets the motor's maximum speed to 6533 RPM.
* **`set_shaft_cpr(0,`** 653&#x33;**`)`**: Defines the encoder resolution as 100 counts per revolution (CPR).
* **`set_control_parameters_velocity(0, 10, 1, 0)`**: Configures PID velocity control parameters.
* **`set_operation_mode(0, 2)`**: Sets the motor's operation mode to velocity control.

## Counting Mechanism and Motor Rotation

The code implements two key functionalities:

1. **Counting Mode**: The user can increment a counter by pressing and releasing the joystick button.
2. **Motor Rotation**: The motor rotates a specified number of turns based on the counter value.

Motor Rotation Function

```python
def rotate_motor(turns):
    steps_per_turn = 6533
    target_position = turns * steps_per_turn
    current_position = m.get_position(0)
    m.set_velocity(id=0, sp=10000)
    while abs(m.get_position(0) - current_position) < target_position:
        time.sleep(0.01)
    m.set_velocity(id=0, sp=0)
```

* **Calculate Target Position**: The number of steps required for the specified turns is calculated.
* **Control Motor Movement**: The motor rotates until the current position reaches the target position.
* **Stop the Motor**: The motor's velocity is set to zero once the target position is achieved.

**Joystick Control Function**

```python
def joystick_control():
    global counting_mode, turn_count, initial_press_time, final_press_time
    
    while True:
        joystick = m.get_joystick(0, 1)

        if joystick is not None:
            button_pressed = joystick[2]  # Button

            # Switching to counting mode: If the button is held down for 5 seconds for the first time
            if button_pressed and not counting_mode:
                initial_press_time = time.time()
                while button_pressed and time.time() - initial_press_time < 5:
                    button_pressed = m.get_joystick(0, 1)[2]  # Check if the button is still pressed
                    time.sleep(0.1)
                if time.time() - initial_press_time >= 2:
                    counting_mode = True
                    print("Counting mode has been entered. You can count by pressing and pulling.")
            
            # Increase turn_count by push-pull operation in counting mode
            elif counting_mode and button_pressed:
                turn_count += 1
                print(f"The counter was increased: {turn_count}")

            # Rotate the motor: Press and hold the button for 5 seconds in counting mode to rotate the motor.
            if counting_mode and button_pressed:
                final_press_time = time.time()
                while button_pressed and time.time() - final_press_time < 5:
                    button_pressed = m.get_joystick(0, 1)[2]
                    time.sleep(0.1)
                if time.time() - final_press_time >= 2:
                    print(f"The motor will turn {turn_count} times.")
                    rotate_motor(turn_count)
                    turn_count = 0  # Reset the turn count
                    counting_mode = False  # Exit counting mode
                    print("The motor is turned on and the counter is reset to zero.")

        time.sleep(0.01)
```

* **Button Press Detection**: Reads the joystick button state from the motor controller.
* **Entering Counting Mode**: Holding the button for 5 seconds activates counting mode.
* **Incrementing the Counter**: In counting mode, pressing and releasing the button increases the counter.
* **Triggering Motor Rotation**: Holding the button for another 5 seconds rotates the motor according to the counter value.

## Application Workflow

1. **Joystick Monitoring**: The `joystick_control` function continuously monitors joystick input in a separate thread.
2. **Counting Mode Activation**: The user can activate counting mode by holding the joystick button for 5 seconds.
3. **Increment Counter**: In counting mode, each press-and-release increments the counter.
4. **Motor Rotation**: Holding the button for 5 seconds in counting mode rotates the motor by the specified number of turns.

## Full 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():
    if system() == "Windows":
        ports = list(comports())
        if ports:
            for port, desc, hwid in sorted(ports):
                if 'USB Serial Port' in desc:
                    return port
        return None

    elif system() == "Linux":
        ports = list(serial.tools.list_ports.comports())
        if ports:
            for port, desc, hwid in sorted(ports):
                if '/dev/ttyUSB' in port:
                    return port

    elif system() == "Darwin":  # macOS
        ports = list(serial.tools.list_ports.comports())
        if ports:
            for port, desc, hwid in sorted(ports):
                if '/dev/tty.usbserial' in port or '/dev/tty.usbmodem' in port:
                    return port

    return None

port = USB_Port()
m = Master(port)
motor = m.attach(Red(0))

# Set motor parameters
m.set_shaft_rpm(0, 6533)
m.set_shaft_cpr(0, 100)
m.set_control_parameters_velocity(0, 10, 1, 0) 
m.set_operation_mode(0, 2)

# Variable to count how many turns to perform when the button is released
counting_mode = False
turn_count = 0
initial_press_time = 0
final_press_time = 0 

# Function to rotate the motor a specific number of turns
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


# Function to handle joystick control
def joystick_control():
    global counting_mode, turn_count, initial_press_time, final_press_time
    
    while True:
        joystick = m.get_joystick(0, 1)

        if joystick is not None:
            button_pressed = joystick[2]  # Button

            # Switching to counting mode: If the button is held down for 5 seconds for the first time
            if button_pressed and not counting_mode:
                initial_press_time = time.time()
                while button_pressed and time.time() - initial_press_time < 5:
                    button_pressed = m.get_joystick(0, 1)[2]  # Check if the button is still pressed
                    time.sleep(0.1)
                if time.time() - initial_press_time >= 2:
                    counting_mode = True
                    print("Counting mode has been entered. You can count by pressing and pulling.")
            
            # Increase turn_count by push-pull operation in counting mode
            elif counting_mode and button_pressed:
                turn_count += 1
                print(f"The counter was increased: {turn_count}")

            # Rotate the motor: Press and hold the button for 5 seconds in counting mode to rotate the motor.
            if counting_mode and button_pressed:
                final_press_time = time.time()
                while button_pressed and time.time() - final_press_time < 5:
                    button_pressed = m.get_joystick(0, 1)[2]
                    time.sleep(0.1)
                if time.time() - final_press_time >= 2:
                    print(f"The motor will turn {turn_count} times.")
                    rotate_motor(turn_count)
                    turn_count = 0  # Reset the turn count
                    counting_mode = False  # Exit counting mode
                    print("The motor is turned on and the counter is reset to zero.")

        time.sleep(0.01)
        
joystick_thread = Thread(target=joystick_control)
joystick_thread.daemon = True
joystick_thread.start()

while True:
    time.sleep(1)
```


# Education Kit

The Acrome Education Kit is designed to provide students, educators, and robotics enthusiasts with a hands-on learning experience in motion control, automation, and embedded systems. This kit simplifies the learning process for beginners while offering advanced features for researchers and industry professionals.

With a structured hardware-software ecosystem, users can explore concepts in robotics, mechatronics, programming, and real-time control, making it a perfect choice for STEM education, university labs, and prototyping projects.

<figure><img src="/files/YazU6MmllAoH2RuOcudL" alt=""><figcaption><p>Education Kit</p></figcaption></figure>

The Education Kit has all [SMD Add-on Modules](/electronics/add-on-modules) on three combined [11x19 Plate](/mechanics/building-set/plates/11x19-plate). It allows the users to interact with all the sensors that is available on the add-on modules and understand their working principle through experience. This kit is ideally created for educational purposes.

## Who Is It For?

* High school and university educators
* Engineering lab coordinators
* Technical training programs
* STEM-focused classrooms

## What’s Inside the Box?

The Education Kit includes a comprehensive selection of components designed to teach students fundamental and advanced robotics concepts:

* 1x [SMD RED](/electronics/smd-red) Smart Brushed Motor Driver with Speed, Position and Current Control Modes
* 1x [USB Gateway Module](/electronics/gateway-modules/usb-gateway-module)
* 1x[ 100 RPM DC motors with encoders](/electronics/electrical-motors/brushed-dc-motors-bdc)
* 1x [Ultrasonic distance sensor module](/electronics/add-on-modules/ultrasonic-distance-sensor-module)
* 1x[ servo module](/electronics/add-on-modules/servo-module) with servo motor
* 1x [Ambient Light Sensor Module](/electronics/add-on-modules/ambient-light-sensor-module)
* 1x [RGB LED module](/electronics/add-on-modules/rgb-led-module)
* 1x [Button Module](/electronics/add-on-modules/button-module)
* 1x[ Joystick Module](/electronics/add-on-modules/joystick-module)
* 1x [Buzzer Module](/electronics/add-on-modules/buzzer-module)
* 1x[ IMU Module](/electronics/add-on-modules/imu-module)
* 1x [Potentiometer Module](/electronics/add-on-modules/potentiometer-module)
* 1x [Reflectance Sensor Module](/electronics/add-on-modules/reflectance-sensor-module)
* All necessary RJ-45 cables and connectors
* Pre-configured power supply and mounting hardware

## Key Learning Outcomes

With this kit, students will:

* Understand core principles of robotics and motion control
* Gain hands-on experience with PID algorithms and sensor integration
* Learn modular design and how to build reconfigurable robots
* Develop real-world problem-solving and programming skills
* Apply theoretical knowledge in physics, math, and computer science

## **How to Use the Acrome Education Kit?**

The **Education Kit** supports a **step-by-step learning process**, making it accessible for **beginners, educators, and advanced users**.

**-Beginner Level: Drag & Drop Programming (Blockly UI)**

* **Blockly-based visual programming** allows users to control motors and sensors without writing code.
* **Ideal for high school students and first-time robotics learners**.

Example: Move a motor forward for 5 seconds using Blockly.

**-Intermediate Level: Python API for Robotics Control**

* Write Python scripts to control motors, read sensors, and perform automated tasks.
* **Great for university projects, mechatronics coursework, and industrial training**.

Example:

```python
set_motor_speed(left_motor=50, right_motor=50)  # Move forward
time.sleep(2)  # Wait for 2 seconds
stop_motors()  # Stop movement
```

#### **-Advanced Level: AI, IoT & Industry 4.0 Applications**

* Implement **PID control algorithms** for smooth motion.
* Integrate **AI-based object tracking, real-time data logging, and IoT connectivity**.
* Example: Use machine learning for autonomous robot navigation.

## **Real-World Applications**

The **Acrome Education Kit** is designed for **academic learning, research, and prototyping**, with applications in:

**STEM Education & University Labs** – Robotics, automation, and programming courses.\
**Industrial Training** – Understanding **servo motors, stepper motors, and real-time control**.\
**AI & Machine Learning** – Develop **autonomous robots with sensor fusion**.\
**IoT & Smart Automation** – Create **smart home systems and automated machinery**.

## Assembly Guide

A detailed step-by-step assembly guide is available as a PDF document:

{% file src="/files/MmpoZGdvznKiTbGiCFn2" %}

## Codes

{% tabs %}
{% tab title="The Education Kit Project Python" %}
{% code lineNumbers="true" %}

```python
from smd.red import *

import os
import sys
from serial.tools.list_ports import comports
from platform import system
from colorama import Fore, Style
from tabulate import tabulate
from random import randint


id = 0
module_id = 1

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)

m.attach(Red(id))

try:
    print("Scanning process is starting...")
    connected_modules = m.scan_modules(id)
except serial.serialutil.PortNotOpenError:
    print("Please check the USB Gateway. If it's plugged, unplug and plug again.")
    input("\nPress enter to exit.")

if system() == "Windows":
    os.system('cls')

else:
    os.system('clear')

print(connected_modules)

def colorize_str(str, boolean):
    return f"{Fore.GREEN}{str} found!{Style.RESET_ALL}" if boolean else f"{Fore.RED}{str} not found.{Style.RESET_ALL}"

############### Module Test Functions ###############
########################################################################################################################

## Global variables ##
motor_speed = 0
servo_position = 0
old_pot = 0
new_pot = 0

latency = 0
######################
data = m.get_variables(id, [Index.Button_1, Index.Buzzer_1, Index.Distance_1, Index.IMU_1, Index.Joystick_1, Index.Light_1, Index.Pot_1, Index.RGB_1, Index.Servo_1, Index.QTR_1])
######################

def button_test(check:bool, button_state):
    if check:
        button_state = m.get_button(id, module_id)

        if button_state:
            R = randint(0,255)
            G = randint(0,255)
            B = randint(0,255)

            m.set_rgb(id, module_id, R, G, B)

        return button_state

    else:
        return f"{Fore.RED}Not Connected{Style.RESET_ALL}"

def buzzer_test(check:bool, button_state):
    if check:

        if button_state:
            freq = randint(100,4000)
            m.set_buzzer(id, module_id, freq)

            return f"Buzzer Frequency: {freq} Hz"

        else:
            return "Button is not pressed"
        
    else:
        return f"{Fore.RED}Not Connected{Style.RESET_ALL}"
        
def distance_test(check:bool, distance):
    if check:

        if distance > 30:
            distance = 0

        elif 20 <= distance <= 30 and distance != 0:

            R = 0
            G = 255
            B = 0

            m.set_rgb(id, module_id, int(R), int(G), int(B))
            m.set_buzzer(id, module_id, 400)

        elif 10 <= distance < 20 and distance != 0:

            R = 255
            G = 55
            B = 0

            m.set_rgb(id, module_id, int(R), int(G), int(B))
            m.set_buzzer(id, module_id, 800)

        elif 0 <= distance < 10 and distance != 0:

            R = 255
            G = 0
            B = 0

            m.set_rgb(id, module_id, int(R), int(G), int(B))
            m.set_buzzer(id, module_id, 1200)

        return distance
    
    else:
        return f"{Fore.RED}Not Connected{Style.RESET_ALL}"

def imu_test(check:bool, imu):
    if check:
        return imu
    
    else:
        return f"{Fore.RED}Not Connected{Style.RESET_ALL}"

def joystick_test(check:bool, joystick_data):
    if check:

        global motor_speed

        if joystick_data[0] > 10 or joystick_data[0] < -10:
            m.set_duty_cycle(id, joystick_data[0])
            motor_speed = joystick_data[0]

        elif 0 <= joystick_data[0] < 10 or 0 >= joystick_data[0] > -10:
            m.set_duty_cycle(id, 0)
            motor_speed = joystick_data[0]

        return f"X: {joystick_data[0]}   Y: {joystick_data[1]}   Button: {joystick_data[2]}  Motor Speed: {motor_speed}"
    
    else:
        return f"{Fore.RED}Not Connected{Style.RESET_ALL}"

def light_test(check:bool, ambient_light):
    if check:

        ambient_light = m.get_light(id, module_id)

        if ambient_light < 150:
            m.set_rgb(id, module_id, 255, 255, 255)

        elif ambient_light > 300:
            m.set_rgb(id, module_id, 0, 0, 0)

        return ambient_light
    
    else:
        return f"{Fore.RED}Not Connected{Style.RESET_ALL}"
    
def pot_test(check:bool, pot):
    if check:
        global old_pot
        global new_pot

        old_pot = new_pot
        potentiometer_data = pot
        new_pot = potentiometer_data
        delta_pot = abs(new_pot - old_pot)

        if potentiometer_data <= 180 and delta_pot > 5:
            m.set_servo(id, module_id, potentiometer_data)
        
        elif potentiometer_data > 180 and delta_pot > 5:
            m.set_servo(id, module_id, 180)

        return potentiometer_data
    
    else:
        return f"{Fore.RED}Not Connected{Style.RESET_ALL}"


def rgb_test(check:bool, button_data):
    if check:

        button_data = m.get_button(id, module_id)

        if button_data:
            
            R = randint(0,255)
            G = randint(0,255)
            B = randint(0,255)

            m.set_rgb(id, module_id, R, G, B)
            time.sleep(0.02)

            return f"R: {R} G: {G} B: {B}"
        
        else:
            return "Button is not pressed"

    else:
        return f"{Fore.RED}Not Connected{Style.RESET_ALL}"


def servo_test(check:bool, imu_data):

    if check:

        global servo_position

        try:
            imu_data = imu_data[0]
            servo_position = (((imu_data + 90) * 180) / 180)

            if imu_data > 5 or imu_data < -5:
                m.set_servo(id, module_id, int(servo_position))

        except:
            pass

        return servo_position
    
    else:
        return f"{Fore.RED}Not Connected{Style.RESET_ALL}"


def qtr_test(check:bool, qtr_data):

    if check:

        if qtr_data[0] < 50:
            m.set_buzzer(id, module_id, 262)    # C4

        elif qtr_data[1] < 50:
            m.set_buzzer(id, module_id, 294)    # D4

        elif qtr_data[2] < 50:
            m.set_buzzer(id, module_id, 330)    # E4

        else:
            m.set_buzzer(id, module_id, 0)      # Empty note

        return qtr_data
    
    else:
        return f"{Fore.RED}Not Connected{Style.RESET_ALL}"


########################################################################################################################

############### Module Connection Check ###############
########################################################################################################################

BUTTON_check	= False
BUZZER_check	= False
DISTANCE_check	= False
IMU_check		= False
JOYSTICK_check	= False
LIGHT_check		= False
POT_check	    = False
RGB_check	    = False
SERVO_check		= False
QTR_check	    = False

try:
    if ("Button_" + str(module_id)) in connected_modules:
        BUTTON_check = True

    if ("Buzzer_" + str(module_id)) in connected_modules:
        BUZZER_check = True

    if ("Distance_" + str(module_id)) in connected_modules:
        DISTANCE_check = True

    if ("IMU_" + str(module_id)) in connected_modules:
        IMU_check = True

    if ("Joystick_" + str(module_id)) in connected_modules:
        JOYSTICK_check = True

    if ("Light_" + str(module_id)) in connected_modules:
        LIGHT_check = True

    if ("Pot_" + str(module_id)) in connected_modules:
        POT_check = True

    if ("RGB_" + str(module_id)) in connected_modules:
        RGB_check = True

    if ("Servo_" + str(module_id)) in connected_modules:
        SERVO_check = True

    if ("QTR_" + str(module_id)) in connected_modules:
        QTR_check = True

except:
    print("\nNO MODULES CONNECTED!\n")

module_check_data = [["Button module", colorize_str("Button module", BUTTON_check)],
                     ["Buzzer module", colorize_str("Buzzer module", BUZZER_check)],
                     ["Distance module", colorize_str("Distance module", DISTANCE_check)],
                     ["IMU module", colorize_str("IMU module", IMU_check)],
                     ["Joystick module", colorize_str("Joystick module", JOYSTICK_check)],
                     ["Light module", colorize_str("Light module", LIGHT_check)],
                     ["Potentiometer module", colorize_str("Pot module", POT_check)],
                     ["RGB module", colorize_str("RGB module", RGB_check)],
                     ["Servo module", colorize_str("Servo module", SERVO_check)],
                     ["QTR module", colorize_str("QTR module", QTR_check)]]

module_check_table = tabulate(module_check_data, headers=['Modules', 'States'], tablefmt="rounded_grid")

print(module_check_table)

########################################################################################################################

test_input = str(input("Press enter to start the test, write 'exit' to close the program: "))

if test_input == "exit":
    sys.exit()

else:
    m.set_operation_mode(id, 0)
    m.enable_torque(id, 1)
    pass


while True:
    data = m.get_variables(id, [Index.Button_1, Index.Distance_1, Index.IMU_1, Index.Joystick_1, Index.Light_1, Index.Pot_1, Index.QTR_1])
    
    test_result = [ ["Button module", button_test(BUTTON_check, data[0])],
                    ["Buzzer module", buzzer_test(BUZZER_check, data[0])],
                    ["Distance module", distance_test(DISTANCE_check, data[1])],
                    ["IMU module", imu_test(IMU_check, data[2])],
                    ["Joystick module", joystick_test(JOYSTICK_check, data[3])],
                    ["Light module", light_test(LIGHT_check, data[4])],
                    ["Potentiometer module", pot_test(POT_check, data[5])],
                    ["RGB module", rgb_test(RGB_check, data[0])],
                    ["Servo module", servo_test(SERVO_check, data[2])],
                    ["QTR module", qtr_test(QTR_check, data[6])]]

    test_table = tabulate(test_result, headers=["Modules", "Results"], tablefmt="rounded_grid")

    if system() == "Windows":
        os.system('cls')
    
    else:
        os.system('clear')

    print(test_table)
    
```

{% endcode %}
{% endtab %}

{% tab title="The Education Kit Project Arduino" %}
{% code lineNumbers="true" fullWidth="true" %}

```cpp
#include "Acrome-SMD.h"

#define ID          0
#define BAUDRATE    115200
#define MODULE_ID   1

#define MAX_DISTANCE    30
#define JOYSTICK_DEADZONE 10
#define LIGHT_THRESHOLD_LOW 150
#define LIGHT_THRESHOLD_HIGH 300
#define MAX_SERVO_ANGLE 180
#define POT_DELTA_THRESHOLD 5

Red master(ID, Serial, BAUDRATE);

int servo_position = 0;
int old_pot = 0;
int new_pot = 0;

bool BUTTON_check = true;
bool BUZZER_check = true;
bool DISTANCE_check = true;
bool IMU_check = true;
bool JOYSTICK_check = true;
bool LIGHT_check = true;
bool POT_check = true;
bool RGB_check = true;
bool SERVO_check = true;
bool QTR_check = false;

void setup() {
    master.begin();
}

void loop() {
    // Button and RGB Test
    if (BUTTON_check && RGB_check) {
        if (master.getButton(MODULE_ID)) {
            master.setRGB(MODULE_ID, random(256), random(256), random(256));
        }
    }

    // Buzzer Test
    if (BUZZER_check) {
        if (master.getButton(MODULE_ID)) {
            master.setBuzzer(MODULE_ID, random(100, 4000));
        } else {
            master.setBuzzer(MODULE_ID, 0);
        }
    }

    // Distance Test
    if (DISTANCE_check) {
        int distance = master.getDistance(MODULE_ID);
        if (distance <= MAX_DISTANCE) {
            if (distance > 20) {
                master.setRGB(MODULE_ID, 0, 255, 0);
                master.setBuzzer(MODULE_ID, 400);
            } else if (distance > 10) {
                master.setRGB(MODULE_ID, 255, 55, 0);
                master.setBuzzer(MODULE_ID, 800);
            } else {
                master.setRGB(MODULE_ID, 255, 0, 0);
                master.setBuzzer(MODULE_ID, 1200);
            }
        }
    }

    // IMU and Servo Test
    if (IMU_check && SERVO_check) {
        float roll = master.getRollAngle(MODULE_ID);
        if (abs(roll) > 5) {
            servo_position = ((roll + 90) * 180) / 180;
            master.setServo(MODULE_ID, servo_position);
        }
    }

    // Joystick Test
    if (JOYSTICK_check) {
        int joystickX = master.getJoystickX(MODULE_ID);
        master.setOperationMode(0);
        master.torqueEnable(1);
        if (abs(joystickX) > JOYSTICK_DEADZONE) {
            master.setpoint(0,float(joystickX));
        } else {
            master.setpoint(0,0);
        }
    }

    // Light Test
    if (LIGHT_check && RGB_check) {
        int lightLevel = master.getLight(MODULE_ID);
        if (lightLevel < LIGHT_THRESHOLD_LOW) {
            master.setRGB(MODULE_ID, 255, 255, 255);
        } else if (lightLevel > LIGHT_THRESHOLD_HIGH) {
            master.setRGB(MODULE_ID, 0, 0, 0);
        }
    }

    // Potentiometer and Servo Test
    if (POT_check && SERVO_check) {
        old_pot = new_pot;
        new_pot = master.getPotentiometer(MODULE_ID);
        if (abs(new_pot - old_pot) > POT_DELTA_THRESHOLD) {
            master.setServo(MODULE_ID, min(new_pot, MAX_SERVO_ANGLE));
        }
    }

    // QTR Test
    if (QTR_check && BUZZER_check) {
        QTRValues qtrData = master.getQTR(MODULE_ID);
        if (qtrData.LeftValue < 50) {
            master.setBuzzer(MODULE_ID, 262);
        } else if (qtrData.MiddleValue < 50) {
            master.setBuzzer(MODULE_ID, 294);
        } else if (qtrData.RightValue < 50) {
            master.setBuzzer(MODULE_ID, 330);
        } else {
            master.setBuzzer(MODULE_ID, 0);
        }
    }
    
    delay(10);
}
```

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


# What You Can Build

Explore the projects and applications you can create using the components in the Education Kit:

* [**Blink**](/smd-applications/basics/blink)\
  A basic LED blinking application to understand digital output control.

* [**Action - Reaction**](/smd-applications/basics/action-reaction)\
  Demonstrates immediate response to sensor-triggered input.

* [**Autonomous Lighting**](/smd-applications/basics/autonomous-lighting)\
  Automatically turns on lights based on environmental conditions.

* [**Smart Doorbell**](/smd-applications/basics/smart-doorbell)\
  A doorbell system integrated with sensors and feedback mechanisms.

* [**Security System**](/smd-applications/basics/security-system)\
  Motion detection–based system for basic security alerts.

* [**Distance Buzzer Warning**](/smd-applications/basics/distance-buzzer-warning)\
  Activates a buzzer when an object is detected within a certain range.

* [**Distance Auto Stop**](/smd-applications/basics/distance-auto-stop)\
  Stops the robot automatically when an obstacle is too close.

* [**Smart Light Control**](/smd-applications/basics/smart-light-control)\
  Controls lighting intelligently based on user presence or input.

* [**Automatic Trash Bin**](/smd-applications/interactive/automatic-trash-bin)\
  Opens the bin lid automatically when motion is detected.

* [**Radar**](/smd-applications/interactive/radar)\
  Visual representation of distance data from ultrasonic sensors.

* [**Chrome Dino Game Player**](/smd-applications/interactive/chrome-dino-game-player)\
  A system that plays the Chrome Dino game autonomously.

* [**Play Chrome Dino Game With Joystick**](/smd-applications/interactive/play-chrome-dino-game-with-joystick)\
  Manual gameplay using a joystick connected to the kit.

* [**Snake Game With Joystick**](/smd-applications/interactive/snake-game-with-joystick)\
  Classic Snake game controlled via a hardware joystick.

* [**Rev Up the Engine**](/smd-applications/interactive/rev-up-the-engine)\
  Simulates engine revving based on user input or conditions.

* [**Motor Rotation Based on Turn Input Value**](/smd-applications/interactive/motor-rotation-based-on-turn-input-value)\
  Rotates motor proportionally to a control input value.

* [**Basic Motor Speed Control Application**](/smd-applications/interactive/basic-motor-speed-control-application)\
  Controls the motor speed using analog or digital input.

* [**Basic Motor Control Application Using PWM Input**](/smd-applications/interactive/basic-motor-control-application-using-pwm-input)\
  Uses PWM signals to control motor speed and direction.

* [**Basic Motor Position Control Application**](/smd-applications/interactive/basic-motor-position-control-application)\
  Moves the motor to a desired position using encoder feedback.

* [**Basic Motor Torque Control Application**](/smd-applications/interactive/basic-motor-torque-control-application)\
  Controls the torque applied to the motor shaft.

* [**Motor Rotation Based on Joystick Counting**](/smd-applications/interactive/motor-rotation-based-on-joystick-counting)\
  Counts joystick movement and rotates motor accordingly.


# Motion Kit

The Acrome Motion Kit is an advanced yet user-friendly educational platform designed for students, educators, and researchers who want to explore motion control, robotics, and automation. This modular system provides hands-on learning in motor control, sensor integration, and real-world industrial applications.

With its plug-and-play architecture, visual programming support, and multiple control options, the Motion Kit offers a powerful and flexible environment for learning, experimentation, and prototyping.

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

## Who Is It For?

The **Motion Kit** is designed to serve a broad spectrum of users ranging from beginners to advanced developers in robotics and control systems. Whether you're in an educational setting or working on a research project, the kit is tailored to provide maximum flexibility and learning depth.

#### &#x20;Students

Perfect for undergraduate and graduate students studying:

* Robotics
* Mechatronics
* Electrical/Electronics Engineering
* Mechanical Engineering
* Computer Science

It enables hands-on experience in topics like motion control, sensor integration, and embedded system programming.

#### Educators

Ideal for instructors and lab coordinators who want to:

* Demonstrate real-time control systems in action
* Deliver engaging laboratory sessions
* Run robotics workshops with ready-to-use hardware and software

#### Researchers

Suitable for academic and industrial researchers looking to:

* Prototype motion control systems
* Test control algorithms like PID, MPC, or fuzzy logic
* Validate robotics concepts in physical environments

#### Makers & Developers

Great for hobbyists and engineers who want to:

* Build custom robots
* Integrate with Raspberry Pi, AI models, or remote control apps
* Explore Python-based hardware development

## What’s Inside the Box?

Everything you need to start building right away:

2x [SMD RED](/electronics/smd-red) Smart Brushed Motor Driver with Speed, Position and Current Control Modes

2x [12V Brushed DC Motor with built-in encoder](/electronics/electrical-motors/brushed-dc-motors-bdc)

1x [USB Gateway Module](/electronics/gateway-modules/usb-gateway-module)

2x [Servo Module](/electronics/add-on-modules/servo-module) with 2x Servo Motor

1x [IMU Module](/electronics/add-on-modules/imu-module)

1x [Joystick Module](/electronics/add-on-modules/joystick-module)

1x [Ultrasonic Distance Sensor Module](/electronics/add-on-modules/ultrasonic-distance-sensor-module)

1x [Reflectance Sensor Module](/electronics/add-on-modules/reflectance-sensor-module)

1x [Buzzer Module](/electronics/add-on-modules/buzzer-module)

1x [RGB LED Module](/electronics/add-on-modules/rgb-led-module)

## Learn by Doing

The Motion Kit is fully compatible with:

* **SMD Blockly** – Drag-and-drop programming for absolute beginners
* **Python SDK** – Code and customize projects with real-time feedback

Use official sample codes or create your own—from the very first minute, you’ll be in full control of your hardware.

## Key Features

* **Sensor Integration** – Includes distance, light, and potentiometer sensors.
* **Multi-Platform Support** – Works with **Python GUI, Blockly UI, Flutter mobile app**.
* &#x20;**Hands-on Learning** – Designed for **educational labs, research projects, and industry training**.
* &#x20;**Wireless & USB Control** – Can be controlled via a **PC, tablet, or mobile device**.
* &#x20;**Open-Source & Customizable** – Supports advanced **Python scripting and API integrations**.

## **Software & Control Options**

The **Motion Kit** can be programmed and controlled using various methods:

#### **1. Blockly UI (Visual Programming)**

* Beginner-friendly **drag-and-drop** interface.
* Ideal for quick **robotics and motion control projects**.
* No coding skills required.

#### **2. Python GUI (Desktop Application)**

* **PyQt5-based** desktop app for real-time control.
* Offers a **structured and interactive** user interface.
* Suitable for both beginners and advanced users.

#### **3. Python CLI (Command-Line Control)**

* Provides **direct API access** for automation.
* Best for **developers and researchers** working with scripts.

#### **4. Flutter Mobile App (Wireless Control)**

* **Control via smartphone or tablet**.
* Supports **Bluetooth and Wi-Fi connectivity**.
* Great for **remote operation and IoT integration**.

## **Learning & Experimentation Topics**

With the Motion Kit, you can experiment with real-world applications in:

* DC Motor Speed & Position Control​ACROME SMD&#x20;
* Linear Actuation with Feedback
* PID Control & Motion Optimization​
* Sensor-Based Obstacle Avoidance​
* Manual vs. Automated Control Methods​
* Wireless Motor Control using Mobile Devices​
* Servo Positioning & Object Tracking

## **Example Project: Waypoint Tracker Robot**

The Waypoint Tracker Robot is a practical example of what can be built with the Motion Kit. It autonomously moves between predefined waypoints using real-time sensor data and motion planning algorithms.​

*Project Highlights*:

* **Autonomous Navigation**: Follows a sequence of waypoints efficiently.​
* **Sensor-Guided Control**: Uses IMU, encoders, and optional LiDAR for precise tracking.​
* **Path Optimization**: Implements motion control algorithms for smooth operation
* **Python Integration**: Compatible with advanced robotic frameworks.​

For detailed assembly instructions and further information, please refer to the [official documentation](/smd-applications/robotics/waypoint-tracker-robot)


# What You Can Build

The **Acrome SMD Motion Kit** is designed for users who want to explore advanced motor control, motion planning, and robotics. Below is a curated list of projects that can be built using the components in the Motion Kit:

**Motor Control Applications**

* [**Motor Rotation Based on Turn Input Value**](/smd-applications/interactive/motor-rotation-based-on-turn-input-value)\
  Rotate the motor proportionally to a sensor or input value.

* [**Basic Motor Speed Control Application**](/smd-applications/interactive/basic-motor-speed-control-application)\
  Adjust motor speed dynamically using analog or digital input.

* [**Basic Motor Control Using PWM Input**](/smd-applications/interactive/basic-motor-control-application-using-pwm-input)\
  Demonstrate motor speed and direction control using PWM signals.

* [**Basic Motor Position Control Application**](/smd-applications/interactive/basic-motor-position-control-application)\
  Move the motor to a target position using encoder feedback.

* [**Basic Motor Torque Control Application**](/smd-applications/interactive/basic-motor-torque-control-application)\
  Apply controlled torque to simulate real-world mechanical load behavior.

* [**Motor Rotation Based on Joystick Counting**](/smd-applications/interactive/motor-rotation-based-on-joystick-counting)\
  Control rotation based on cumulative joystick input steps.

**Advanced Robotics Applications**

* [**Mouse Cursor Tracker Motion Robot**](/smd-applications/robotics/mouse-cursor-tracker-motion-robot)\
  A robot that mirrors the movement of a computer mouse cursor.

* [**Waypoint Tracker Robot**](/smd-applications/robotics/waypoint-tracker-robot)\
  Follow a predefined set of coordinates to navigate the environment.

* [**Braitenberg Robot**](/smd-applications/robotics/braitenberg-robot)\
  Behavior-driven robot that responds to environmental stimuli.

* [**Line-Follower Robot**](/smd-applications/robotics/line-follower-robot)\
  Follows a black line on the ground using infrared sensors.

* [**Teleoperation Robot**](/smd-applications/robotics/teleoperation-robot)\
  Remotely control a robot using keyboard or joystick inputs.

* [**Obstacle Avoidance Robot**](/smd-applications/robotics/obstacle-avoidance-robot)\
  Detects and avoids obstacles using ultrasonic sensors.

* [**ESP32 Wireless Controlled Mobile Robot**](/smd-applications/robotics/esp32-wireless-controlled-mobile-robot)\
  A mobile robot controlled via Wi-Fi and a web/mobile interface.

* [**Object Tracking Robot**](/ai/object-tracking-robot)\
  Follows and tracks a moving object using a vision system.

* [**Groq Chatbot-Controlled Robot**](/ai/groq-chatbot-controlled-robot)\
  Control the robot using natural language input via Groq AI API.

* [**Teleoperation Robot with ROS**](/ros/teleoperation-robot-with-ros)\
  Remotely control a robot through ROS infrastructure and networking.


# Autonomous Kit

The **Autonomous Kit** is an all-in-one robotics platform for learning, building, and experimenting with intelligent autonomous systems. Designed for both education and research, it brings advanced capabilities like navigation, obstacle avoidance, and real-time sensor fusion into an easy-to-use and modular system.

## Who Is It For?

* **Educators & Students**: Ideal for classroom robotics, hands-on STEM education, and project-based learning.
* **University Labs & Researchers**: Supports complex robotics experiments, SLAM, AI, and ROS2 integration.
* **Makers & Developers**: A flexible platform for building autonomous robots and testing advanced algorithms.

Whether you're starting out or pushing the limits of robotic intelligence, the Autonomous Kit adapts to your needs.

## What’s Inside the Box?

Everything you need to start building right away:

1x Raspberry Pi

2x [SMD RED](/electronics/smd-red)

2x [12V Brushed DC Motor with built-in encoder](/electronics/electrical-motors/brushed-dc-motors-bdc)

1x [USB Gateway Module](/electronics/gateway-modules/usb-gateway-module)

1x [IMU Module](/electronics/add-on-modules/imu-module)

1x [Ultrasonic Distance Sensor Module](/electronics/add-on-modules/ultrasonic-distance-sensor-module)

1x [Buzzer Module](/electronics/add-on-modules/buzzer-module)

1x [RGB LED Module](/electronics/add-on-modules/rgb-led-module)

## Learn by Doing

The Autonomous Kit empowers you to:

* Program robots using Python or visual Blockly code
* Build real-time obstacle-avoiding systems
* Visualize sensor data and understand sensor fusion
* Design SLAM-based mapping solutions
* Prototype custom algorithms for decision-making and mobility

Hands-on learning meets real-world robotics.

## Key Features

* Fully integrated **sensor fusion system** (Ultrasonic, IMU, LIDAR)
* **Wireless (Wi-Fi/Bluetooth)** and **USB** communication
* Cross-platform interfaces: **Python, GUI, Blockly, Mobile App**
* Supports both **ESP32** and **Raspberry Pi**
* ROS2-ready for advanced robotics development
* Modular and open-source hardware/software

## Software & Control Options

* **Blockly UI**: Drag-and-drop programming for beginners
* **Python GUI**: Desktop interface with real-time motor and sensor visualization
* **Python Scripting API**: Full control over sensors and actuators
* **Flutter Mobile App** (optional): Control via smartphone over Wi-Fi or Bluetooth
* **ROS2 Integration**: Ideal for SLAM, navigation, and research applications (Raspberry Pi only)

## Learning & Experimentation Topics

* PID motor control algorithms
* Obstacle detection and avoidance
* Sensor fusion techniques (IMU + Ultrasonic + LIDAR)
* SLAM (Simultaneous Localization and Mapping)
* Autonomous navigation and path planning
* AI-based robot behavior (vision, logic, etc.)

## Example Project: SLAM Navigation Robot

**Overview**:\
Build a self-driving robot that maps its surroundings using LIDAR and navigates autonomously using real-time obstacle avoidance and path planning.

**Hardware Used**:

* 2× SMD Red Motor Drivers
* Ultrasonic Sensor
* IMU Sensor
* 360° LIDAR
* Raspberry Pi (recommended) or ESP32

**Software Stack**:

* Python SDK for control and decision logic
* GUI for live visualization
* ROS2 for SLAM and navigation stack integration

**Highlights**:

* LIDAR-based mapping
* Dynamic obstacle detection
* Real-time path correction using sensor feedback
* Expandable with a camera for visual SLAM or object tracking


# What You Can Build

Self-navigating delivery robot

Indoor mapping robot with LIDAR

Obstacle-avoiding mobile vehicle

Vision-enabled robot with object detection (optional camera)

Maze-solving or line-following smart robot

ROS2-compatible research platform


# Libraries

Acrome SMD can be used with Arduino, Python and Java programming environments. Instructions on how to install and use the libraries can be found on each library page.

{% content-ref url="/pages/eUeTsfRzgvgPJjI3pqKS" %}
[Python Library](/software/libraries/python-library)
{% endcontent-ref %}

{% content-ref url="/pages/dftej5a0rgLeSfwMlU7K" %}
[Arduino Library](/software/libraries/arduino-library)
{% endcontent-ref %}

{% content-ref url="/pages/aF3knROAbYCFrSJM38t1" %}
[Java Library](/software/libraries/java-library)
{% endcontent-ref %}

{% content-ref url="/pages/A2VpbHjKpSdFnw0rZ25l" %}
[Matlab Library](/software/libraries/matlab-library)
{% endcontent-ref %}


# Python Library

SMD Python library provides easy-to-use Python modules and methods to extensively use Acrome Smart Motion Device products. It's user friendly for programmers at any level who have desire to learn and countless projects in mind.

Whether you need simple tasks like changing the speed of each motor or more complex processes like precise positioning, PID auto-tuning etc., this library lets you do it with the versatility of Python. You can easily implement various motor control methods.

The library also enhances your projects by allowing easy integration with SMD sensor modules. This means that it allows you to perform numerous applications by using the necessary modules for your needs. It eliminates the hassle of integrating third-party sensors and their software modules into your system, thus improving the functionality and efficiency of your project.

All you need to develop your projects with the SMD is a computer capable of running your Python scripts.

### Installation

To use [Acrome Smart Motion Devices](https://acrome.net/product/smart-motor-drivers) with Python library, follow the installation steps below. The library is compatible with Python 3.x and can be installed on both Windows and Linux systems.

#### Prerequisites

Before you begin, make sure you have the following prerequisites:

* Python 3.x: [Python Official Website](https://www.python.org/downloads/)
* Pip (comes default with Python)

{% hint style="warning" %}
Beware that you should check the `pip` feature while installing Python 3.x. If you didn't, you always can install `pip` from the source for any OS.

<https://pip.pypa.io/en/stable/installation/>

{% endhint %}

`pip` installation with Python setup is demonstrated below for Windows.

<figure><img src="/files/C5oNlACFidX8gJXwuBIV" alt=""><figcaption><p><strong>Step 1: Customize installation</strong></p></figcaption></figure>

{% hint style="warning" %}
"Add python.exe to PATH" is necessary for using Python from any terminal.
{% endhint %}

<figure><img src="/files/xgjIoDnam0H3GT0cFhWT" alt=""><figcaption><p><strong>Step 2: Check the "pip"</strong></p></figcaption></figure>

You can check if `pip` is installed properly by typing this command in terminal of any OS:

```
pip --version
```

This command will return you the version and directory of `pip`, which means it is installed and ready to use.

&#x20;Once you have met the prerequisites, you can follow the steps for whichever OS you use.

{% tabs %}
{% tab title="Windows" %}

1. Open a Command Prompt with administrative privileges.
2. Install the SMD library using `pip` (Python package manager) by running the following command:

```
pip install acrome-smd
```

3. Wait until the installation is complete. Pip will automatically download and install the library and any required dependencies.
   {% endtab %}

{% tab title="Mac/Linux" %}

1. Open a terminal.
2. Install the SMD library using `pip` (Python package manager) by running the following command:

```
pip install acrome-smd
```

3. Wait until the installation is complete. Pip will automatically download and install the library and any required dependencies.
   {% endtab %}
   {% endtabs %}

### Verification of Installation

To verify that the SMD library has been successfully installed, open a Python interpreter and run the following command:

```python
import smd
import smd.red
```

If no errors are raised, the installation was successful.

For usage and more info, see our [Github](https://github.com/Acrome-Smart-Motor-Driver/python-library) page.

### Basic Use of the Python Library

First of all, PC and SMD connections should be made. Connect your [USB gateway module](/electronics/gateway-modules/usb-gateway-module) to your PC's USB port and connect your SMD to the gateway module with an RJ-11 cable. Lastly, connect a 12V adapter to supply power to the SMD.

There are basics to start programming with SMD Python library. First, the user needs to know the serial port (`COM...` or `/dev/tty...`) of the connected USB gateway module, COM3 as an example.&#x20;

Since SMD cards can be connected to each other, each of them can have a different ID by user's choice. However, an SMD Red has an ID of 0 by default. This value can be intentionally changed between 0 - 255 .

SMD can communicate with different baud rates, user may want to change baud rate depending on the needs of project. SMD Red has a default baud rate of 115200.

With all this information, the crucial part of coding can begin.

Here is the first part of the code:

{% code lineNumbers="true" fullWidth="false" %}

```python
from smd.red import *

SerialPort = "COM3"    # Serial port of the USB gateway module
baudrate = 115200      # Baud rate of the communication
ID = 0                 # ID of the SMD board

master = Master(SerialPort, baudrate)    # Defines the USB gateway module
master.attach(Red(ID))                   # Gives acces to the SMD of specified ID

```

{% endcode %}

This code snippet acts as a communication setup for SMD.

We defined baud rate as 115200 and ID as 0 (default SMD ID, if it wasn't changed), and used `Master`class to create an object named `master`, object name depends on user. Then, we used necessary parameters of `Master`class, which are serial port and baud rate.&#x20;

{% hint style="info" %}
Serial port value can be different device to device, so the user can change the code of the serial port as `COM...` or `/dev/tty...` according to the OS.
{% endhint %}

Then we can do our first application , PID auto-tune and velocity control, to practice with our library. You will need an SMD and a brushed DC motor, which are included in the [Starter Kit](/smd-kits/starter-kit).

We start with the communication setup, and then add the necessary motor control functions, which will be explained below.

{% code lineNumbers="true" fullWidth="false" %}

```python
from smd.red import *

SerialPort = "COM3"    # Serial port of the USB gateway module
baudrate = 115200      # Baud rate of the communication
ID = 0                 # ID of the SMD board

master = Master(SerialPort, baudrate)    # Defines the USB gateway module
master.attach(Red(ID))                   # Gives acces to the SMD of specified ID

master.set_operation_mode(ID, OperationMode.Velocity)    # Sets the motor's operation mode as "Velocity"
master.set_shaft_rpm(ID, 100)        # Defines the motor RPM value as 100
master.set_shaft_cpr(ID, 6533)       # Defines the motor CPR value as 6533
master.pid_tuner(ID)                 # Starts the PID auto-tune process
time.sleep(30)    # Waits 30 seconds for the process to complete
print(master.get_control_parameters_velocity(ID))    # Prints the calculated PID values

master.enable_torque(ID, True)       # Enables motor to operate
master.set_velocity(ID, 50)          # Sets motor to operate at 50 RPM
```

{% endcode %}

{% hint style="info" %}
You should specify the ID of the target SMD when using functions, in this application there is only one SMD and it has an ID of 0, which is also defined as `ID` variable.
{% endhint %}

There are various operation modes for motor control,  for example, we have selected "Velocity" control mode, which allows the motor to be controlled in terms of RPM value.

Then, we specified the RPM and CPR value of motor, in order to be tuned properly. Brushed DC motor in [Starter Kit](/smd-kits/starter-kit) has 100 RPM and 6533 CPR value.

To run the PID auto-tune process, we use the `pid_tuner()` function with the ID of the target SMD. After running the function, the motor will start spinning and the process will take about 30 seconds. That's why we put the `time.sleep(30)` in order to wait for any other processes before the end of the process. The calculated PID values are printed with the `get_control_parameters_...()` function, the last part of function name changes with the operation mode of the motor, which in our application is "Velocity".

For all detailed function and feature explanations of Python library, visit the [Python library GitHub page](https://github.com/Acrome-Smart-Motor-Driver/python-library).

For more use cases, visit the projects and see the Python codes:

{% content-ref url="/pages/D8GfFqH2K1UZoTG9H6Qg" %}
[Broken mention](broken://pages/D8GfFqH2K1UZoTG9H6Qg)
{% endcontent-ref %}


# Arduino Library

SMD Arduino library is designed to improve the mobility of your system by enabling the operation of SMD with Arduino. The library simplifies the process of programming various projects and gives lots of ways to control motors in your system. It also works seamlessly with all SMD modules, which gives more imagination for countless projects.

The Arduino library can be used directly with Arduino IDE. It is user friendly as well as Arduino, familiarity and ease of programming an Arduino project with your Arduino and precise motor control  availability is indispensable for makers.

### Installation

To use [Acrome Smart Motion Devices](https://acrome.net/product/smart-motor-drivers) with Arduino library, follow the installation steps below.

#### Prerequisities

Before you begin, make sure you have the following prerequisities:

* Latest [Arduino IDE](https://www.arduino.cc/en/software) (click to download)
* Any programmable Arduino board

Once you have met the prerequisites, you can follow the steps.

1. Open Arduino IDE
2. In the Arduino IDE, go to `Sketch` -> `Include Library` -> `Manage Libraries...` or simply click the book stack icon on the left, and search for Acrome-SMD in the search bar.
3. Click "Install".

<figure><picture><source srcset="/files/9cQ2e5CX8XxPYhB3uOz6" media="(prefers-color-scheme: dark)"><img src="/files/mWVofqmWkxFEz8jHpbBv" alt=""></picture><figcaption><p>Arduino SMD Library</p></figcaption></figure>

### Verification of Installation

To verify that Arduino library successfully installed, open Arduino IDE and open a new sketch. Type this code line into your first line of sketch as shown in the image below, then click "Verify" button on the top left.

```cpp
#include <Acrome-SMD.h>
```

<figure><picture><source srcset="/files/P1TwK1wQmlVuGdr9394n" media="(prefers-color-scheme: dark)"><img src="/files/OKXhBX0YJwjcoIx8zDNG" alt=""></picture><figcaption><p>Arduino Library Verification</p></figcaption></figure>

## Basic Use of Arduino Library

First of all, the Arduino and SMD connections should be made. Connect your Arduino to the PC and place the [Arduino gateway module](/electronics/gateway-modules/arduino-gateway-module) on your Arduino board as the front two pins of the module should meet with the RX-TX pins and analog pins of module should sit on the analog pin slots. Then, connect SMD to the Arduino gateway module with an RJ-11 cable. Finally, connect a 12V adapter to supply power to the SMD.

Since SMD cards can be connected to each other, each of them can have a different ID by user's choice. However, an SMD Red has an ID of 0 by default. This value can be intentionally changed between 0 - 255 .

SMD can communicate with different baud rates, user may want to change baud rate depending on the needs of the project. SMD Red has a default baud rate of 115200.

With all this information, the crucial part of coding can begin.

Here is the first part of the code:

{% code lineNumbers="true" %}

```cpp
#include <Acrome-SMD.h>

#define ID        0        // ID of the SMD board
#define BAUDRATE  115200   // Baud rate of the communication


Red master(ID, Serial, BAUDRATE);    // Defines the Arduino gateway module

void setup() {

}

void loop() {

}
```

{% endcode %}

This code snippet acts as a communication setup for SMD.

We defined baud rate as 115200 and ID as 0 (default SMD ID, if it wasn't changed), and used `Red` class to create an object named `master`, object name depends on user. Then, we used necessary parameters of `Red` class, which are ID, Serial (communication with Arduino), and baud rate.

Then we can do our first application , PID auto-tune and velocity control, to practice with our library. In addition to the Arduino board, you will need an SMD, Arduino gateway module, and a brushed DC motor, which are included in the [Starter Kit](https://acrome.gitbook.io/acrome-smd-docs/~/changes/lDxbzVdDGe9259bNHBG1/applications/kits/starter-kit).

We start with the communication setup, and then add the necessary motor control functions, which will be explained below.

{% code lineNumbers="true" %}

```cpp
#include <Acrome-SMD.h>

#define ID        0        // ID of the SMD board
#define BAUDRATE  115200   // Baud rate of the communication

Red master(ID, Serial, BAUDRATE);    // Defines the Arduino gateway module

void setup() {
    master.begin();    // Starts the communication
    
    master.setMotorRPM(100);      // Defines the motor RPM value as 100
    master.setMotorCPR(6533);     // Defines the motor CPR value as 6533
    master.setOperationMode(VelocityControl);    // Sets the motor's operation mode as "Velocity"
    master.torqueEnable(1);       // Enables motor to operate
    
    master.tune();    // Starts the PID auto-tune process
    delay(30000);     // Waits 30 seconds for the process to complete
}

void loop() {
    
}
```

{% endcode %}

There are various operation modes for motor control, for example, we have selected "Velocity" control mode, which allows the motor to be controlled in terms of RPM value.

Then, we specified the RPM and CPR value of motor, in order to be tuned properly. Brushed DC motor in [Starter Kit](https://acrome.gitbook.io/acrome-smd-docs/~/changes/lDxbzVdDGe9259bNHBG1/applications/kits/starter-kit) has 100 RPM and 6533 CPR value.

To run the PID auto-tune process, we use the `tune()` function with the object name of the target SMD. After running the function, the motor will start spinning and the process will take about 30 seconds. That's why we put the `delay(30000)` in order to wait for any other processes before the end of the process.

For all detailed function and feature explanations of Arduino library, visit the [Arduino library GitHub page](https://github.com/Acrome-Smart-Motor-Driver/SMD-Arduino-Library).

For more use cases, visit the projects and see the Arduino codes:

{% content-ref url="/pages/D8GfFqH2K1UZoTG9H6Qg" %}
[Broken mention](broken://pages/D8GfFqH2K1UZoTG9H6Qg)
{% endcontent-ref %}


# Java Library

Documentation coming soon!

[GitHub Link of the Java Library](https://github.com/Acrome-Smart-Motor-Driver/java-library)


# Matlab Library

Matlab is a high-level programming and numerical computing environment developed for engineers and scientists. It is widely used for tasks such as data analysis, signal and image processing, control system design, wireless communications, and robotics. The platform combines a powerful programming language with interactive applications, specialized toolboxes, and built-in capabilities for automatically generating embedded code.

Watch the video below or read the text, and download the User Manual to learn more about the usage process.

## <mark style="color:red;">SMD Starter Kit with Matlab/Simulink Software</mark>

{% embed url="<https://youtu.be/ClOhNYZM6tk>" %}

### MATLAB/Simulink Setup and Control

The MATLAB/Simulink approach allows for graphical modeling and simulation of your control system.

#### Prerequisites

Before you begin, ensure you have the following software installed:

1. MATLAB and Simulink
2. Instrument Control Toolbox (Required for serial communication)
3. Simulink Desktop Real-Time (Required for real-time execution)

#### Initial Setup Steps

1. File Preparation: Copy the "SimulinkModelSMD" folder to a local drive on your computer (e.g., under C:\\).
2. Connections:
   * Connect the USB Gateway Module to your PC's USB port.
   * Connect the SMD RED board to the gateway module using an RJ-11 cable.
   * Connect the 12V adapter to supply power to the SMD.
3. Identify COM Port: Check your computer's Device Manager -> Ports to determine the serial port name assigned to the USB Gateway Module (e.g., 'COM4').

While your request uses the format for the Python library, the information below details the corresponding initial setup and parameters required to begin working with the SMD MATLAB/Simulink interface, based on the file content.

***

#### Initial Setup for SMD MATLAB/Simulink

First of all, PC and SMD connections should be made. Connect your USB gateway module to your PC's USB port and connect your SMD to the gateway module with an RJ-11 cable. Lastly, connect a 12V adapter to supply power to the SMD.

To start controlling the SMD with MATLAB, the user needs to know several key parameters:

* Serial Port: The user needs to know the serial port (e.g., COM... or /dev/tty...) of the connected USB gateway module. For example, 'COM4' is a typical value for Windows systems.
* SMD ID: Since SMD cards can be connected to each other, each of them can have a different ID by user's choice. However, an SMD Red has an ID of 0 by default. This value can be intentionally changed between 0 - 255.
* Operation Mode: The user must specify the desired operation mode (e.g., 'velocity', 'position', or 'main') to the StartSMD function, which launches the correct Simulink interface.

With all this information, the crucial part of launching the control interface can begin using the StartSMD function in the MATLAB Command Window.

{% file src="/files/eKdRyHoFkRomP2jenGB3" %}

##


# SMD UI

Smart User Interface of SMD

### [⬇️ Download Link for the SMD UI](https://github.com/Acrome-Smart-Motion-Devices/SMD-UI/blob/main/Acrome%20SMD%20UI%20v0.11.exe)

### Home Page

<figure><img src="/files/LnR5MhWKPZWehqOALO2m" alt=""><figcaption><p>SMD UI Home Page</p></figcaption></figure>

The SMD UI is the essential tool for controlling your SMD projects. It allows the user to control every aspect of SMD products. SMD UI allows the user to comprehensively test the SMD systems with different motor control methods and gives access to the functionality of all SMD modules.

<figure><img src="/files/22k9UyxuuNwCtvXm5iws" alt=""><figcaption></figcaption></figure>

Scanning process of SMD is quite simple.  The "Scan Ports" button lists the connected and open ports on the current PC, and if the [USB Gateway Module](/electronics/gateway-modules/usb-gateway-module) is connected, it automatically selects specific serial port (COM) that the USB Gateway has. Scanning process looks for each SMD module connected to the each SMD, and it lists modules under the SMD they are connected to.

### SMD Board Page

<figure><img src="/files/KkdzeFTmJBb6N3nYaInt" alt=""><figcaption><p>SMD Board Page</p></figcaption></figure>

SMD UI, provides an extensive control over the SMD. The user can change SMD's ID and baud rate according to project requirements. The "Blink" button serves as an indicator of which card is which ID when there are more than one SMD in a project, it flashes the indicator LED on the SMD board.

{% hint style="warning" %}
Each SMD should have a different ID before creating projects. The default ID is 0, if it is not changed and more than one SMD is connected, they will be seen as one SMD in the SMD UI.
{% endhint %}

Most importantly, the user can update the firmware of the board to keep up with the latest software updates and new features of the SMD.

### Motor Page

<figure><img src="/files/ABWmfpXXyddyQzaKxQQV" alt=""><figcaption><p>Configuration and Autotune Page</p></figcaption></figure>

The most authentic feature of the SMD is the autotune function for the motor. The user should enter the necessary parameters for the used motor. PID autotuning with these parameters allows to effectively control the motor with position and velocity modes . CPR and RPM values are as shown in the image for the motor inside the [Starter Kit](/smd-kits/starter-kit).&#x20;

The autotuning process takes about 30 seconds and then, after which the PID parameters are determined and can be viewed on the various motor drive pages. These parameters can be stored in the EEPROM, so that they are retained after power-off.

### PWM Motor Drive

<figure><img src="/files/veFWxY9eD5eXP1XLkuGH" alt=""><figcaption><p>PWM Drive Page</p></figcaption></figure>

The PWM motor drive mode allows the user to control the motor with mimicking analog values. This mode determines the motor speed with PWM duty cycle. Negative values are used to reverse the direction of rotation.

### Position Motor Drive

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

The position motor drive mode allows the user to control the position of the motor in terms of degrees. Position mode is especially important for precise control projects. Negative degree values are used to reverse the direction of rotation.

### Velocity Motor Drive

<figure><img src="/files/fS1zu5mbOMuoJafGr3lo" alt=""><figcaption><p>Velocity Drive Page</p></figcaption></figure>

The velocity motor drive mode allows the user to control the speed of the motor in terms of RPM. Velocity mode is especially cut out for robotic application with wheels. Negative RPM values are used to reverse the direction of rotation.


# SMD Blockly

The SMD RED Blockly application is a powerful and user-friendly platform designed for programming and controlling SMD devices through a visual programming interface. This application leverages several modern technologies and frameworks to provide an intuitive experience for users, making it accessible for both beginners and experienced developers.

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

You can download smd red blockly application from this link:&#x20;

### [⬇️ Download Link for the SMD Blockly](https://github.com/Acrome-Smart-Motion-Devices/SMD-Blockly)

## **Key Features and Technologies Used:**

1. Visual Programming with Blockly:\
   \
   The application utilizes Blockly, a web-based visual programming editor that allows users to create code by stacking blocks. This approach simplifies the coding process, making it easier for users to understand programming logic without needing to write traditional code.<br>
2. Responsive Design:\
   \
   The user interface is designed to be responsive, ensuring that it works seamlessly across various devices, including desktops, tablets, and smartphones. This is achieved through the use of Bootstrap, a popular CSS framework that provides a grid system and responsive utilities.<br>
3. Rich User Interface:\
   \
   The application features a clean and modern UI, enhanced by Font Awesome icons for better visual representation and user interaction. The use of Google Fonts, particularly the 'Inter' and 'JetBrains Mono' fonts, ensures that the text is both readable and aesthetically pleasing.<br>
4. Real-time Code Execution:\
   \
   Users can write and execute Python code directly within the application. The backend, powered by Flask, handles code execution and provides real-time feedback, allowing users to see the results of their code immediately.<br>
5. File Management:\
   \
   The application supports file operations, enabling users to download their block configurations as XML files and save their Python code as .py files. This feature is crucial for users who want to save their work and continue later.<br>
6. Error Handling and Notifications:\
   \
   The application includes robust error handling mechanisms that provide users with clear and informative messages when issues arise. Notifications are displayed using a visually appealing design, ensuring that users are always informed about the status of their actions.<br>
7. Cross-Origin Resource Sharing (CORS):\
   \
   The application implements CORS to allow secure communication between the frontend and backend, ensuring that data can be exchanged safely and efficiently.<br>

## **Conclusion**

SMD RED Blockly stands out as an innovative solution for programming SMD devices. By combining visual programming with a rich set of features and a user-friendly interface, it empowers users to create complex programs with ease. Whether you are a novice looking to learn programming or an experienced developer seeking a quick way to prototype ideas, SMD RED Blockly offers the tools and flexibility needed to succeed. The application not only simplifies the coding process but also enhances the overall learning experience, making it a valuable resource in the world of programming and robotics.


# Introducing Customized Blockly Blocks

## **Define Master Block**

This block enables the configuration of a USB gateway and its initialization with a user-selected baud rate. The baud rate can be conveniently chosen from a drop-down menu, ensuring flexibility and ease of use. The USB gateway serves as a critical communication bridge between the computer and the SMD Red system, facilitating seamless data exchange.

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

## **Smd Red Block**

This block establishes a connection to an SMD Red device by utilizing a specified Red ID parameter. The user is required to provide a valid Red ID to ensure accurate identification and communication with the target device.

<figure><img src="/files/8M9B8inog2hCOAhPFflw" alt=""><figcaption></figcaption></figure>

Above is the block structure for connecting to the smd red device with id value 0 and baudrate value 115200.

## **Set CPR Block**

This block is used to configure the **CPR (Counts Per Revolution)** value for a motor identified by a specified **Red ID**. The user provides the desired CPR value, which determines the resolution of the motor's encoder, ensuring precise control and measurement.

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

## **Set RPM Block**

This block is used to configure the **RPM (Revolutions Per Minute)** value for a motor identified by a specified **Red ID**. The user provides the desired RPM value, which controls the motor's rotational speed to meet application-specific requirements.

<figure><img src="/files/8YpoNLrLoe4MVvZfDDqU" alt=""><figcaption></figcaption></figure>

## **Define Motor Block**

This block is used to initialize and start a motor using its default parameters. To activate the motor, the user must provide the **Red ID**, which identifies the specific motor to be started.

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

## Set Control Parameters Block

This block allows you to configure the PID parameters dynamically for the specific mode you choose and the Red ID you input. By specifying the appropriate `mode` (Velocity, Position, Torque) and a unique Red ID, you can assign tailored values for the proportional (Kp), integral (Ki), and derivative (Kd) gains. The functionality ensures flexibility and precision for different control scenarios.

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

## Enable Torque Bloc

This block is designed to initiate the torque of an motor dynamically using a specified Red ID. By entering the appropriate Red ID, the system ensures precise activation of the torque mechanism, tailored to the corresponding motor.

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

## **Set Operation Mode Block**&#x20;

This block allows the user to set the operating mode for a motor identified by a specified **Red ID**. The user can select from one of the following modes: **PWM**, **Position**, **Speed**, or **Torque**, depending on the desired control strategy for the motor.

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

## Pwm Mode Blocks

These two blocks perform the same function, with the distinction that one accepts only **numerical values**, while the other accepts a **joystick variable block** as input. This flexibility allows users to choose the appropriate input method based on their specific application requirements.

<figure><img src="/files/6nx15x1ODa5SzsPXMm5Y" alt=""><figcaption></figcaption></figure>

## Position Mode Blocks

These two blocks perform the same function, but with different methods of control: one rotates the motor directly to the specified position (in degrees), while the other uses a joystick input block to control the rotation.

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

## Velocity Mode Blocks

These two blocks perform the same function, but with different methods of speed control: one rotates the motor at a constant speed based on a given value, while the other adjusts the speed dynamically using a joystick input.

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

## Torque Mode Blocks

These two blocks perform the same function, but with different methods for controlling the motor's current: one rotates the motor based on a fixed **milliampere** value, while the other adjusts the milliampere value dynamically using a joystick input.

<figure><img src="/files/3MaIrRZWArfvePeJVz0G" alt=""><figcaption></figcaption></figure>

## Get [Joystick](/electronics/add-on-modules/joystick-module) Block

This block receives **x**, **y**, and **button** information from the [joystick module](/electronics/add-on-modules/joystick-module) and synchronizes it with the corresponding variable blocks placed on the values within the block. This allows real-time control and interaction based on joystick input.

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

```python
Red_id = None
Module_id = None
X = None
Y = None
B = None


from smd.red import *
import math
import os

from serial.tools.list_ports import comports
from platform import system
def USB_Port():
    if system() == 'Windows':
        ports = list(comports())
        if ports:
            for port, desc, hwid in sorted(ports):
                if 'USB Serial Port' in desc:
                    SMD_Port = port
                    return SMD_Port

    elif system() == 'Linux':
        ports = list(serial.tools.list_ports.comports())
        if ports:
            for port, desc, hwid in sorted(ports):
                if '/dev/ttyUSB' in port:
                    SMD_Port = port
                    return SMD_Port

    elif system() == 'Darwin':  # macOS
        ports = list(serial.tools.list_ports.comports())
        if ports:
            for port, desc, hwid in sorted(ports):
                if '/dev/tty.usbserial' in port or '/dev/tty.usbmodem' in port:
                    SMD_Port = port
                    return SMD_Port

    else:
        SMD_Port = None
        return SMD_Port

port=USB_Port()
m = Master(port,baudrate=115200)
Red_id = 0
m.attach(Red(Red_id))

Module_id = 1
while True:
  X, Y, B = m.get_joystick(Red_id, Module_id)
```

## [RGB Led](/electronics/add-on-modules/rgb-led-module) Block

This block controls the [**RGB LED module**](/electronics/add-on-modules/rgb-led-module) by setting its color according to the **RGB values** entered. Users can specify the desired red, green, and blue values to customize the LED’s color output.

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

```python
Red_id = None
Module_id = None


from smd.red import *
import math
import os

from serial.tools.list_ports import comports
from platform import system
def USB_Port():
    if system() == 'Windows':
        ports = list(comports())
        if ports:
            for port, desc, hwid in sorted(ports):
                if 'USB Serial Port' in desc:
                    SMD_Port = port
                    return SMD_Port

    elif system() == 'Linux':
        ports = list(serial.tools.list_ports.comports())
        if ports:
            for port, desc, hwid in sorted(ports):
                if '/dev/ttyUSB' in port:
                    SMD_Port = port
                    return SMD_Port

    elif system() == 'Darwin':  # macOS
        ports = list(serial.tools.list_ports.comports())
        if ports:
            for port, desc, hwid in sorted(ports):
                if '/dev/tty.usbserial' in port or '/dev/tty.usbmodem' in port:
                    SMD_Port = port
                    return SMD_Port

    else:
        SMD_Port = None
        return SMD_Port

port=USB_Port()
m = Master(port,baudrate=115200)
Red_id = 0
m.attach(Red(Red_id))

Module_id = 1
m.set_rgb(Red_id, Module_id, 255, 0, 0)
```

## [Button ](/electronics/add-on-modules/button-module)Block

This block retrieves and returns the current **value** from the [**button module**](/electronics/add-on-modules/button-module), allowing the system to react based on the button's state (e.g., pressed or released).

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

```python
Red_id = None
Module_id = None
B = None


from smd.red import *
import math
import os

from serial.tools.list_ports import comports
from platform import system
def USB_Port():
    if system() == 'Windows':
        ports = list(comports())
        if ports:
            for port, desc, hwid in sorted(ports):
                if 'USB Serial Port' in desc:
                    SMD_Port = port
                    return SMD_Port

    elif system() == 'Linux':
        ports = list(serial.tools.list_ports.comports())
        if ports:
            for port, desc, hwid in sorted(ports):
                if '/dev/ttyUSB' in port:
                    SMD_Port = port
                    return SMD_Port

    elif system() == 'Darwin':  # macOS
        ports = list(serial.tools.list_ports.comports())
        if ports:
            for port, desc, hwid in sorted(ports):
                if '/dev/tty.usbserial' in port or '/dev/tty.usbmodem' in port:
                    SMD_Port = port
                    return SMD_Port

    else:
        SMD_Port = None
        return SMD_Port

port=USB_Port()
m = Master(port,baudrate=115200)
Red_id = 0
m.attach(Red(Red_id))

Module_id = 1
while True:
  B = m.get_button(Red_id, Module_id)
```

## [Ambient Light Sensor](/electronics/add-on-modules/ambient-light-sensor-module) Block

This block retrieves and returns the current **ambient light value**, allowing the system to adjust or react based on the surrounding light conditions.

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

```python
Red_id = None
Module_id = None
Light = None


from smd.red import *
import math
import os

from serial.tools.list_ports import comports
from platform import system
def USB_Port():
    if system() == 'Windows':
        ports = list(comports())
        if ports:
            for port, desc, hwid in sorted(ports):
                if 'USB Serial Port' in desc:
                    SMD_Port = port
                    return SMD_Port

    elif system() == 'Linux':
        ports = list(serial.tools.list_ports.comports())
        if ports:
            for port, desc, hwid in sorted(ports):
                if '/dev/ttyUSB' in port:
                    SMD_Port = port
                    return SMD_Port

    elif system() == 'Darwin':  # macOS
        ports = list(serial.tools.list_ports.comports())
        if ports:
            for port, desc, hwid in sorted(ports):
                if '/dev/tty.usbserial' in port or '/dev/tty.usbmodem' in port:
                    SMD_Port = port
                    return SMD_Port

    else:
        SMD_Port = None
        return SMD_Port

port=USB_Port()
m = Master(port,baudrate=115200)
Red_id = 0
m.attach(Red(Red_id))

Module_id = 1
while True:
  Light = m.get_light(Red_id,Module_id)
```

## [Ultrasonic Distance Sensor](/electronics/add-on-modules/ultrasonic-distance-sensor-module) Block

This block retrieves and returns the **distance value** measured by the [**ultrasonic distance sensor**](/electronics/add-on-modules/ultrasonic-distance-sensor-module), providing accurate readings of the proximity or distance to an object..

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

{% code lineNumbers="true" %}

```python
Red_id = None
Module_id = None
Distance = None


from smd.red import *
import math
import os

from serial.tools.list_ports import comports
from platform import system
def USB_Port():
    if system() == 'Windows':
        ports = list(comports())
        if ports:
            for port, desc, hwid in sorted(ports):
                if 'USB Serial Port' in desc:
                    SMD_Port = port
                    return SMD_Port

    elif system() == 'Linux':
        ports = list(serial.tools.list_ports.comports())
        if ports:
            for port, desc, hwid in sorted(ports):
                if '/dev/ttyUSB' in port:
                    SMD_Port = port
                    return SMD_Port

    elif system() == 'Darwin':  # macOS
        ports = list(serial.tools.list_ports.comports())
        if ports:
            for port, desc, hwid in sorted(ports):
                if '/dev/tty.usbserial' in port or '/dev/tty.usbmodem' in port:
                    SMD_Port = port
                    return SMD_Port

    else:
        SMD_Port = None
        return SMD_Port

port=USB_Port()
m = Master(port,baudrate=115200)
Red_id = 0
m.attach(Red(Red_id))

Module_id = 1
while True:
  Distance = m.get_distance(Red_id,Module_id)
```

{% endcode %}

## [Buzzer ](/electronics/add-on-modules/buzzer-module)Block

This block activates the [**buzzer module**](/electronics/add-on-modules/buzzer-module) and sets it to emit sound at the **frequency** value entered by the user.

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

```python
Red_id = None
Module_id = None


from smd.red import *
import math
import os

from serial.tools.list_ports import comports
from platform import system
def USB_Port():
    if system() == 'Windows':
        ports = list(comports())
        if ports:
            for port, desc, hwid in sorted(ports):
                if 'USB Serial Port' in desc:
                    SMD_Port = port
                    return SMD_Port

    elif system() == 'Linux':
        ports = list(serial.tools.list_ports.comports())
        if ports:
            for port, desc, hwid in sorted(ports):
                if '/dev/ttyUSB' in port:
                    SMD_Port = port
                    return SMD_Port

    elif system() == 'Darwin':  # macOS
        ports = list(serial.tools.list_ports.comports())
        if ports:
            for port, desc, hwid in sorted(ports):
                if '/dev/tty.usbserial' in port or '/dev/tty.usbmodem' in port:
                    SMD_Port = port
                    return SMD_Port

    else:
        SMD_Port = None
        return SMD_Port

port=USB_Port()
m = Master(port,baudrate=115200)
Red_id = 0
m.attach(Red(Red_id))

Module_id = 1
m.set_buzzer(Red_id,Module_id,500)
```

## [IMU ](/electronics/add-on-modules/imu-module)Block

This block receives and processes data from the [**IMU (Inertial Measurement Unit)**](/electronics/add-on-modules/imu-module), which typically includes information such as orientation.

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

```python
Red_id = None
Module_id = None
Pitch = None
roll = None


from smd.red import *
import math
import os

from serial.tools.list_ports import comports
from platform import system
def USB_Port():
    if system() == 'Windows':
        ports = list(comports())
        if ports:
            for port, desc, hwid in sorted(ports):
                if 'USB Serial Port' in desc:
                    SMD_Port = port
                    return SMD_Port

    elif system() == 'Linux':
        ports = list(serial.tools.list_ports.comports())
        if ports:
            for port, desc, hwid in sorted(ports):
                if '/dev/ttyUSB' in port:
                    SMD_Port = port
                    return SMD_Port

    elif system() == 'Darwin':  # macOS
        ports = list(serial.tools.list_ports.comports())
        if ports:
            for port, desc, hwid in sorted(ports):
                if '/dev/tty.usbserial' in port or '/dev/tty.usbmodem' in port:
                    SMD_Port = port
                    return SMD_Port

    else:
        SMD_Port = None
        return SMD_Port

port=USB_Port()
m = Master(port,baudrate=115200)
Red_id = 0
m.attach(Red(Red_id))

Module_id = 1
roll, Pitch = m.get_imu(Red_id, Module_id)  
```

## Potentiometer Block

This block retrieves the **ADC (Analog-to-Digital Conversion)** value from the [**potentiometer modul**](/electronics/add-on-modules/potentiometer-module)**e**, providing a digital representation of the analog voltage output based on the potentiometer's position.

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

```python
Red_id = None
Module_id = None
pot = None


from smd.red import *
import math
import os

from serial.tools.list_ports import comports
from platform import system
def USB_Port():
    if system() == 'Windows':
        ports = list(comports())
        if ports:
            for port, desc, hwid in sorted(ports):
                if 'USB Serial Port' in desc:
                    SMD_Port = port
                    return SMD_Port

    elif system() == 'Linux':
        ports = list(serial.tools.list_ports.comports())
        if ports:
            for port, desc, hwid in sorted(ports):
                if '/dev/ttyUSB' in port:
                    SMD_Port = port
                    return SMD_Port

    elif system() == 'Darwin':  # macOS
        ports = list(serial.tools.list_ports.comports())
        if ports:
            for port, desc, hwid in sorted(ports):
                if '/dev/tty.usbserial' in port or '/dev/tty.usbmodem' in port:
                    SMD_Port = port
                    return SMD_Port

    else:
        SMD_Port = None
        return SMD_Port

port=USB_Port()
m = Master(port,baudrate=115200)
Red_id = 0
m.attach(Red(0))

Module_id = 1
pot = m.get_potentiometer(Red_id, Module_id)
```

## [Servo ](/electronics/add-on-modules/servo-module)Blocks

This block is used to set the position of a **servo motor** by specifying the desired angle. The motor adjusts its position to align with the given angle value.

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

```python
Red_id = None
Module_id = None


from smd.red import *
import math
import os

from serial.tools.list_ports import comports
from platform import system
def USB_Port():
    if system() == 'Windows':
        ports = list(comports())
        if ports:
            for port, desc, hwid in sorted(ports):
                if 'USB Serial Port' in desc:
                    SMD_Port = port
                    return SMD_Port

    elif system() == 'Linux':
        ports = list(serial.tools.list_ports.comports())
        if ports:
            for port, desc, hwid in sorted(ports):
                if '/dev/ttyUSB' in port:
                    SMD_Port = port
                    return SMD_Port

    elif system() == 'Darwin':  # macOS
        ports = list(serial.tools.list_ports.comports())
        if ports:
            for port, desc, hwid in sorted(ports):
                if '/dev/tty.usbserial' in port or '/dev/tty.usbmodem' in port:
                    SMD_Port = port
                    return SMD_Port

    else:
        SMD_Port = None
        return SMD_Port

port=USB_Port()
m = Master(port,baudrate=115200)
Red_id = 0
m.attach(Red(0))

Module_id = 1
m.set_servo(Red_id, Module_id, 90)
```

## [QTR ](/electronics/add-on-modules/reflectance-sensor-module)Block

This block retrieves the sensor values from the [**QTR** module](/electronics/add-on-modules/reflectance-sensor-module), typically used for detecting changes in proximity, position, or surface reflection.

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

```python
Red_id = None
Module_id = None
left = None
right = None
middle = None


from smd.red import *
import math
import os

from serial.tools.list_ports import comports
from platform import system
def USB_Port():
    if system() == 'Windows':
        ports = list(comports())
        if ports:
            for port, desc, hwid in sorted(ports):
                if 'USB Serial Port' in desc:
                    SMD_Port = port
                    return SMD_Port

    elif system() == 'Linux':
        ports = list(serial.tools.list_ports.comports())
        if ports:
            for port, desc, hwid in sorted(ports):
                if '/dev/ttyUSB' in port:
                    SMD_Port = port
                    return SMD_Port

    elif system() == 'Darwin':  # macOS
        ports = list(serial.tools.list_ports.comports())
        if ports:
            for port, desc, hwid in sorted(ports):
                if '/dev/tty.usbserial' in port or '/dev/tty.usbmodem' in port:
                    SMD_Port = port
                    return SMD_Port

    else:
        SMD_Port = None
        return SMD_Port

port=USB_Port()
m = Master(port,baudrate=115200)
Red_id = 0
m.attach(Red(0))

Module_id = 1
left, middle, right = m.get_qtr(Red_id, Module_id)
```

## Get Position Block

This block retrieves the current position of the motor identified by the specified **Red ID**. It allows the system to track and monitor the motor's position in real-time.

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

```python
Red_id = None
position = None


from smd.red import *
import math
import os

from serial.tools.list_ports import comports
from platform import system
def USB_Port():
    if system() == 'Windows':
        ports = list(comports())
        if ports:
            for port, desc, hwid in sorted(ports):
                if 'USB Serial Port' in desc:
                    SMD_Port = port
                    return SMD_Port

    elif system() == 'Linux':
        ports = list(serial.tools.list_ports.comports())
        if ports:
            for port, desc, hwid in sorted(ports):
                if '/dev/ttyUSB' in port:
                    SMD_Port = port
                    return SMD_Port

    elif system() == 'Darwin':  # macOS
        ports = list(serial.tools.list_ports.comports())
        if ports:
            for port, desc, hwid in sorted(ports):
                if '/dev/tty.usbserial' in port or '/dev/tty.usbmodem' in port:
                    SMD_Port = port
                    return SMD_Port

    else:
        SMD_Port = None
        return SMD_Port

port=USB_Port()
m = Master(port,baudrate=115200)
Red_id = 0
m.attach(Red(Red_id))

position = m.get_position(Red_id)
```


# Boardoza Sensors

{% hint style="info" %}
💡 Info: The Boardoza sensor family consists of industrial-grade modules specifically designed for Acrome robotic kits and prototyping projects.
{% endhint %}

<table data-view="cards"><thead><tr><th align="center"></th><th data-hidden data-card-cover data-type="image">Cover image</th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td align="center">HX711 Analog Digital Converter</td><td><a href="/files/iow4tgRfyVCu39Bxijii">/files/iow4tgRfyVCu39Bxijii</a></td><td><a href="/pages/Wpd7efoyL5tzSzYkuxLq">/pages/Wpd7efoyL5tzSzYkuxLq</a></td></tr><tr><td align="center">TPS63030 Single Inductor Buck-Boost Converter</td><td><a href="/files/wBUHQFR9sotfTBIM2wmE">/files/wBUHQFR9sotfTBIM2wmE</a></td><td><a href="/pages/s5BQ3xMTFNsDMVfV929o">/pages/s5BQ3xMTFNsDMVfV929o</a></td></tr><tr><td align="center">SM351LT Magnetoresistive Sensor Breakout Board</td><td><a href="/files/GvP499EEpvBS9yLTTqm9">/files/GvP499EEpvBS9yLTTqm9</a></td><td><a href="/pages/pgLziwSt34GmjayVjR0m">/pages/pgLziwSt34GmjayVjR0m</a></td></tr><tr><td align="center">TH09C Temp Sensor Breakout Board</td><td><a href="/files/uRELOQ7e4CAF7dBsI8es">/files/uRELOQ7e4CAF7dBsI8es</a></td><td><a href="/pages/5Xdfr2rkEsn6ZlA6fTDX">/pages/5Xdfr2rkEsn6ZlA6fTDX</a></td></tr><tr><td align="center">TPS630702RNMT Breakout Board</td><td><a href="/files/zfEo2OhwDcxVd9ySo603">/files/zfEo2OhwDcxVd9ySo603</a></td><td><a href="/pages/V6emNUlQBPhR4p46oc2b">/pages/V6emNUlQBPhR4p46oc2b</a></td></tr><tr><td align="center">GP-02 GPS Breakout Board</td><td><a href="/files/FgGD1dqM5gIbFcXCZMeT">/files/FgGD1dqM5gIbFcXCZMeT</a></td><td><a href="/pages/c3RsUHda5dQkUP6uZf8e">/pages/c3RsUHda5dQkUP6uZf8e</a></td></tr><tr><td align="center">W25Q40CLSNIG SPI Flash</td><td><a href="/files/DgnnueSlsvIQp8Ng3rS7">/files/DgnnueSlsvIQp8Ng3rS7</a></td><td><a href="/pages/TSSAMn0bZyuQmyP76U8E">/pages/TSSAMn0bZyuQmyP76U8E</a></td></tr><tr><td align="center">BNO055 IMU Sensor Breakout Board</td><td><a href="/files/c1Fj5WU1f28g2F606T5T">/files/c1Fj5WU1f28g2F606T5T</a></td><td><a href="/pages/cDUirVzeeqdS9mzXKWgG">/pages/cDUirVzeeqdS9mzXKWgG</a></td></tr><tr><td align="center">MS5611 Barometric Pressure Sensor</td><td><a href="/files/zP80SoeHIxKG1e0J0bah">/files/zP80SoeHIxKG1e0J0bah</a></td><td><a href="/pages/rgCxKMR6Fsyr6nm9c8dO">/pages/rgCxKMR6Fsyr6nm9c8dO</a></td></tr><tr><td align="center">Quectel FC41D BT &#x26; WiFi Module</td><td data-object-fit="contain"><a href="/files/nCDCHO8Bx07oFPmpGKsu">/files/nCDCHO8Bx07oFPmpGKsu</a></td><td><a href="/pages/yIIhDGJMpdFYzRCKxjfO">/pages/yIIhDGJMpdFYzRCKxjfO</a></td></tr><tr><td align="center">ADXL345 3-Axis Accelerometer Sensor</td><td data-object-fit="contain"><a href="/files/lBvuemfynYx7DpBQEpqG">/files/lBvuemfynYx7DpBQEpqG</a></td><td><a href="/pages/t4T8C5M4mO35FxpGErei">/pages/t4T8C5M4mO35FxpGErei</a></td></tr><tr><td align="center">LM75ADP Temperature Sensor</td><td data-object-fit="contain"><a href="/files/ygpoor6G7X1oI6NytPDd">/files/ygpoor6G7X1oI6NytPDd</a></td><td><a href="/pages/YInuk0sbSF4q34FcHrxw">/pages/YInuk0sbSF4q34FcHrxw</a></td></tr><tr><td align="center">BA6208 Motor Driver Breakout Board</td><td><a href="/files/x5sK2eJ7AC5bzjGO8GjG">/files/x5sK2eJ7AC5bzjGO8GjG</a></td><td><a href="/pages/yBH6O7PAWodE7LC91Mun">/pages/yBH6O7PAWodE7LC91Mun</a></td></tr><tr><td align="center">MQ-4 Methane Gas Sensor</td><td><a href="/files/9WcGxmif3KeSLRfjvxOn">/files/9WcGxmif3KeSLRfjvxOn</a></td><td><a href="/pages/919my5tWjfLOxMqNCFMh">/pages/919my5tWjfLOxMqNCFMh</a></td></tr><tr><td align="center">Ublox SAM-M8Q GPS Board</td><td data-object-fit="contain"><a href="/files/rVHJtf61BgoQXik8ujrg">/files/rVHJtf61BgoQXik8ujrg</a></td><td><a href="/pages/e8JLhqfFsakgDVFwNKLt">/pages/e8JLhqfFsakgDVFwNKLt</a></td></tr><tr><td align="center">ESP01M Wi-Fi Module</td><td><a href="/files/9Clpw76BJDj2iwweTEhX">/files/9Clpw76BJDj2iwweTEhX</a></td><td><a href="/pages/TWorE3TEVsOGjZuGGHOh">/pages/TWorE3TEVsOGjZuGGHOh</a></td></tr><tr><td align="center">MCP73831 Charge Management Controller</td><td><a href="/files/4dEt3QEZ97SeZDCnW9i2">/files/4dEt3QEZ97SeZDCnW9i2</a></td><td><a href="/pages/CS77vyvdgYgfjLQcGWSV">/pages/CS77vyvdgYgfjLQcGWSV</a></td></tr><tr><td align="center">MDBT50Q BLE Module</td><td data-object-fit="contain"><a href="/files/OI1bT9qtBpFkVB7cXrYf">/files/OI1bT9qtBpFkVB7cXrYf</a></td><td><a href="/pages/fb7xV3iQ9lTIP2tCTKRW">/pages/fb7xV3iQ9lTIP2tCTKRW</a></td></tr><tr><td align="center">MicroSD Breakout Board</td><td><a href="/files/xRKOrTGFfeYDOGpXuCWB">/files/xRKOrTGFfeYDOGpXuCWB</a></td><td><a href="/pages/KY2SGttBsTAY9J1ifM8N">/pages/KY2SGttBsTAY9J1ifM8N</a></td></tr><tr><td align="center">RFM6601W LoRa Module</td><td data-object-fit="contain"><a href="/files/DNWSbXmsJyPB9pJeXHpD">/files/DNWSbXmsJyPB9pJeXHpD</a></td><td><a href="/pages/VNKp7rN5ED8ADiADcV1y">/pages/VNKp7rN5ED8ADiADcV1y</a></td></tr><tr><td align="center">Vibration Motor Driver Breakout Board</td><td><a href="/files/0RIdNnz6i6JeLduLGlzY">/files/0RIdNnz6i6JeLduLGlzY</a></td><td><a href="/pages/BP717R6L7ma4sfaYOZvj">/pages/BP717R6L7ma4sfaYOZvj</a></td></tr><tr><td align="center">Pulse S32-S3 Development Board</td><td data-object-fit="contain"><a href="/files/LstborgfvDnhzclaLVwJ">/files/LstborgfvDnhzclaLVwJ</a></td><td><a href="/pages/sC3ZBe7FQI1UkoNBXhh8">/pages/sC3ZBe7FQI1UkoNBXhh8</a></td></tr></tbody></table>


# HX711 Analog Digital Converter (ADC)

### Overview

The Boardoza HX711 is a precision 24-bit analog-to-digital converter designed specifically for weigh scales and industrial control applications to interface directly with a bridge sensor. Built around the Avia Semiconductor HX711 architecture, this module integrates a low-noise programmable gain amplifier (PGA) and a regulated power supply, providing a complete "front-end" solution for load cells.

Unlike general-purpose ADCs, the HX711 is optimized for small-signal differential measurements. It eliminates the need for external active components by incorporating on-chip power supply regulators and an on-chip oscillator, drastically reducing the bill of materials and PCB footprint for high-precision force sensing systems.

***

|                                                            Front Side                                                           |                                                           Back Side                                                           |
| :-----------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------: |
| ![HX711 Front](https://github.com/Boardoza/Boardoza_HX711_Load_Cell_Amplifier_Breakout_Board/raw/main/assets/HX711%20Front.png) | ![HX711 Back](https://github.com/Boardoza/Boardoza_HX711_Load_Cell_Amplifier_Breakout_Board/raw/main/assets/HX711%20Back.png) |

<div align="left"><figure><img src="/files/A299EENm4ReyTF1As2ym" alt="" width="375"><figcaption></figcaption></figure></div>

***

### Core Technical Specifications

The module is defined by the following operational parameters:

* Resolution: 24-bit output precision, capable of resolving extremely minute voltage changes typical of strain gauge bridges.
* Input Channels: Features two selectable differential input channels (Channel A and Channel B). Channel A is programmable with a gain of 64 or 128, while Channel B has a fixed gain of 32.
* Low-Noise PGA: The integrated Programmable Gain Amplifier enables direct interfacing with low-output sensors (e.g., 2mV/V load cells) without requiring external instrumentation amplifiers.
* Data Rate: User-selectable output data rate of either 10 samples per second (SPS) for high stability or 80 SPS for faster response times.
* Power Supply Rejection: Simultaneous 50Hz and 60Hz supply rejection ensures measurement stability in electrically noisy industrial environments.
* Operating Voltage: Supports a wide supply range from 2.6V to 5.5V, making it compatible with both 3.3V and 5V logic systems.
* Current Consumption: Low operating current (<1.5 mA) and an integrated power-down mode (<1 µA) suitable for battery-powered scales.

***

### Key Engineering Features

#### Specialized Bridge Interface

The module is engineered to drive Wheatstone bridge sensors directly. It provides the excitation voltage (E+ and E-) and reads the differential signal voltage (A+ and A-). The on-chip analog power regulator simplifies the power distribution network, ensuring that the excitation voltage remains stable relative to the ADC reference, which is critical for ratiometric measurement accuracy.

#### Digital Interface Protocol

The HX711 utilizes a custom two-wire serial interface (Clock and Data) that is similar to, but not compatible with, standard SPI. This "bit-banging" protocol allows the host microcontroller to retrieve the 24-bit conversion result and simultaneously configure the gain and channel selection for the *next* conversion cycle via the number of clock pulses sent.

#### On-Chip Oscillator

The internal on-chip oscillator requires no external crystal or capacitor, simplifying board layout and reducing susceptibility to EMI. This robust clock generation ensures consistent timing for the Sigma-Delta modulator and digital filter stages.

***

### Board Pinout

#### J1 Connector

<table><thead><tr><th width="149.5703125" align="center">Pin Number</th><th align="center">Pin Name</th><th>Description</th></tr></thead><tbody><tr><td align="center">1</td><td align="center">VCC</td><td>2.7V - 5.5V Power Input</td></tr><tr><td align="center">2</td><td align="center">VDD</td><td>2.7V - 5.5V Power Input</td></tr><tr><td align="center">3</td><td align="center">DAT</td><td>Serial Data Output</td></tr><tr><td align="center">4</td><td align="center">CLK</td><td>Serial Clock Input</td></tr><tr><td align="center">5</td><td align="center">GND</td><td>Ground</td></tr></tbody></table>

#### J2 Connector

<table><thead><tr><th width="150.0234375" align="center">Pin Number</th><th align="center">Pin Name</th><th>Description</th></tr></thead><tbody><tr><td align="center">1</td><td align="center">B+</td><td>Positive Signal (Second Channel)</td></tr><tr><td align="center">2</td><td align="center">B-</td><td>Negative Signal (Second Channel)</td></tr></tbody></table>

#### J3 Connector (Load Cell Interface)

<table><thead><tr><th width="149.87890625" align="center">Pin Number</th><th align="center">Pin Name</th><th>Description</th></tr></thead><tbody><tr><td align="center">1</td><td align="center">RED/E+</td><td>+ Excitation</td></tr><tr><td align="center">2</td><td align="center">BLK/E-</td><td>- Excitation</td></tr><tr><td align="center">3</td><td align="center">WHT/A-</td><td>- Signal</td></tr><tr><td align="center">4</td><td align="center">GRN/A+</td><td>+ Signal</td></tr></tbody></table>

#### JP1 Jumper Settings

<table><thead><tr><th width="176.27734375" align="center">Pin Configuration</th><th>Data Rate</th></tr></thead><tbody><tr><td align="center">1-2</td><td>80 Samples per Second (SPS)</td></tr><tr><td align="center">2-3</td><td>10 Samples per Second (SPS)</td></tr></tbody></table>

***

### Applications

* Electronic Scales: Kitchen scales, bathroom scales, and postage meters.
* Industrial Weighing: Hopper scales, platform scales, and conveyor belt monitoring.
* Force Sensing: Strain gauge measurement for structural health monitoring.
* Tactile Sensors: Robotics pressure sensing and grip force feedback.

***

### Board Dimensions:

![HX711 Dimension](https://github.com/Boardoza/Boardoza_HX711_Load_Cell_Amplifier_Breakout_Board/raw/main/assets/HX711%20Dimension.png)

***

{% hint style="info" %}
Ready to integrate? You can purchase the **HX711 Analog Digital Converter** directly from our [Online Store](https://www.robotshop.com/products/acrome-load-cell-amplifier-board-hx711?qd=97fe14d7a62dbe4d77087959586fffc1). Worldwide shipping is available for engineering samples and production batches.
{% endhint %}


# TPS63030 Single Inductor Buck-Boost Converter

### Overview

The Boardoza TPS63030 is a high-efficiency power management module designed to regulate voltage from variable sources that fluctuate above and below the target output. Powered by the Texas Instruments TPS63030 engine, this Single Inductor Buck-Boost converter provides a seamless transition between step-down (buck) and step-up (boost) modes, ensuring a stable power rail without the dropout issues inherent to LDOs or the noise of dual-stage switchers.

Engineered for portable and battery-critical applications, the module utilizes a synchronous rectification topology to maximize energy conversion efficiency. It is particularly optimized for powering 3.3V logic from single-cell Lithium-Ion batteries (which range from 4.2V down to 2.8V) or dual-cell Alkaline configurations, extracting the full usable capacity of the energy source.

***

<div align="left"><figure><img src="/files/3vkoS6DTcGWeDTwfKYv4" alt="" width="375"><figcaption></figcaption></figure></div>

***

### Core Technical Specifications

The module is defined by the following operational parameters:

* Topology: High-frequency Synchronous Buck-Boost with a single inductor architecture.
* Input Voltage Range: Accepts a wide input spectrum from 1.8V to 5.5V DC, covering most standard battery chemistries (Li-Ion, Li-Po, 2xAA/AAA).
* Output Current: Capable of delivering up to 900 mA in Buck mode and approximately 500 mA in Boost mode (at 3.3V out, 2.5V in), depending on the thermal environment.
* Efficiency: Achieves peak power conversion efficiency of up to 96%, significantly extending battery runtimes in portable devices.
* Switching Frequency: Operates at a fixed 2.4 MHz, allowing for the use of small passive components and simplifying EMI filtering.
* Quiescent Current: Features a low operating quiescent current of roughly 30 µA in power-save mode, minimizing standby drain.
* Physical Footprint: Designed with a compact PCB layout optimized for thermal dissipation and minimal EMI radiation.

***

### Key Engineering Features

#### Seamless Mode Transition

The defining characteristic of the TPS63030 is its ability to maintain tight voltage regulation while the input voltage crosses the output threshold. For example, as a Li-Ion battery discharges from 4.2V to 3.0V, the converter transparently shifts from Buck mode to Boost mode without output glitches or resets, a critical requirement for maintaining MCU stability during brownout conditions.

#### Dynamic Power Save Mode

To accommodate variable load profiles, the module features a Power Save Mode (PSM). At light loads, the converter automatically reduces its switching frequency to maintain high efficiency (Pulse Frequency Modulation). For noise-sensitive applications, this feature can be disabled via the PS/SYNC pin to force fixed-frequency PWM operation, reducing low-frequency ripple.

#### Robust System Protection

The board integrates comprehensive protection circuitry, including Over-Temperature Shutdown and Under-Voltage Lockout (UVLO). Unlike basic boosters, the synchronous design ensures true output disconnection during shutdown, preventing current leakage from input to output when the device is disabled.

***

### Board Pinout

<table><thead><tr><th width="162.1953125" align="center">( J1 ) Pin Number</th><th align="center">Pin Name</th><th>Description</th></tr></thead><tbody><tr><td align="center">1</td><td align="center">GND</td><td>Ground</td></tr><tr><td align="center">2</td><td align="center">VIN</td><td>Voltage Input Pin (1.8V ~ 5.5V)</td></tr></tbody></table>

<table><thead><tr><th width="161.76953125" align="center">( J2 ) Pin Number</th><th width="133.78125" align="center">Pin Name</th><th>Description</th></tr></thead><tbody><tr><td align="center">1</td><td align="center">GND</td><td>Ground</td></tr><tr><td align="center">2</td><td align="center">VIN SENSE</td><td>Can be used to measure the input voltage directly on the input capacitor.</td></tr></tbody></table>

<table><thead><tr><th width="171.0703125" align="center">( J3 ) Pin Number</th><th width="122.87109375" align="center">Pin Name</th><th>Description</th></tr></thead><tbody><tr><td align="center">1</td><td align="center">HIGH</td><td>Power Supply</td></tr><tr><td align="center">2</td><td align="center">EN</td><td>Shorting jumper between the center pin EN and HIGH turns on the unit. Shorting jumper between the center pin EN and LOW turns the unit off. (Default: Pulled up to VIN in circuit)</td></tr><tr><td align="center">3</td><td align="center">LOW</td><td>Ground</td></tr></tbody></table>

<table><thead><tr><th width="164.30078125" align="center">( J4 ) Pin Number</th><th width="143.4609375" align="center">Pin Name</th><th>Description</th></tr></thead><tbody><tr><td align="center">1</td><td align="center">GND</td><td>Ground</td></tr><tr><td align="center">2</td><td align="center">VOUT SENSE</td><td>Can be used to measure the output voltage directly on the output capacitor.</td></tr></tbody></table>

<table><thead><tr><th width="165.0703125" align="center">( J5 ) Pin Number</th><th width="125.8984375" align="center">Pin Name</th><th>Description</th></tr></thead><tbody><tr><td align="center">1</td><td align="center">HIGH</td><td>Power Supply</td></tr><tr><td align="center">2</td><td align="center">PS/SYNC</td><td>The center pin of this jumpers is connected to the SYNC pin of the TPS63030 and is used to synchronize the unit with an external clock.This jumper also enables/disables the power-saving mode at light loads. To enable power-save, PS/SYNC must shorting to LOW. (Default: Pulled up to VIN in circuit)</td></tr><tr><td align="center">3</td><td align="center">LOW</td><td>Ground</td></tr></tbody></table>

<table><thead><tr><th width="166.234375" align="center">( J6 ) Pin Number</th><th width="170.7734375" align="center">Pin Name</th><th>Description</th></tr></thead><tbody><tr><td align="center">1</td><td align="center">GND</td><td>Ground</td></tr><tr><td align="center">2</td><td align="center">VOUT</td><td>Buck-boost converter output (3.3V)</td></tr></tbody></table>

***

### Applications

* Wearable Electronics: Regulating 3.3V rails for Bluetooth/Wi-Fi SoCs from small Li-Po cells.
* Portable Instrumentation: Ensuring consistent sensor performance as battery voltage degrades.
* RF Transceivers: Providing low-noise power by forcing PWM mode during transmission bursts.
* Energy Harvesting: Efficiently regulating variable voltage from solar or thermal sources

***

### Board Dimensions:

![TPS63030 Dimension](https://github.com/Boardoza/Boardoza_TPS63030_Buck-Boost_Converter_Breakout_Board/raw/main/assets/TPS63030%20Dimension.png)

***

{% hint style="info" %}
Ready to integrate? You can purchase the **TPS63030 Buck-Boost Converter** directly from our [Online Store](https://www.robotshop.com/products/acrome-tps63030-single-inductor-buck-boost-converter?qd=2034270b758942787c5990ac20109d60). Worldwide shipping is available for engineering samples and production batches.
{% endhint %}


# SM351LT Magnetoresistive Sensor Breakout Board

### Overview

The Boardoza SM351LT is an ultra-sensitive, nanopower magnetic sensing solution designed to replace traditional reed switches and standard Hall-effect devices in battery-constrained applications. Built around the Honeywell SM351LT magnetoresistive (MR) sensor engine, this module offers omnipolar detection capabilities, allowing it to trigger in the presence of either a North or South magnetic pole with equal precision.

Unlike diverse Hall-effect sensors that require significant operating current, the SM351LT utilizes a state-of-the-art magnetoresistive bridge architecture. This enables it to achieve reliable switching at typical currents as low as 360 nA (nanoamperes), making it the gold standard for "install-and-forget" battery-operated systems like utility meters, medical infusion pumps, and wireless security contacts.

***

<div align="left"><figure><img src="/files/sJ0uK1wN0b2iBp697gY0" alt="" width="375"><figcaption></figcaption></figure></div>

***

### Core Technical Specifications

The module is defined by the following operational parameters:

* Sensing Technology: Omnipolar Magnetoresistive (MR) sensor, offering superior sensitivity compared to standard Hall devices.
* Operating Voltage: Extremely wide input range of 1.65V to 5.5V DC, accommodating direct connection to 1.8V logic, coin cells, or 5V buses.
* Supply Current: Ultra-low power consumption, typically averaging 360 nA at 2V, enabling multi-year battery life.
* Sensitivity: High-sensitivity switching point (typical operating point around 14 Gauss / 1.4 mT), allowing for the use of smaller, cheaper magnets or larger air gaps.
* Output Configuration: Push-Pull (CMOS) output stage. This eliminates the need for an external pull-up resistor, saving component count and board space.
* Operating Frequency: Capable of detecting magnetic field changes up to 1 kHz, suitable for low-speed counting applications.
* Thermal Endurance: Rated for industrial temperature ranges from -40°C to +85°C.
* Physical Dimensions: A compact 20 mm x 40 mm PCB footprint.

***

### Key Engineering Features

#### Omnipolar Detection Logic

The module is "pole independent," meaning it activates (switches output state) when the magnetic field magnitude exceeds the operating point, regardless of whether the field is North or South polarity. This drastically simplifies manufacturing assembly and installation, as magnet orientation does not need to be strictly controlled.

#### Nanopower Architecture

The defining feature of the SM351LT is its duty-cycled power management. The internal logic wakes up the sensing element for a brief interval to sample the magnetic field and then returns to a deep sleep state. This periodic sampling occurs fast enough to appear continuous for most human-interface and mechanical monitoring applications while maintaining sub-microampere average current.

#### Robust Solid-State Design

As a solid-state device, the Boardoza SM351LT suffers from none of the mechanical wear, contact bounce, or "sticking" issues associated with glass-encapsulated reed switches. It is immune to vibration and shock, providing high reliability in mobile or industrial environments.

***

### Hardware Interface and Signal Mapping

The module simplifies integration via a standard 3-pin interface:

Power and Signal

* VCC: Power Supply Input (1.65V - 5.5V).
* GND: Common System Ground.
* OUT: Digital Output Signal.
  * State Low (0V): Magnetic field detected (Field > Operating Point).
  * State High (VCC): No magnetic field detected (Field < Release Point).
  * *(Note: As a push-pull output, this pin drives the logic line actively high and low; do not use strong external pull-down resistors that might contend with the driver.)*

### Board Pinout

<table><thead><tr><th width="133.4296875" align="center">Pin Number</th><th width="197.88671875" align="center">Pin Name</th><th>Description</th></tr></thead><tbody><tr><td align="center">1</td><td align="center">VCC</td><td>Power Supply (3.3V - 5V)</td></tr><tr><td align="center">2</td><td align="center">OUT</td><td>Digital Output (Push-Pull)</td></tr><tr><td align="center">3</td><td align="center">GND</td><td>Ground</td></tr></tbody></table>

***

### Applications

* Utility Metering: Tamper detection in water, gas, and electric meters.
* Consumer Electronics: Lid closure detection (Open/Close) for laptops and TWS earbud cases.
* Medical Devices: Medication delivery tracking in battery-powered handhelds.
* Industrial Automation: Pneumatic cylinder position sensing and non-contact limit switches.

***

### Board Dimensions:

![Board Dimensions](https://github.com/Boardoza/Boardoza_SM351LT_Magnetoresistive_Sensor_Breakout_Board/raw/main/assets/SM351LT%20Dimension.png)

***

{% hint style="info" %}
Ready to integrate? You can purchase the **SM351LT Magnetoresistive Sensor** directly from our [Online Store](https://www.robotshop.com/products/acrome-sm351lt-hall-effect-sensor?qd=ea182830cbb3086e2c6d56f13063c9cf). Worldwide shipping is available for engineering samples and production batches.
{% endhint %}


# TH09C Temp Sensor Breakout Board

### Overview

The Boardoza TH09C is a precision temperature sensing module designed for applications demanding high accuracy and rapid thermal response. At its core lies a sensitive thermistor-based architecture, engineered to provide reliable temperature measurements across a broad environmental range.

Optimized for integration into embedded systems, this breakout board simplifies the analog interface by providing a standard 3-pin connection. It is suitable for both 3.3V and 5V logic environments, making it a versatile choice for HVAC monitoring, industrial process control, and consumer electronics thermal management.

***

<div align="left"><figure><img src="/files/XoG89FW9wfCENKeqBEIv" alt="" width="375"><figcaption></figcaption></figure></div>

***

### Core Technical Specifications

The module is defined by the following operational parameters:

* Sensing Element: High-precision NTC (Negative Temperature Coefficient) thermistor, typically 10kΩ at 25°C, where resistance decreases as temperature increases.
* Temperature Range: Capable of measuring temperatures from -40°C to +125°C, covering most industrial and consumer application requirements.
* Accuracy: Provides a measurement tolerance of ±1%, ensuring consistent data fidelity for critical thermal loops.
* B-Constant: Characterized by a Beta value (B25/50) of 3950K, defining the slope of the resistance-temperature curve for software linearization.
* Output Type: Analog voltage output proportional to the temperature, designed for direct connection to an MCU ADC pin.
* Operating Voltage: Supports a flexible supply input of 3.3V to 5V DC.
* Physical Dimensions: A compact 20 mm x 40 mm PCB footprint.

***

### Key Engineering Features

#### Linearized Analog Output

While raw thermistors exhibit a non-linear resistance response, this breakout board is typically configured as a voltage divider circuit. This setup produces an analog voltage output that can be easily mapped to temperature values using the Steinhart-Hart equation or simplified Beta parameter calculations in the host microcontroller firmware.

#### Wide Operational Envelope

The sensor's wide operating temperature range (-40°C to +125°C) allows it to be deployed in harsh environments, from freezing outdoor weather stations to the high-heat interiors of power supply enclosures. Its ±1% accuracy ensures that it meets the rigorous standards required for safety-critical thermal shutdowns.

#### Simplified Interface

The module is designed for "plug-and-measure" simplicity. By handling the mechanical mounting and electrical termination of the discrete thermistor component, it provides a robust, vibration-resistant platform that eliminates the need for point-to-point wiring or custom signal conditioning on the main PCB.

***

### Hardware Interface and Signal Mapping

The module interfaces via a standard 3-pin header, labeled for quick identification:

Power and Signal

* VCC (Signal Pin): This pin serves as the signal output. In a typical voltage divider configuration on the breakout, the output voltage at this pin varies with temperature. It is connected to the ADC input of the microcontroller.
* GND: Common system ground.
* (Third Pin): Depending on the specific voltage divider topology used on the board, the third pin (often labeled VCC or similar) provides the bias voltage (3.3V or 5V) to the thermistor circuit.

*(Note: Ensure to verify the specific pinout labels on the silk screen, as NTC breakout topologies can vary between VCC-Signal-GND)*.

### Board Pinout

<table><thead><tr><th width="153.6953125" align="center">(J1) Pin Number</th><th width="194.5234375" align="center">Pin Name</th><th>Description</th></tr></thead><tbody><tr><td align="center">1</td><td align="center">VCC</td><td>Power Supply</td></tr><tr><td align="center">2</td><td align="center">SCL</td><td>I<sup>2</sup>C Serial Clock Pin</td></tr><tr><td align="center">3</td><td align="center">SDA</td><td>I<sup>2</sup>C Serial Data Pin</td></tr><tr><td align="center">4</td><td align="center">GND</td><td>Ground</td></tr></tbody></table>

<br>

***

### Applications

* HVAC Systems: Air duct temperature monitoring for climate control feedback loops.
* 3D Printers: Heated bed and hot-end temperature regulation.
* Battery Management Systems (BMS): Thermal runaway detection for Li-Ion battery packs.
* PC Hardware: Case and CPU temperature monitoring for fan speed control.

***

### Board Dimensions:

![TH09C Dimension](https://github.com/Boardoza/Boardoza_TH09C_Temperature_Humidity_Sensor_Breakout_Board/raw/main/assets/TH09C%20Dimensions.png)

***

{% hint style="info" %}
Ready to integrate? You can purchase the **TH09C Temp Sensor** directly from our [Online Store](https://www.robotshop.com/products/acrome-temp-sensor-breakout-board?qd=8da01df86a103994656f728682846c03). Worldwide shipping is available for engineering samples and production batches.
{% endhint %}

{% embed url="<https://www.youtube.com/watch?v=jYhk3OW2h8A>" %}


# TPS630702RNMT Breakout Board

### Overview

The Boardoza TPS630702RNMT is a high-efficiency, wide-input range Buck-Boost converter module designed to provide a regulated output voltage from power sources that can be either higher or lower than the target output. Built around the Texas Instruments TPS630702 regulator engine, this board utilizes a fixed-frequency PWM controller with synchronous rectification to achieve efficiencies up to 95%.

This module is specifically engineered for dynamic power environments, such as battery-operated systems where the voltage degrades over time (e.g., a single Li-Ion cell discharging from 4.2V to 2.8V). Its seamless automatic transition between Buck (step-down) and Boost (step-up) modes ensures a stable power rail without the drop-outs associated with standard LDOs or single-topology switchers.

***

<div align="left"><figure><img src="/files/ZIWoA13x9p7qlYLilbFL" alt="" width="375"><figcaption></figcaption></figure></div>

***

### Core Technical Specifications

The module is defined by the following operational parameters:

* Topology: Synchronous Buck-Boost Converter with automatic mode transition.
* Input Voltage Range: Extremely wide input support from 2.0V to 16V, accommodating diverse sources from dual alkaline cells to 12V automotive rails.
* Output Voltage: User-selectable presets via onboard jumpers. Default is 3.3V, with hardware configurability for 5V, 7.5V, and 9V.
* Current Capacity: Capable of delivering up to 2A continuous output current in both Buck and Boost modes (depending on Vin/Vout ratio).
* Efficiency: Peak efficiency rating of 95%, minimizing thermal waste in compact enclosures.
* Quiescent Current: Ultra-low standby current consumption (typically 50 µA), critical for extending battery shelf life.
* Physical Dimensions: A standardized 40 mm x 60 mm PCB footprint.

***

### Key Engineering Features

#### Seamless Buck-Boost Transition

The core advantage of this module is its ability to maintain a fixed output voltage while the input voltage crosses the regulation threshold. For example, when powering a 3.3V system from a Li-Po battery (4.2V to 3.0V), the module starts in Buck mode and automatically switches to Boost mode as the battery drains, extracting the maximum possible energy from the cell.

#### Configurable Power Modes

To optimize performance for specific loads, the board includes a PS/SYNC jumper.

* Power Save Mode (PSM): Improves efficiency at light loads by reducing switching frequency (PFM), ideal for idle microcontrollers.
* Forced PWM Mode: Maintains a fixed switching frequency for low output ripple and low noise, which is preferable for sensitive analog or audio circuits.

#### Integrated System Protection

The module features a robust safety architecture including Output Overvoltage Protection, Overtemperature Shutdown, and Undervoltage Lockout (UVLO). Notably, it includes a "Load Disconnect" feature during shutdown, which physically isolates the output from the input to prevent battery leakage currents.

***

### **Board Pinout**

#### **J1 - Power Input Connector**

<table><thead><tr><th width="150.0859375" align="center">Pin Number</th><th width="200.12109375" align="center">Pin Name</th><th>Description</th></tr></thead><tbody><tr><td align="center">1</td><td align="center">VIN</td><td>Voltage Input Pin (2V - 16V)</td></tr><tr><td align="center">2</td><td align="center">GND</td><td>Ground</td></tr></tbody></table>

#### **J2 - Power Good (PG) Indicator**

<table><thead><tr><th width="150.69921875" align="center">Pin Number</th><th width="199.75390625" align="center">Pin Name</th><th>Description</th></tr></thead><tbody><tr><td align="center">1</td><td align="center">PG</td><td>Power Good signal, indicating output voltage status.</td></tr><tr><td align="center">2</td><td align="center">GND</td><td>Ground</td></tr></tbody></table>

#### **J3 - Output Connector**

<table><thead><tr><th width="150.13671875" align="center">Pin Number</th><th width="199.68359375" align="center">Pin Name</th><th>Description</th></tr></thead><tbody><tr><td align="center">1</td><td align="center">VOUT</td><td>Adjustable Buck-Boost output (3.3V - 5V - 7.5V - 9V)</td></tr><tr><td align="center">2</td><td align="center">GND</td><td>Ground</td></tr></tbody></table>

#### **JP1 - Enable Control**

<table><thead><tr><th width="149.73046875" align="center">Pin Number</th><th width="200.48046875" align="center">Pin Name</th><th>Description</th></tr></thead><tbody><tr><td align="center">1</td><td align="center">LOW</td><td>Connect to GND</td></tr><tr><td align="center">2</td><td align="center">EN</td><td>Regulator Enable Pin (Default: HIGH). Set LOW to disable the regulator.</td></tr><tr><td align="center">3</td><td align="center">HIGH</td><td>Connect to VIN</td></tr></tbody></table>

#### **JP2 - Power Save / Synchronization Mode**

<table><thead><tr><th width="150.140625" align="center">Pin Number</th><th width="199.921875" align="center">Pin Name</th><th>Description</th></tr></thead><tbody><tr><td align="center">1</td><td align="center">LOW</td><td>Open drain power good output</td></tr><tr><td align="center">2</td><td align="center">PS/SYNC</td><td>Selects between forced PWM and power-save mode. Default: LOW (PWM Mode).</td></tr><tr><td align="center">3</td><td align="center">HIGH</td><td>Connect to VIN</td></tr></tbody></table>

#### **JP3 - Voltage Selection**

<table><thead><tr><th width="149.91796875" align="center">Pin Number</th><th width="200.34765625" align="center">Pin Name</th><th>Description</th></tr></thead><tbody><tr><td align="center">1</td><td align="center">LOW</td><td>Open drain power good output</td></tr><tr><td align="center">2</td><td align="center">V_SEL</td><td>Voltage selection input (Default: LOW for 3.3V). Set HIGH to select another voltage.</td></tr><tr><td align="center">3</td><td align="center">HIGH</td><td>Connect to VIN</td></tr></tbody></table>

#### **Voltage Selection Pads**

<table><thead><tr><th width="200.359375" align="center">Pad</th><th>Description</th></tr></thead><tbody><tr><td align="center">9V</td><td>Select 9V output by jumping this pad</td></tr><tr><td align="center">7.5V</td><td>Select 7.5V output by jumping this pad</td></tr><tr><td align="center">5V</td><td>Select 5V output by jumping this pad</td></tr></tbody></table>

***

### Applications

* Battery-Powered IoT: Stabilizing 3.3V rails from single-cell Li-Ion or 2xAA batteries.
* Industrial Sensors: Providing clean 5V or 9V from fluctuating 12V or 24V industrial buses.
* USB Power Delivery: Boosting 3.7V battery voltage to stable 5V for USB OTG applications.
* Portable Instrumentation: Ensuring constant performance as battery voltage declines over the discharge curve.

***

### Board Dimensions

![Dimension](https://github.com/Boardoza/Boardoza_TPS630702_Buck-Boost_Converter_Breakout_Board/raw/main/assets/TPS630702%20Dimension.png)

***

{% hint style="info" %}
Ready to integrate? You can purchase the **TPS630702RNMT Breakout Board** directly from our [Online Store ](https://www.robotshop.com/products/acrome-tps630702-adjustable-buck-boost-converter-module?qd=e280e4816aa6ddbe7b0b678782fa14fc) . Worldwide shipping is available for engineering samples and production batches.
{% endhint %}


# GP-02 GPS Breakout Board

### Overview

The Boardoza GP-02 is a sophisticated multi-constellation GNSS (Global Navigation Satellite System) receiver module designed for high-precision positioning in embedded applications. At its core, it features a highly integrated System-on-Chip (SoC) architecture that combines a high-sensitivity RF front-end, a digital baseband processor, and a power-efficient 32-bit RISC CPU.

Engineered for global interoperability, the module supports concurrent reception of multiple satellite systems, including GPS (USA), BDS (BeiDou - China), and GLONASS (Russia). This "multi-mode" capability significantly enhances time-to-first-fix (TTFF) and positioning accuracy, particularly in challenging environments like urban canyons where signal obstruction is common. Its robust power management and active antenna protection make it a reliable choice for automotive tracking, UAV navigation, and precision agriculture.

***

<div align="left"><figure><img src="/files/G9u806pGSDBx7OJ6ffVT" alt="" width="375"><figcaption></figcaption></figure></div>

***

### Core Technical Specifications

The module is defined by the following operational parameters:

* Sensing Architecture: Multi-mode GNSS SoC integrating RF, Baseband, and CPU on a single die.
* Constellation Support: Capable of joint positioning using GPS, BeiDou (BDS), and GLONASS constellations.
* Operating Voltage: Features a flexible input range of 3V to 5.5V DC, allowing direct operation from Li-Ion batteries or standard 5V rails.
* Communication Interfaces: Supports both UART (TTL) and I2C protocols for versatile host connectivity.
* Logic Levels: Critical control pins (PPS, RST, INT, SAFE) are designed to operate at 3.3V logic levels, requiring level shifting if used with 5V MCUs.
* Thermal Endurance: Extremely robust industrial operating range from -40°C to +125°C, suitable for automotive and aerospace grade applications.
* Physical Dimensions: A standardized 20 mm x 40 mm footprint for compact integration.

***

### Key Engineering Features

#### Multi-System Joint Positioning

Unlike legacy single-system receivers, the GP-02's ability to track GPS, GLONASS, and BeiDou simultaneously allows it to lock onto a higher number of satellites. This redundancy improves geometric dilution of precision (GDOP), resulting in more stable and accurate coordinate data even when parts of the sky are obstructed.

#### Configurable Constellation Modes

The module features hardware-selectable modes to optimize performance for specific regions. Through physical jumper configurations on the GPS-BDS and GLNSS-GPS pins, users can prioritize specific constellations (e.g., GPS+BeiDou or GPS+GLONASS) to match local satellite availability.

#### Active Antenna Management

The integrated RF front-end includes dedicated circuitry for active antenna detection and protection. This feature safeguards the module against antenna short-circuits and open-circuit conditions, ensuring system reliability in harsh field deployments where cabling might be compromised.

***

### Hardware Interface and Signal Mapping

The breakout board simplifies connectivity through two distinct header groups:

Primary Power and Communication (4-Pin Header)

* VCC: Power Supply Input (3V - 5.5V).
* RX: UART Receive Data pin (Input from MCU TX).
* TX: UART Transmit Data pin (Output to MCU RX).
* GND: Common System Ground.

System Control and Configuration (5-Pin Header)

* PPS: Pulse Per Second output. A precise timing signal synchronized to atomic satellite clocks, used for system synchronization.
* N/F: Shutdown control pin. Keeping this high maintains normal operation; pulling it low likely enters a low-power state.
* RST: External Reset input. An active-low pin with an internal pull-up used to reboot the module.
* GPS-BDS: Configuration pin. Pulling High (or leaving floating) selects BDS + GPS mode.
* GLNSS-GPS: Configuration pin. Pulling Low selects GPS + GLONASS mode.

***

### Applications

* Automotive Navigation: In-dash navigation systems requiring high thermal stability.
* Asset Tracking: Logistics monitors for shipping containers crossing multiple GNSS regions.
* UAV/Drones: Flight controllers needing redundant satellite locks for stable hovering.
* Precision Timing: Network time servers utilizing the PPS signal for synchronization.

***

### Board Dimensions:

![GP-02 Dimension](https://github.com/Boardoza/Boardoza_GP-02_GNSS_Satellite_Navigation_Breakout_Board/raw/main/assets/GP-02%20Dimension.png)

***

{% hint style="info" %}
Ready to integrate? You can purchase the **GP-02 GPS** directly from our [Online Store](https://www.robotshop.com/products/acrome-boardoza-gp-02-bds-gnss-multi-mode-navigation-receiver-module?qd=f8123b57efee8eb1e5b33e08e32f868e) . Worldwide shipping is available for engineering samples and production batches.
{% endhint %}


# W25Q40CLSNIG SPI Flash

### Overview

The Boardoza W25Q40CLSNIG is a high-performance non-volatile memory expansion module designed to provide reliable code and data storage for embedded systems. At its core lies the Winbond W25Q40CL Serial Flash memory engine, a 4-Megabit (512 Kilobyte) device engineered for space-constrained applications requiring fast random access and low power consumption.

This breakout board serves as a robust "digital locker" for microcontrollers, enabling them to store firmware images (for Over-The-Air updates), configuration parameters, or high-speed sensor logs. By utilizing the standardized SPI (Serial Peripheral Interface) bus, it offers a seamless storage upgrade for platforms lacking sufficient internal flash, such as legacy 8-bit MCUs or modern IoT nodes.

***

<div align="left"><figure><img src="/files/aGnrd50rGHQwmI3hgJgJ" alt="" width="375"><figcaption></figcaption></figure></div>

***

### Core Technical Specifications

The module is defined by the following operational parameters:

* Memory Density: Provides 4 Megabits (512 KB) of storage organized into uniform 4KB erasable sectors and larger 32KB/64KB blocks.
* Data Throughput: Supports high-speed SPI clock frequencies up to 104 MHz, enabling rapid data retrieval for execution-in-place (XIP) architectures.
* Operating Voltage: Features a flexible input range of 3.3V to 5V DC, facilitating direct integration with both low-voltage logic and standard 5V legacy systems.
* Durability and Retention: Rated for over 100,000 program/erase cycles with data retention exceeding 20 years, ensuring long-term reliability in industrial deployments.
* Power Efficiency: Optimized for battery-operated devices, with active current consumption as low as 1 mA and deep power-down currents in the micro-ampere range.
* Physical Dimensions: A compact 20 mm x 20 mm square footprint designed for tight enclosure integration.

***

### Key Engineering Features

#### Enhanced SPI Modes (Dual/Quad I/O)

While the module defaults to standard SPI (Clock, Chip Select, Data In, Data Out), the W25Q40CL engine supports Dual and Quad SPI modes. By utilizing the Write Protect (/WP) and Hold (/HOLD) pins as additional bidirectional data lines (IO2 and IO3), the effective data transfer rate can be quadrupled, significantly reducing boot times for complex firmware.

#### Flexible Sector Architecture

The memory array is divided into 4KB uniform sectors, which allows for granular data management. This architecture is particularly beneficial for applications requiring frequent updates to small data packets—such as storing user settings or calibration constants—without needing to erase large blocks of memory, thereby extending the overall lifespan of the chip.

#### Integrated Visual Diagnostics

Unlike bare chips, this breakout board includes an onboard Power LED (D1). This provides immediate visual confirmation of power rail integrity during prototyping and field diagnostics, eliminating guesswork during initial system bring-up.

***

### Hardware Interface and Signal Mapping

The module interfaces via two distinct headers (J1 and J2) to separate basic communication from advanced control features:

Primary Interface (J1)

* 5V: Positive power supply input. The board regulates this for the internal memory logic.
* CLK: Serial Clock Input. Driven by the host microcontroller to synchronize data transmission.
* DI: Data Input (MOSI). The line carrying data/commands from the host to the memory.
* GND: Common system ground.

Advanced Control (J2)

* CS: Chip Select (Active Low). Must be driven low to initiate any communication with the device.
* DO: Data Output (MISO). The line carrying data from the memory back to the host.
* WP: Write Protect. An active-low pin used to hardware-lock specific memory regions against accidental overwrites.
* HOLD: Hold Input. Allows the host to pause communication without deselecting the device, useful in multi-slave SPI bus topologies.

***

### Applications

* Firmware-Over-The-Air (FOTA): Staging area for downloading new system updates before flashing the main MCU.
* Data Logging: Non-volatile buffer for sensors recording environmental metrics like temperature or vibration.
* Asset Configuration: Storing lookup tables, bitmap graphics, or font libraries for display modules.
* FPGA Configuration: Storing the bitstream required to configure Field Programmable Gate Arrays at power-up.

***

### Board Dimensions:

![Board Dimensions](https://github.com/Boardoza/Boardoza_W25Q40CLSNIG_SPI_Flash_Memory_Breakout_Board/raw/main/assets/W25Q40CLSNIG%20Dimension.png)

***

{% hint style="info" %}
Ready to integrate? You can purchase the **W25Q40CLSNIG SPI Flash** directly from our[Online Store ](https://www.robotshop.com/products/acrome-boardoza-w25q40clsnig-serial-flash-memory-breakout-board?qd=96490168ba91ec08c9c1eeaa323cdea5). Worldwide shipping is available for engineering samples and production batches.
{% endhint %}


# BNO055 IMU Sensor Breakout Board

### Overview

The Boardoza BNO055 is a revolutionary "smart" 9-Axis Absolute Orientation Sensor, architected as a System-in-Package (SiP) specifically for autonomous systems, robotics, and wearable technology. Powered by the Bosch Sensortec BNO055 engine, this module integrates a triaxial 14-bit accelerometer, a precise 16-bit gyroscope, and a triaxial geomagnetic sensor into a single silicon die.

What distinguishes this board is its integrated 32-bit Cortex-M0 microcontroller running the embedded BSX3.0 FusionLib software. This architecture allows raw sensor data to be processed on-chip using complex sensor fusion algorithms (such as Quaternions and Euler angles), thereby offloading the computational burden from the host microcontroller and delivering drift-free orientation data directly.

***

<div align="left"><figure><img src="/files/GpfD9HOWwOzCywehL8VB" alt="" width="375"><figcaption></figcaption></figure></div>

***

### Core Technical Specifications

The module is defined by the following operational parameters:

* Sensor Architecture: Integrated SiP housing an Accelerometer, Gyroscope, and Magnetometer.
* Processing Power: On-board 32-bit MCU executing hardware-accelerated Sensor Fusion algorithms.
* Operating Voltage: Features a wide input range, operating reliably between 3.3V and 5.5V DC.
* Output Data Formats:
  * Absolute Orientation: Provides Euler Vectors (360° sphere) or Quaternion outputs at 100Hz.
  * Linear Acceleration: Acceleration data with the gravity vector removed.
  * Gravity Vector: Isolated gravitational acceleration component for tilt calculation.
* Communication Interface: Configured by default for I2C, but supports reconfiguration to UART via the PS0 and PS1 pins.
* Operating Temperature: Engineered for industrial environments ranging from -40°C to +85°C.
* Physical Dimensions: A compact 20 mm x 40 mm PCB footprint.

***

### Key Engineering Features

#### On-Chip Sensor Fusion

In traditional IMU systems, converting raw data into meaningful orientation requires the host processor to run intensive Kalman filters. The BNO055 handles this internally, providing calibrated, drift-free orientation data directly from its output pins. This frees up significant resources on the main system processor for other tasks.

#### Flexible Integration Interface

The board is designed with TTL-level I2C compatibility, allowing direct communication with both 3.3V and 5V microcontrollers (such as Arduino, ESP32, and STM32). Additionally, users can toggle the PS0 and PS1 pins to switch the module into HID-I2C or UART modes, adapting to various system architectures.

#### Advanced Interrupt Management

The integrated INT pin provides a hardware interrupt signal that can be programmed to trigger on specific motion events—such as any motion, no motion, or high-G impacts. This feature is critical for power-efficient designs, allowing the host MCU to sleep until an event occurs.

***

### Hardware Interface and Signal Mapping

The module exposes power and data lines via standard pin headers:

Power and I2C Communication (Main Header)

* VCC: Power supply input (3.3V - 5.5V).
* GND: Common system ground.
* SCL: I2C Serial Clock line for data synchronization.
* SDA: I2C Serial Data line for bidirectional communication.

System Control and Configuration

* ADR: I2C address selection pin, enabling multiple sensors on the same bus.
* INT: Interrupt output pin for hardware-based event signaling.
* PS0 & PS1: Protocol select pins. Toggling the logic levels (High/Low) of these pins determines the active communication protocol (I2C/UART).

***

### Applications

* Autonomous Robotics: Precision navigation and balance control for UAVs and ground rovers.
* Virtual Reality (VR/AR): Low-latency head tracking for headsets and controllers.
* Biomechanics: Rehabilitation tracking of human motion and posture.
* Marine Electronics: Heading and roll compensation for boat autopilot systems.

***

### **Board Dimensions:**

[![Board Dimensions](https://github.com/Boardoza/Boardoza_BNO055_Absolute_Orientation_Sensor_Breakout_Board/raw/main/assets/BNO055%20Dimension.png)](https://github.com/Boardoza/Boardoza_BNO055_Absolute_Orientation_Sensor_Breakout_Board/blob/main/assets/BNO055%20Dimension.png)

***

{% hint style="info" %}
Ready to integrate? You can purchase the **BNO055 IMU Sensor** directly from our [Online Store](https://www.robotshop.com/products/acrome-bno055-imu-sensor-breakout-board?qd=33fa30611e7d4b0be07f3740377151df). Worldwide shipping is available for engineering samples and production batches.
{% endhint %}

{% embed url="<https://www.youtube.com/watch?v=vGkrhWDNyPs>" %}


# MS5611 Barometric Pressure Sensor

### Overview

The Boardoza MS5611 Breakout Board is a high-precision altimetric sensing solution engineered for applications requiring exceptional vertical resolution and stability. At its core lies the TE Connectivity MS5611-01BA03 barometric pressure sensor, a specialized micro-electromechanical system (MEMS) that integrates a high-linearity pressure element with an ultra-low power 24-bit Delta-Sigma (ΔΣ) ADC.

optimized for variometer and altimeter designs, this module distinguishes itself with an altitude resolution of just 10 cm, allowing for the detection of minute elevation changes in UAV flight controllers, mobile instrumentation, and indoor navigation systems. The breakout architecture simplifies integration by incorporating necessary power regulation and logic level translation, ensuring seamless operation with both 3.3V and 5V microcontroller logic.

***

<div align="left"><figure><img src="/files/el5GCCjg9nSzqSFi9PtR" alt="" width="375"><figcaption></figcaption></figure></div>

***

### Core Technical Specifications

The module is defined by the following operational parameters:

* Sensing Architecture: High-linearity pressure die coupled with an internal factory-calibrated 24-bit ADC.
* Pressure Range: Delivers full accuracy within 450 to 1100 mbar, with an extended linear range of 10 to 1200 mbar.
* Altitude Resolution: Achieves a granular vertical resolution of 10 cm at sea level, critical for high-dynamic aerospace applications.
* Temperature Range: Operates reliably across an industrial temperature span of -40°C to +85°C, with an integrated sensor providing ±0.8°C accuracy.
* Supply Voltage: Features a wide input range of 3.3V to 5.5V DC, regulated onboard to the sensor's native operating voltage.
* Communication Protocols: Supports both I2C (default) and SPI serial interfaces, user-selectable via hardware pin configuration.
* Power Efficiency: Extremely low power consumption, drawing approximately 1.4 mA during active conversion and dropping to 0.15 µA in standby mode.
* Physical Dimensions: A compact 20 mm x 20 mm square footprint.

***

### Key Engineering Features

#### 24-Bit Precision and Factory Calibration

The MS5611 eliminates the need for external calibration by storing individual coefficients (PROM) on-chip during manufacture. The host microcontroller retrieves these coefficients to perform a first-order temperature compensation on the raw 24-bit pressure data, resulting in highly stable readings immune to thermal drift.

#### Flexible Communication Interface

To maximize system compatibility, the board supports two primary serial protocols. While it ships configured for I2C (using standard 2-wire SDA/SCL lines), it can be hard-switched to SPI mode by manipulating the Protocol Select (PS) pin. This flexibility allows engineers to optimize for bus speed (SPI) or pin count (I2C) depending on the system architecture.

#### Configurable Oversampling (OSR)

The module allows developers to trade off between conversion speed and power consumption by adjusting the Oversampling Ratio (OSR). Selectable ranges from 256 to 4096 samples enable the sensor to be tuned for ultra-fast response times (down to 0.5 ms) for variometers or maximum resolution for static weather monitoring.

***

### Hardware Interface and Signal Mapping

The module interfaces via a standard 7-pin header, providing access to power, data, and configuration lines:

Power and Ground

* VCC: Main power supply input (3.3V - 5.5V). The onboard LDO regulator ensures a stable voltage for the sensing element.
* GND: Common system ground.

Communication Bus

* SCL: Serial Clock line. Used for both I2C and SPI clock synchronization.
* SDA: Serial Data line. Functions as bidirectional data (SDA) in I2C mode or Master Out Slave In (MOSI) in SPI mode.
* SDO: Serial Data Output. Functions as the MISO line in SPI mode or allows for I2C address selection (LSB).
* CSB: Chip Select (Active Low). Enables the device in SPI mode or determines the I2C address when using the I2C protocol.
* PS: Protocol Select. Pulling this pin High (to VCC) selects I2C mode (default), while pulling it Low (to GND) enables SPI mode.

***

### Applications

* Aerospace Avionics: Variometers and flight control computers for gliders and UAVs.
* Mobile Altimetry: Precision altitude tracking for hiking GPS units and sports watches.
* Indoor Navigation: Floor-level detection for emergency response tracking inside buildings.
* Meteorology: High-resolution barometric pressure logging for weather stations.

***

### Board Dimensions:

![MS5611 Dimension](https://github.com/Boardoza/Boardoza_MS5611_Barometric_Pressure_Sensor_Breakout_Board/raw/main/assets/MS5611%20Dimension.png)

***

{% hint style="info" %}
Ready to integrate? You can purchase the **MS5611 Barometric Pressure Sensor** directly from our [Online Store](https://www.robotshop.com/products/acrome-barometric-pressure-sensor-breakout-board?qd=7b6cbde8918c0a154fb55a4b69b81514). Worldwide shipping is available for engineering samples and production batches.
{% endhint %}


# Quectel FC41D BT & WiFi Module

### Overview

The Boardoza FC41D is a robust, dual-mode wireless connectivity solution powered by the Quectel FC41D engine, a high-performance MCU-based module optimized for the IoT (Internet of Things) ecosystem. This breakout board seamlessly integrates Wi-Fi 4 (802.11 b/g/n) and Bluetooth 5.2 (Low Energy) capabilities into a single compact platform, enabling reliable, high-speed data transmission for industrial automation, smart home infrastructures, and remote sensing networks.

Designed for flexibility, the module features a powerful embedded processor running at 120 MHz, supported by 256 KB of RAM and up to 4 MB of Flash memory. Its "LCC" form factor architecture ensures high vibration resistance, while the breakout design provides easy access to critical interfaces via standard headers, making it an ideal choice for both rapid prototyping and scalable deployment.

***

|                                                                          Front Side                                                                          |                                                                          Back Side                                                                         |
| :----------------------------------------------------------------------------------------------------------------------------------------------------------: | :--------------------------------------------------------------------------------------------------------------------------------------------------------: |
| ![Quectel FC41D Front](https://github.com/Boardoza/Boardoza_Quectel_FC41D_Wi-Fi_And_Bluetooth_Module_Breakout_Board/raw/main/assets/Quectel_FC41D_Front.png) | ![Quectel FC41d Back](https://github.com/Boardoza/Boardoza_Quectel_FC41D_Wi-Fi_And_Bluetooth_Module_Breakout_Board/raw/main/assets/Quectel_FC41D_Back.png) |

<div align="left"><figure><img src="/files/5fYhfpmzyjU2xnxg5Nuq" alt="" width="375"><figcaption></figcaption></figure></div>

***

### Core Technical Specifications

The module is defined by the following operational parameters:

* Wireless Protocol: Supports IEEE 802.11 b/g/n (2.4 GHz) for Wi-Fi and Bluetooth 5.2 for robust local connectivity.
* Processor Architecture: High-efficiency MCU core clocked at 120 MHz, handling both the networking stack and user applications.
* Throughput: Capable of Wi-Fi physical layer rates up to 72.2 Mbps (1x1 SISO), ensuring sufficient bandwidth for video streaming or bulk telemetry.
* Memory Resources: Equipped with 256 KB of RAM and typically 2 MB or 4 MB of Flash, supporting complex firmware logic and secure Over-The-Air (OTA) updates.
* Input Voltage: Designed for broad compatibility with a 5V DC supply input, which is regulated onboard for the module's core logic.
* Operating Temperature: Engineered for harsh industrial environments, functioning reliably from -40°C to +85°C.
* Physical Dimensions: A standardized 40 mm x 40 mm footprint with mounting holes for secure chassis integration.

***

### Key Engineering Features

#### Integrated Network Security

The FC41D prioritizes data integrity with native support for advanced security standards, including WPA-PSK, WPA2-PSK, and WPA3-SAE. This ensures that critical IoT data streams remain protected against unauthorized access and replay attacks, a mandatory requirement for modern commercial deployments.

#### Versatile Interface Connectivity

To facilitate deep system integration, the board exposes a comprehensive set of peripheral interfaces. It supports UART (for AT commands and data), SPI, I2C, ADC, and PWM, allowing the module to directly control sensors, actuate motors, or interface with other local peripherals without needing a secondary microcontroller.

#### Power-Optimized Architecture

The module is designed for energy-sensitive applications. It features multiple low-power modes and a dedicated "keep-alive" mechanism, minimizing quiescent current consumption during idle periods while maintaining network association. This makes it highly suitable for battery-powered end-nodes and portable diagnostics equipment.

***

### Hardware Interface and Signal Mapping

The breakout board simplifies connectivity by breaking out the module's high-density pins into standard 2.54mm pitch headers, organized by function:

Communication Interfaces

* TX / RX: UART Transmit and Receive lines. These are the primary channels for sending AT commands and data payloads to the host MCU.
* SCL / SDA: I2C clock and data lines for interfacing with sensors or displays.
* CLK / MISO / MOSI / CS: Standard SPI bus pins for high-speed data transfer.

System Control and Power

* VIN: Positive power input (5V). This rail powers the onboard regulator.
* GND: Common system ground reference.
* RST: Hardware Reset pin. Pulling this line triggers a system reboot, useful for recovering from error states.
* WKP (Wakeup): A dedicated input pin used to wake the module from deep sleep modes based on external events.

***

### Applications

* Smart Home Automation: Wireless control of lighting, thermostats, and smart plugs via local Wi-Fi.
* Industrial Telemetry: Secure transmission of sensor data from factory floor machinery to cloud dashboards.
* Wearable Technology: Bridging Bluetooth health monitors to Wi-Fi networks for remote patient monitoring.
* Remote Asset Tracking: Location and status reporting for logistics containers using low-power beacons.

***

### Board Dimensions:

![Quectel FC41D Dimension](https://github.com/Boardoza/Boardoza_Quectel_FC41D_Wi-Fi_And_Bluetooth_Module_Breakout_Board/raw/main/assets/Quectel%20FC41D%20Dimension.png)

***

{% hint style="info" %}
Ready to integrate? You can purchase the **Quectel FC41D BT & WiFi Module** directly from our [Online Store](https://www.robotshop.com/products/acrome-wi-fi-bluetooth-module-breakout-board?qd=3a32007e18ad1a4e88f2ddd42b2c5d4a). Worldwide shipping is available for engineering samples and production batches.
{% endhint %}


# ADXL345 3-Axis Accelerometer Sensor

### Overview

The Boardoza ADXL345 Breakout Board is a precision MEMS (Micro-Electro-Mechanical Systems) sensing module designed to measure static gravity and dynamic acceleration forces across three orthogonal axes (X, Y, Z). Built around the industry-standard Analog Devices ADXL345 chipset, this module delivers high-resolution (13-bit) digital output, making it capable of detecting inclination changes of less than 1.0°.

Engineered for versatility in embedded systems, the board features an integrated voltage regulator and logic level shifting, allowing for seamless interfacing with both 3.3V and 5V microcontrollers. Its ultra-low power consumption and advanced motion-detection features make it an ideal solution for mobile instrumentation, gaming peripherals, and industrial vibration monitoring systems.

|                                                                  Front Side                                                                 |                                                                 Back Side                                                                 |
| :-----------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------: |
| ![ADXL345 Front](https://github.com/Boardoza/Boardoza_ADXL345_Triple_Axis_Accelerometer_Breakout_Board/raw/main/assets/ADXL345%20Front.png) | ![ADXL345 Back](https://github.com/Boardoza/Boardoza_ADXL345_Triple_Axis_Accelerometer_Breakout_Board/raw/main/assets/ADXL345%20Back.png) |

<div align="left"><figure><img src="/files/peRjj0D9AaGwZ0UnFhyp" alt="" width="375"><figcaption></figcaption></figure></div>

### Core Technical Specifications

The module is characterized by the following operational parameters:

* Sensing Architecture: 3-Axis MEMS accelerometer with user-selectable full-scale measurement ranges of ±2g, ±4g, ±8g, and ±16g.
* Resolution: Offers up to 13-bit resolution at ±16g (maintaining a 4 mg/LSB scale factor), enabling precise tilt calculations.
* Operating Voltage: Supports a wide input range of 3.3V to 6V DC thanks to the onboard low-dropout (LDO) regulator, while the core sensor operates internally at low voltage.
* Communication Interface: Flexible digital connectivity via SPI (3-wire or 4-wire) or I2C buses, selected via pin configuration.
* Power Consumption: Extremely efficient operation, drawing as little as 40 µA in measurement mode and 0.1 µA in standby mode.
* Data Rate: Configurable output data rates (ODR) ranging from 0.1 Hz to 3200 Hz, allowing optimization for low-power or high-frequency sampling.
* Physical Dimensions: A compact 20 mm x 20 mm PCB footprint designed for space-constrained integration.

### Key Engineering Features

#### Advanced Motion Detection Logic

Beyond raw acceleration data, the ADXL345 engine includes embedded logic for autonomous event detection:

* Tap/Double Tap: Detects single or double impulses on any axis, useful for gesture control interfaces.
* Activity/Inactivity: Monitors acceleration thresholds to determine if the device is in motion or stationary, enabling intelligent system sleep/wake cycles.
* Free-Fall Detection: Identifies rapid 0g conditions indicating a drop event, commonly used in hard drive protection mechanisms.

#### Integrated FIFO Buffer

To reduce the processing load on the host microcontroller, the module features a 32-level First-In-First-Out (FIFO) memory buffer. This allows the sensor to store data samples locally, permitting the host processor to sleep until a burst of data is ready for retrieval, thereby significantly lowering overall system power consumption.

#### Flexible Interface Compatibility

The breakout design simplifies integration by exposing the necessary pins for both SPI and I2C protocols. It includes standard 0.1" pitch headers, making it compatible with breadboards and standard prototyping cables. The default I2C address is typically 0x53, but can be modified via the SDO/ALT ADDR pin.

### Hardware Interface and Signal Mapping

The module provides a comprehensive 8-pin interface for power and data:

Power Terminals

* VCC (or +5V): Main power input (3.3V - 6V). The onboard regulator steps this down for the sensor.
* GND: Common system ground.

Digital Communication

* SDA: Serial Data line for I2C (or SDI/SDIO for SPI). Bidirectional data transfer pin.
* SCL: Serial Clock line. Provides the timing signal for I2C or SPI communication.
* SDO: Serial Data Output (SPI MISO) or Alternate Address Select (I2C). Grounding or pulling this pin high changes the I2C address (0x53 vs 0x1D).
* CS: Chip Select. Used to enable SPI mode (active low). For I2C operation, this is typically pulled high.

Interrupt Outputs

* INT1 & INT2: Programmable interrupt pins. These can be mapped to trigger on specific events like data-ready, free-fall, or tap detection, alerting the host MCU immediately.

### Applications

* Mobile Devices: Screen orientation (portrait/landscape) detection and user interface gestures.
* Industrial Monitoring: Vibration analysis for machinery health and predictive maintenance.
* Robotics: Balance stability control and impact detection for autonomous platforms.
* Medical Instrumentation: Activity monitoring in pedometers and wearable health trackers.

***

### Board Dimensions:

![ADXL345 Dimension](https://github.com/Boardoza/Boardoza_ADXL345_Triple_Axis_Accelerometer_Breakout_Board/raw/main/assets/ADXL345%20Dimension.png)

***

{% hint style="info" %}
Ready to integrate? You can purchase the **ADXL345 3-Axis Accelerometer** directly from our [Online Store](https://www.robotshop.com/products/acrome-adxl345-3-axis-accelerometer-sensor-breakout-board?qd=b36376b57490f7693e8eeea2e0deaea8). Worldwide shipping is available for engineering samples and production batches.
{% endhint %}


# LM75ADP Temperature Sensor

### Overview

The Boardoza LM75A is a precision temperature-to-digital converter module based on the highly integrated NXP LM75ADP architecture. It utilizes an on-chip bandgap temperature sensor paired with a Sigma-Delta analog-to-digital converter to deliver high-resolution thermal data.

Beyond simple measurement, the device functions as a sophisticated thermal watchdog. It includes an integrated over-temperature detection output (OS) that can operate independently as a standalone thermostat upon power-up, making it invaluable for system protection in industrial control units, power supplies, and personal computing hardware.

***

|                                                              Front Side                                                              |                                                              Back Side                                                             |
| :----------------------------------------------------------------------------------------------------------------------------------: | :--------------------------------------------------------------------------------------------------------------------------------: |
| ![LM75ADP Front](https://github.com/Boardoza/Boardoza_LM75ADP_Temperature_Sensor_Breakout_Board/raw/main/assets/LM75ADP%20Front.png) | ![LM75ADP Back](https://github.com/Boardoza/Boardoza_LM75ADP_Temperature_Sensor_Breakout_Board/raw/main/assets/LM75ADP%20Back.png) |

<div align="left"><figure><img src="/files/st0CEsXaxrv4ehVhFMcr" alt="" width="375"><figcaption></figcaption></figure></div>

***

### Core Technical Specifications

The module is defined by the following operational parameters:

* Sensing Architecture: On-chip bandgap sensor with an integrated 11-bit Sigma-Delta ADC.
* Resolution: Provides a fine temperature resolution of 0.125 °C, allowing for the detection of minute thermal gradients.
* Operating Voltage: Versatile supply range from 2.8 V to 5.5 V, ensuring compatibility with both low-voltage MCUs and standard 5V logic.
* Accuracy:
  * ±2 °C within the critical range of −25 °C to +100 °C.
  * ±3 °C across the extended range of −55 °C to +125 °C.
* Communication Interface: Industry-standard I2C-bus interface supporting up to 8 devices on a single bus via selectable addresses.
* Power Efficiency: Features a low-power shutdown mode consuming only 3.5 µA, ideal for battery-constrained IoT nodes.
* Robustness: ESD protection exceeding 2000 V (HBM) and latch-up immunity >100 mA, meeting strict JEDEC industrial standards.
* Physical Dimensions: Compact 20 mm x 20 mm square footprint.

***

### Key Engineering Features

#### Enhanced Resolution and Compatibility

Designed as a pin-for-pin replacement for the industry-standard LM75, the LM75A offers a significant upgrade in resolution (11-bit vs 9-bit) while maintaining full backward compatibility. This allows engineers to drop it into legacy designs to instantly improve thermal tracking precision without firmware overhaul.

#### Programmable Thermal Watchdog

The module features a dedicated Overtemp Shutdown (OS) pin with programmable hysteresis and threshold set points. This open-drain output can be configured to trigger an interrupt or directly drive a cooling fan when temperatures exceed safe limits, operating entirely in hardware without constant microcontroller polling.

#### Versatile I2C Addressing

To facilitate complex sensor networks, the board supports address selection. This feature enables the simultaneous operation of up to 8 distinct LM75A modules on the same 2-wire bus, simplifying multi-point thermal monitoring in large enclosures or battery packs.

***

### Hardware Interface and Signal Mapping

The module interfaces via a standard 5-pin header, supporting mixed-voltage environments:

Power and Ground

* VCC: Power supply input, accepting a wide range from 2.8V to 5.5V DC.
* GND: Common system ground.

Digital Interface

* SDA: I2C-bus bidirectional serial data line. This is an open-drain pin requiring a pull-up resistor (typically included on-board or required externally).
* SCL: I2C-bus serial clock input.
* OS (Overtemp Shutdown): Open-drain thermal alert output. Active when the measured temperature exceeds the programmed limit.

***

### Applications

* System Thermal Management: Critical component monitoring for servers, routers, and base stations.
* Environmental Control: Precision thermostats for HVAC systems and office automation.
* Industrial Process Control: Over-temperature protection for motor drivers and power inverters.
* Personal Electronics: Thermal throttling logic for laptops and gaming consoles.

***

### Board Dimensions:

![LM75 Temperature Sensor](https://github.com/Boardoza/Boardoza_LM75ADP_Temperature_Sensor_Breakout_Board/raw/main/assets/LM75ADP%20Dimension.png)

***

{% hint style="info" %}
Ready to integrate? You can purchase the **LM75ADP Temperature Sensor** directly from our [Online Store](https://www.robotshop.com/products/acrome-lm75adp-digital-temperature-sensor-breakout-board?qd=542f89e8f2d8a10080011cc6a0c6393b). Worldwide shipping is available for engineering samples and production batches.
{% endhint %}


# BA6208 Motor Driver Breakout Board

### Overview

The Boardoza BA6208 is a compact, reversible DC motor driver module designed to simplify the control of low-power brushed motors in embedded applications. Based on the robust BA6208 monolithic IC, this board integrates both the logic control interface and the power output stage into a single, cohesive unit.

Engineered primarily for precision electromechanical systems such as cassette mechanisms, robotic actuators, and variable-speed appliances, it enables seamless bidirectional control (Forward/Reverse) and braking via standard TTL-level logic signals. Its low standby current architecture makes it particularly suitable for battery-operated devices where quiescent power consumption is a critical design constraint.

***

|                                                                Front Side                                                               |                                                               Back Side                                                              |
| :-------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------: |
| ![Boardoza\_BA6208G\_Front](https://github.com/Boardoza/Boardoza_BA6208_Motor_Driver_Breakout_Board/raw/main/assets/BA6208%20Front.png) | ![Boardoza\_BA6208\_Back](https://github.com/Boardoza/Boardoza_BA6208_Motor_Driver_Breakout_Board/raw/main/assets/BA6208%20Back.png) |

<div align="left"><figure><img src="/files/Z1uqP8smAKTXSOoYl9Fi" alt="" width="375"><figcaption></figcaption></figure></div>

***

### Core Technical Specifications

The module is defined by the following operational parameters:

* Driver Architecture: Monolithic reversible motor driver with a built-in power output stage.
* Operating Voltage Range: Supports a wide supply voltage from 4.5V to 15.0V, accommodating various standard power rails (5V, 9V, 12V).
* Output Current Capacity: Delivers a typical continuous drive current of 100mA, with a peak capacity of 200mA.
* Logic Interface: Direct TTL-compatible inputs, allowing for easy interfacing with microcontrollers (Arduino, ESP32, STM32) without external level shifting.
* Standby Efficiency: Features an ultra-low standby current of approximately 0.4mA when the inputs are grounded (Ain=Low, Bin=Low).
* Thermal Tolerance: Rated for reliable operation in environments ranging from -20°C to +60°C.
* Mechanical Footprint: Compact 20 mm x 40 mm PCB dimensions.

***

### Key Engineering Features

#### Integrated Protection and Braking

The BA6208 incorporates internal surge absorption diodes to clamp inductive kickback spikes generated by the motor windings, protecting the driver transistors from breakdown. Additionally, the driver features a hard-braking mode; when both logic inputs are pulled HIGH, the output terminals are shorted to the ground rail (Low/Low), effectively stalling the motor using back-EMF damping.

#### Simplified Logic Control

The driver uses a dual-input logic scheme (Ain, Bin) to determine the motor state, eliminating the need for complex H-bridge driver code.

* Forward Drive: Ain=High, Bin=Low drives current from A-Out to B-Out.
* Reverse Drive: Ain=Low, Bin=High reverses the polarity.
* Forced Stop (Brake): Ain=High, Bin=High rapidly halts rotation.
* Standby/Coast: Ain=Low, Bin=Low puts the outputs in a high-impedance (OPEN) state, allowing the motor to spin down freely.

***

### Hardware Interface and Signal Mapping

The module provides separate headers for logic control and power output to ensure signal integrity:

Logic and Power Input

* +5V: Logic supply voltage input.
* A IN: Logic input A (Controls Output A state).
* B IN: Logic input B (Controls Output B state).
* GND: Common system ground.

Motor Output

* A OUT: Motor Terminal A connection.
* B OUT: Motor Terminal B connection.

***

### Applications

* Consumer Electronics: Drive mechanisms for cassette decks, CD players, and VCR loading trays.
* Robotics: Control of small DC gear motors for micro-robot locomotion or gripper actuation.
* Automotive Accessories: Actuators for mirror adjustments or door lock solenoids.
* Prototyping: Rapid testing of motor control algorithms using standard 5V logic.

***

### Board Dimensions:

![BA6208 Dimension](https://github.com/Boardoza/Boardoza_BA6208_Motor_Driver_Breakout_Board/raw/main/assets/BA6208%20Dimension.png)

***

{% hint style="info" %}
Ready to integrate? You can purchase the **BA6208 Motor Driver** directly from our [Online Store](https://www.robotshop.com/products/acrome-mq4-methane-gas-sensor-breakout-board?qd=2fbb3af2cc1b35765a78c5669574db21). Worldwide shipping is available for engineering samples and production batches.
{% endhint %}


# MQ-4 Methane Gas Sensor

### Overview

The Boardoza MQ-4 is a specialized electrochemical sensing module engineered for the reliable detection of Methane (CH₄) and Compressed Natural Gas (CNG) in ambient environments. Built around a robust metal-oxide semiconductor (MOS) chemiresistor, this sensor exhibits high sensitivity to methane concentrations ranging from 200 to 10000 ppm, making it a critical component for gas leak detection, industrial safety monitoring, and domestic air quality systems.

The module simplifies the integration of the raw MQ-4 sensor by providing onboard signal conditioning circuitry, offering both analog and digital output interfaces for seamless connectivity with modern microcontrollers.

***

|                                                                       Front Side                                                                       |                                                                       Back Side                                                                      |
| :----------------------------------------------------------------------------------------------------------------------------------------------------: | :--------------------------------------------------------------------------------------------------------------------------------------------------: |
| ![Boardoza\_MQ4\_GAS\_MKPV2\_Front\_View](https://github.com/Boardoza/Boardoza_MQ4_Methane_Gas_Sensor_Breakout_Board/raw/main/assets/MQ-4%20Front.png) | ![Boardoza\_MQ4\_GAS\_MKPV2\_Back\_View](https://github.com/Boardoza/Boardoza_MQ4_Methane_Gas_Sensor_Breakout_Board/raw/main/assets/MQ-4%20Back.png) |

<br>

<div align="left"><figure><img src="/files/a4w5ZBu3spZQCgmeQeVU" alt="" width="375"><figcaption></figcaption></figure></div>

***

### Core Technical Specifications

The module is defined by the following operational parameters:

* Target Gas: Optimized for Methane (CH₄) and Natural Gas (CNG) detection.
* Detection Range: Capable of sensing concentrations between 300 ppm and 10000 ppm.
* Sensing Architecture: Metal-Oxide Semiconductor (SnO₂) chemiresistor, where conductivity increases in the presence of target combustible gases.
* Operating Voltage: designed for standard 5V DC supply rails to power the internal heating element.
* Heater Consumption: approximately 150mA, required to maintain the sensing element at optimal catalytic temperature.
* Response Time: Fast response (< 10s) suitable for real-time safety alerts.
* Sensitivity Adjustment: Features an onboard precision potentiometer for calibrating the digital trigger threshold.

***

### Key Engineering Features

#### Dual-Signal Output Architecture

To maximize versatility, the breakout board provides two distinct output modes:

1. Analog Output (A0): Delivers a continuous voltage signal proportional to the gas concentration. This allows for precise ppm estimation when coupled with an MCU's Analog-to-Digital Converter (ADC).
2. Digital Output (D0): Provides a simple TTL logic signal (High/Low) based on a pre-set threshold. This is ideal for standalone alarm systems where a microcontroller might be overkill or for triggering interrupt-based safety shutdowns.

#### Integrated Comparator Circuitry

The digital output stage is driven by an onboard LM393 comparator. This integrated circuit compares the analog sensor voltage against a reference set by the onboard potentiometer, providing a clean, hysteresis-free digital signal for robust alarm triggering without software debouncing.

#### Industrial-Grade Stability

The MQ-4 sensor element is known for its long-term stability and resistance to alcohol and smoke interference, ensuring a low false-positive rate in specific methane detection applications compared to general-purpose combustible gas sensors.

***

### Hardware Interface and Signal Mapping

The module interfaces via a standard 4-pin header, clearly labeled for rapid prototyping:

Power Terminals

* VCC: Positive supply input. Must be connected to a stable 5V source to ensure consistent heater performance.
* GND: Common system ground.

Signal Outputs

* A0 (Analog Out): The primary measurement pin. Output voltage increases as gas concentration rises.
* D0 (Digital Out): The threshold trigger pin. Logic Low (0V) typically indicates gas presence exceeding the calibrated limit (adjustable via potentiometer).

***

### Applications

* Domestic Safety: Leak detectors for residential natural gas pipelines and stoves.
* Industrial Monitoring: Methane concentration logging in coal mines or waste management facilities.
* Portable Gas Analyzers: Handheld sniffers for locating pipe fractures.
* Smart HVAC: Ventilation control based on indoor air quality metrics.

***

### Board Dimensions:

![MQ4 Methane Gas Sensor](https://github.com/Boardoza/Boardoza_MQ4_Methane_Gas_Sensor_Breakout_Board/raw/main/assets/MQ-4%20Dimension.png)

***

{% hint style="info" %}
Ready to integrate? You can purchase the **MQ-4 Methane Gas Sensor** directly from our [Online Store](https://www.robotshop.com/products/acrome-mq4-methane-gas-sensor-breakout-board?qd=2fbb3af2cc1b35765a78c5669574db21). Worldwide shipping is available for engineering samples and production batches.
{% endhint %}

{% embed url="<https://www.youtube.com/watch?v=TtW3a_jSY8o>" %}


# Ublox SAM-M8Q GPS Board

### Overview

The Boardoza Ublox SAM-M8Q is a precision-engineered GNSS (Global Navigation Satellite System) solution designed around the industry-leading u-blox SAM-M8Q concurrent positioning engine. This module distinguishes itself with its embedded wide-band patch antenna, which utilizes a specialized "Smart Antenna" architecture to deliver omnidirectional reception and superior gain, even in RF-hostile environments.

Capable of acquiring signals from up to three satellite constellations simultaneously (GPS, GLONASS, and Galileo), the board offers exceptional positioning accuracy and reliability compared to single-constellation receivers. With its dual-interface design (UART and I2C) and wide input voltage compatibility, it serves as a versatile geospatial anchor for avionics, autonomous robotics, and precision asset tracking systems.

***

|                                                             Front Side                                                            |                                                            Back Side                                                            |
| :-------------------------------------------------------------------------------------------------------------------------------: | :-----------------------------------------------------------------------------------------------------------------------------: |
| ![Front](https://github.com/Boardoza/Boardoza_Ublox_Sam_M8Q_GNSS_Module_Breakout_Board/raw/main/assets/UBLOX_SAM_M8Q%20Front.png) | ![Back](https://github.com/Boardoza/Boardoza_Ublox_Sam_M8Q_GNSS_Module_Breakout_Board/raw/main/assets/UBLOX_SAM_M8Q%20Back.png) |

<div align="left"><figure><img src="/files/CTgyPrHnsbkQ6Oh2Sf5f" alt="" width="375"><figcaption></figcaption></figure></div>

***

### Core Technical Specifications

The module is defined by the following operational parameters:

* GNSS Engine: 72-channel u-blox M8 architecture supporting concurrent reception of GPS, GLONASS, and Galileo.
* Antenna Topology: Integrated wide-band patch antenna with an omnidirectional radiation pattern, eliminating the need for external RF circuitry.
* Update Rate: Supports up to 18 Hz in single-GNSS mode and 10 Hz when using concurrent GNSS, enabling high-dynamic tracking.
* Sensitivity: Achieves a tracking sensitivity of -165 dBm and a cold-start acquisition sensitivity of -146 dBm.
* Supply Voltage: engineered for flexibility with a simplified input range of 3.3V to 5.5V DC.
* Communication Interfaces: Features both UART (TTL) and I2C buses for broad microcontroller compatibility.
* Time Pulse Accuracy: Provides a highly precise PPS (Pulse Per Second) signal with ±30ns RMS accuracy for system time synchronization.
* Physical Dimensions: A standardized 40 mm x 40 mm footprint with mounting holes for secure chassis integration.

***

### Key Engineering Features

#### Concurrent Multi-GNSS Reception

Unlike legacy GPS-only modules, the SAM-M8Q leverages concurrent processing to track multiple constellations simultaneously. This "Multi-GNSS" capability significantly increases the number of visible satellites, improving position lock stability in "urban canyons" or obstructed horizons where a single constellation might fail.

#### RF Interference Mitigation

The module integrates a high-performance SAW (Surface Acoustic Wave) filter and a low-noise amplifier (LNA) directly in the RF front-end. This architecture provides exceptional immunity against jamming and RF noise from collocated peripherals like cellular modems or motor drivers, ensuring data integrity in complex electromechanical systems.

#### Embedded Smart Antenna

The onboard patch antenna is tuned for optimal performance independent of the ground plane size. This "design-in" readiness reduces the complexity of RF impedance matching during the integration phase, allowing engineers to treat the GPS subsystem as a "black box" component.

***

### Hardware Interface and Signal Mapping

The board provides access to power and data lines via standard 2.54mm pitch headers, organized into logical groups:

Communication Interfaces

* VCC: Main power supply input (3.3V - 5.5V).
* GND: Common system ground.
* TXD: UART Transmit line (Outputs NMEA stream to MCU).
* RXD: UART Receive line (Inputs configuration commands from MCU).
* SDA: I2C Serial Data line for bus-based communication.
* SCL: I2C Serial Clock line.

System Control Pins

* PPS: Pulse Per Second output. Delivers a high-precision logic pulse synchronized to atomic GPS time, essential for data logging timestamps.
* RST: Active-low hardware reset pin. Used to externally reboot the GNSS engine.
* INT: External Interrupt input. Can be used to wake the module from power-save modes or for time-aiding injection.
* SAFE: Reserved pin for SAFEBOOT\_N functionality, used during firmware updates or recovery procedures.

***

### Applications

* Unmanned Aerial Vehicles (UAVs): Provides stable positioning and "Return-to-Home" coordinates for drones.
* Precision Agriculture: Enables geofenced autonomous steering for robotic farming equipment.
* Fleet Telematics: Tracks vehicle location, speed, and heading for logistics management.
* High-Altitude Ballooning: capable of operating at high altitudes (up to 50,000m depending on flight mode configuration).

***

### Board Dimensions:

![Dimension](https://github.com/Boardoza/Boardoza_Ublox_Sam_M8Q_GNSS_Module_Breakout_Board/raw/main/assets/UBLOX_SAM_M8Q%20Dimension.png)

***

{% hint style="info" %}
Ready to integrate? You can purchase the **Ublox SAM-M8Q GPS Board** directly from our [Online Store](https://www.robotshop.com/products/acrome-ublox-sam-m8q-gps-breakout-board?qd=4dc3ec081aa1beb58bb46b427d70b5ce). Worldwide shipping is available for engineering samples and production batches.
{% endhint %}

{% embed url="<https://www.youtube.com/watch?v=-4UZI1GHHt8>" %}


# ESP01M Wi-Fi Module

### Overview

The Boardoza ESP01M is a highly integrated, compact Wi-Fi SoC (System on Chip) solution driven by the high-performance ESP8266 core architecture. Engineered for robust IoT (Internet of Things) deployments, this module incorporates a full TCP/IP protocol stack and a high-efficiency 2.4 GHz transceiver, enabling seamless network bridging for embedded microcontrollers.

Designed with an ultra-small 18mm x 18mm footprint, the ESP01M minimizes PCB real estate requirements while offering flexible "Station" and "SoftAP" modes. It serves as a critical communication node for smart home automation, industrial telemetry, and low-power sensor networks.

<div align="left"><figure><img src="/files/xAbpuseKGP4ZH1abcGiI" alt="" width="375"><figcaption></figcaption></figure></div>

### Core Technical Specifications

The module is characterized by the following operational parameters:

* Core Architecture: Built upon the Tensilica L106 32-bit RISC processor, optimized for ultra-low power consumption and high-speed data processing.
* Operating Voltage: Supports a wide input range of 3.3V to 5V DC, facilitating direct integration with diverse logic levels.
* Wireless Standard: Compliant with IEEE 802.11 b/g/n protocols, operating strictly in the 2.4 GHz frequency band.
* Data Throughput: Capable of achieving physical layer (PHY) rates up to 72.2 Mbps in 802.11n mode.
* Communication Interface: primarily utilizes a high-speed UART (Universal Asynchronous Receiver-Transmitter) bus with a default baud rate of 74880 bps for boot logs and command interfacing.
* Thermal Endurance: Engineered to withstand harsh industrial environments ranging from -40°C to +85°C.
* Physical Dimensions: A compact square form factor measuring 20 mm x 20 mm.

### Key Engineering Features

#### Advanced Networking Modes

The ESP01M supports a versatile range of network topologies:

1. Station Mode (STA): Allows the module to connect to an existing Wi-Fi router as a client.
2. SoftAP Mode: Enables the module to act as a wireless access point for other devices.
3. Promiscuous Mode: Facilitates low-level packet sniffing for network analysis and security applications.
4. Virtual Wi-Fi Interfaces: Supports up to two simultaneous virtual Wi-Fi interfaces for complex routing scenarios.

#### Robust UART Integration

The module is designed as a serial-to-Wi-Fi bridge. By utilizing standard TX/RX lines, it allows any microcontroller with a UART port to offload the heavy lifting of TCP/IP processing, significantly reducing the computational load on the host MCU.

### Hardware Interface and Signal Mapping

The Boardoza ESP01M exposes a simplified 6-pin header interface designed for rapid prototyping and reliable connectivity:

Power Terminals

* 5V Pin: The positive power supply input, accepting a regulated voltage between 3.3V and 5V.
* GND Pin: The common ground reference for both power and logic signals.

Communication Bus

* TX Pin: UART Transmit line. Used to send data from the ESP01M to the host controller.
* RX Pin: UART Receive line. Used to receive commands and data from the host controller.

Control Logic

* RST Pin: External hardware reset input. Driving this pin low triggers a hard reset of the SoC.
* IO0 (GPIO0): A multi-functional pin used for boot mode selection. Pulling this pin LOW during power-up places the module into UART Download Mode (Flash Mode) for firmware updates.

### Mechanical Specifications

The module features a square 20 mm x 20 mm PCB outline. Mounting is typically achieved via standard 2.54mm pitch headers, making it compatible with breadboards and industry-standard sockets.

{% hint style="info" %}
Ready to integrate? You can purchase the **ESP01M Wi-Fi Module** directly from our [Online Store](https://www.robotshop.com/products/acrome-boardoza-esp-01m-wi-fi-module?qd=b2e8b31d6e5d83b6965b2c55bbf4b7e0). Worldwide shipping is available for engineering samples and production batches.
{% endhint %}

***


# MCP73831 Charge Management Controller

### Overview

The Boardoza MCP73831 is a fully integrated, linear charge management solution designed specifically for single-cell Lithium-Ion and Lithium-Polymer battery chemistries. Built around the industry-standard Microchip MCP73831 engine, this module employs a constant-current/constant-voltage (CC/CV) charging algorithm with integrated thermal regulation, ensuring safe and efficient energy replenishment.

Featuring a modern USB Type-C interface alongside redundant solder pads, it provides a versatile power entry point for portable embedded systems, wearable electronics, and battery-backed IoT nodes. Its compact form factor and low external component count make it an ideal drop-in solution for space-constrained designs.

***

|                                                              Front Side                                                             |                                                             Back Side                                                             |
| :---------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------: |
| ![Front](https://github.com/Boardoza/Boardoza_MCP73831_Lithium_Battery_Charger_Breakout_Board/raw/main/assets/MCP73831%20Front.png) | ![Back](https://github.com/Boardoza/Boardoza_MCP73831_Lithium_Battery_Charger_Breakout_Board/raw/main/assets/MCP73831%20Back.png) |

<div align="left"><figure><img src="/files/mQMWFrrM56DsW82eSDc4" alt="" width="375"><figcaption></figcaption></figure></div>

***

### Core Technical Specifications

The module is characterized by the following operational parameters:

* Charging Topology: Linear regulation utilizing a CC/CV algorithm for safe and complete battery termination.
* Input Voltage Range: Compliant with standard USB bus voltages, operating reliably between 3.75V and 6V DC.
* Battery Compatibility: Specifically calibrated for single-cell Li-Ion or Li-Po cells with a standard 4.2V charge termination voltage.
* Charge Current: Configured by default for 500 mA throughput, with adjustability possible via the onboard R3 programming resistor.
* Thermal Endurance: Rated for industrial operating temperatures ranging from -40°C to +85°C.

***

### Key Engineering Features

#### Precision Linear Architecture

The module employs a high-accuracy linear control loop to regulate voltage within strict tolerances (typically ±0.75%). Unlike switching regulators, this linear topology generates negligible electromagnetic interference (EMI), making it the preferred choice for powering noise-sensitive RF communication modules and precision audio circuits.

#### Dual-Input Power Interface

To maximize integration flexibility, the board offers two distinct power entry methods:

1. USB Type-C Receptacle: Facilitates immediate plug-and-play charging from standard USB PD sources and wall adapters.
2. Solderable Power Pads: Allows for permanent, vibration-resistant hardwiring into custom chassis or power distribution buses.

#### Integrated Thermal Regulation

Safety is paramount in lithium battery management. The onboard controller features continuous thermal feedback. If the die temperature approaches its thermal limit due to high power dissipation, the charge current is automatically throttled back. This "thermal foldback" mechanism ensures the longevity of the silicon without suspending the charging cycle, eliminating the need for external heat sinks.

***

### Hardware Interface and Connectivity

The module simplifies battery integration through a clearly defined physical interface:

Power Input The primary power input is handled via the onboard USB Type-C connector, accepting standard 5V USB bus power.

Battery Output Terminals Direct battery connection is achieved through high-current solder pads located at the board edge:

* Positive Terminal (+): Connects to the Battery Anode (VBAT). This path delivers the regulated charge current to the cell.
* Negative Terminal (–): Connects to the Battery Cathode (GND). This serves as the common return path for the system.

***

### Mechanical Specifications

The device is housed in an ultra-compact footprint measuring 20 mm x 40 mm, designed to fit within the tight spatial constraints of modern enclosure designs.

***

### **Board Dimensions:**

![MCP73831 Battery Charger Dimensions](https://github.com/Boardoza/Boardoza_MCP73831_Lithium_Battery_Charger_Breakout_Board/raw/main/assets/MCP73831%20Dimension.png)

***

{% hint style="info" %}
Ready to integrate? You can purchase the **MCP73831 Charge Management Controller** directly from our [Online Store](https://www.robotshop.com/products/acrome-mcp73831t-battery-charger-module?qd=cf94d747f48f3a40db2da5b1c86a94a3) . Worldwide shipping is available for engineering samples and production batches.
{% endhint %}


# MDBT50Q BLE Module

### Overview

The Boardoza MDBT50Q is an industrial-grade, high-performance Bluetooth Low Energy (BLE) SoC module powered by the Nordic Semiconductor engine. Supporting the Bluetooth 5.2 standard, this module is engineered for applications requiring extended wireless range, high throughput, and ultra-low power consumption.

With its integrated 32-bit architecture and advanced power management features, the MDBT50Q serves as a robust wireless communication bridge for battery-operated IoT devices, industrial automation interfaces, and smart sensor networks.

***

|                                                   Front Side                                                   |                                                   Back Side                                                  |
| :------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------: |
| ![Front](https://github.com/Boardoza/Boardoza_MDBT50Q_Bluetooth5.2_Module/raw/main/assets/MDBT50Q%20Front.png) | ![Back](https://github.com/Boardoza/Boardoza_MDBT50Q_Bluetooth5.2_Module/raw/main/assets/MDBT50Q%20Back.png) |

<div align="left"><figure><img src="/files/NsArHz0yuGNcaD20AlvX" alt="" width="375"><figcaption></figcaption></figure></div>

***

### Core Technical Specifications

* Wireless Protocol: Bluetooth 5.2 (Low Energy).
* Operating Voltage: Versatile supply range from 3.3V to 5V DC.
* Host Interface: Standard UART with Hardware Flow Control (CTS/RTS).
* Memory Resources: Large-scale 512 KB RAM for complex application logic.
* Thermal Tolerance: Extended industrial range from -40°C to +105°C.
* Analog Capability: Integrated 10-bit resolution ADC with a 200ms refresh cycle.
* Physical Footprint: 40 mm x 40 mm compact PCB design.

***

### Key Engineering Features

#### Advanced BLE 5.2 Ecosystem

The MDBT50Q leverages the Bluetooth 5.2 stack to provide long-range communication and high-speed data transfer rates. The module is optimized for high interference immunity, ensuring stable links in RF-dense environments such as smart factories and medical facilities.

#### Intelligent Power Management

The module features sophisticated power-saving modes, including an active-high UART\_PD (Power Down) pin that allows developers to disable the UART hardware interface to minimize quiescent current during idle periods. Furthermore, the WAKEUP pin provides a deterministic exit strategy from deep-sleep states based on programmable system events.

#### Integrated ADC and System Reliability

Unlike standard BLE modules, the MDBT50Q integrates a continuously active 10-bit ADC, allowing for real-time analog sensing without additional MCU overhead. System integrity is further enhanced by an active-low hardware RESET pin and a dedicated FLASH DEFAULT trigger for secure system recovery and factory reset operations.

***

### Hardware Interface & Pinout

The module exposes two primary headers (J1 and J2) for power and signal interfacing.

#### J1: Primary Communication and Power

1. 5V: Positive Power Supply Input.
2. UART\_TX: Asynchronous Serial Data Transmitter.
3. UART\_RX: Asynchronous Serial Data Receiver.
4. UART\_CTS: Clear to Send flow control signal.
5. UART\_RTS: Request to Send flow control signal.
6. GND: Common System Ground.

#### J2: System Control and Analog Sensing

1. ADC: 10-bit Analog-to-Digital input, updated every 200ms.
2. UART\_PD: Active-high input with internal pull-high to disable hardware UART.
3. FLASH DEFAULT: Active-low system recovery trigger (0.48s ≦ logic low ≦ 1s).
4. RESET: Active-low hardware system reset.
5. WAKEUP: Selective output logic for deep-sleep wake-up actions.

***

### Applications

* Industrial IoT (IIoT): Long-range telemetry and wireless sensor data aggregation.
* Smart Energy: Remote monitoring of utility meters and power distribution nodes.
* Medical Devices: Secure, low-power data transmission for wearable health monitors.
* Asset Tracking: High-precision proximity sensing and beaconing in logistics.

***

### **Board Dimensions:**

![MDBT50Q Bluetooth Module Dimensions](https://github.com/Boardoza/Boardoza_MDBT50Q_Bluetooth5.2_Module/raw/main/assets/MDBT50Q%20Dimension.png)

***

{% hint style="info" %}
Ready to integrate? You can purchase the **MDBT50Q Bluetooth Module** directly from our [Online Store](https://www.robotshop.com/products/acrome-mdbt50q-bluetooth-module?qd=92cf1e3f4eace6512760b7dea49edd6e) . Worldwide shipping is available for engineering samples and production batches.
{% endhint %}


# MicroSD Breakout Board

### Overview

The Boardoza MicroSD Breakout Board is a high-performance, industrial-grade storage expansion module engineered for reliable non-volatile data management in embedded environments. Designed to provide a seamless bridge between microcontrollers and high-capacity flash media, this board simplifies the integration of external storage via the robust SPI (Serial Peripheral Interface) protocol.

Engineered for high data integrity and durability, it serves as the primary storage backbone for high-frequency data logging, local firmware repositories, and multimedia asset hosting in complex IoT ecosystems.

***

|                                                     Front Side                                                    |                                                    Back Side                                                    |
| :---------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------: |
| ![MicroSD Front](https://github.com/Boardoza/Boardoza_MicroSD_Breakout_Board/raw/main/assets/MicroSD%20Front.png) | ![MicroSD Back](https://github.com/Boardoza/Boardoza_MicroSD_Breakout_Board/raw/main/assets/MicroSD%20Back.png) |

<div align="left"><figure><img src="/files/ZWVzlLZ2phkaXvGs12yv" alt="" width="375"><figcaption></figcaption></figure></div>

***

### Core Technical Specifications

* Host Interface: Synchronous SPI (Serial Peripheral Interface).
* Media Support: MicroSD and MicroSDHC (High Capacity) cards.
* Operating Voltage: 3.3V DC (Nominal).
* File System Compatibility: Fully compatible with FAT16 and FAT32 architectures.
* Maximum Storage Capacity: Supports media up to 32 GB.
* Form Factor: Ultra-compact 20mm x 40mm PCB footprint.
* Physical Interconnect: Standard 2.54mm (0.1") pitch headers, breadboard-ready.

***

### Key Engineering Features

#### Enhanced Signal Integrity

The Boardoza MicroSD Breakout is designed with high-frequency signal propagation in mind. The PCB layout features optimized trace routing and onboard de-coupling capacitors to mitigate power-line noise and electromagnetic interference (EMI), ensuring stable communication even at high SPI clock speeds.

#### Seamless SPI Integration

The module simplifies the complex SD physical layer into a standard 6-pin SPI interface. This allows for rapid deployment across various architectures including ARM Cortex-M, AVR, ESP32, and RISC-V. By handling the mechanical and electrical interface of the microSD slot, it allows engineers to focus on high-level file system implementation.

#### Industrial Durability & Compactness

Constructed with a high-quality push-pull microSD socket, the board is built to withstand repeated insertion cycles. Its small form factor makes it ideal for space-constrained applications such as wearable diagnostics or compact industrial controllers where internal MCU flash is insufficient.

***

### Applications

* Black-Box Logging: High-resolution recording of flight data, vehicle telemetry, or industrial sensor arrays for post-mortem analysis.
* Firmware Staging (FOTA): Serving as a local buffer for Over-The-Air firmware updates before system flashing.
* Multimedia Repositories: Local storage for high-resolution GUI bitmaps, WAV audio files, or complex configuration scripts.
* Offline Data Collection: Long-term environmental monitoring in remote areas where cloud connectivity is intermittent.

Empower your embedded system with reliable, high-capacity storage using the Boardoza MicroSD Breakout Board.

* Bit Order: MSB (Most Significant Bit) First.

***

### Board Dimensions:

![MicroSD Breakout Dimensions](https://github.com/Boardoza/Boardoza_MicroSD_Breakout_Board/raw/main/assets/MicroSD%20Dimension.png)

***

{% hint style="info" %}
Ready to integrate? You can purchase the **MicroSD Breakout Board** directly from our [Online Store](https://www.robotshop.com/products/acrome-boardoza-microsd-breakout-board?qd=154072743c0290d54a078a3e8fbf22fe) . Worldwide shipping is available for engineering samples and production batches.
{% endhint %}


# RFM6601W LoRa Module

### Overview

The Boardoza RFM6601W is a high-performance, ultra-low-power SoC (System on Chip) LoRa module designed for long-range wireless data communication. Based on the robust RFM6601W engine, this module integrates a 32-bit MCU and a powerful LoRa transceiver into a single package, making it an ideal choice for LPWAN (Low Power Wide Area Network) applications.

Engineered for reliability in harsh environments, it provides deep indoor penetration and extreme outdoor range, making it the backbone for smart agriculture, utility metering, and industrial tracking systems.

***

|                                                             Front Side                                                             |                                                             Back Side                                                            |
| :--------------------------------------------------------------------------------------------------------------------------------: | :------------------------------------------------------------------------------------------------------------------------------: |
| ![RFM6601W Front](https://github.com/Boardoza/Boardoza_RFM6601W_LoRa_Wireless_Breakout_Board/raw/main/assets/RFM6601W%20Front.png) | ![RFM6601W Back](https://github.com/Boardoza/Boardoza_RFM6601W_LoRa_Wireless_Breakout_Board/raw/main/assets/RFM6601W%20Back.png) |

<div align="left"><figure><img src="/files/aOrwLPmeD9lDSPOKPlwI" alt="" width="375"><figcaption></figcaption></figure></div>

***

### Core Technical Specifications

* Microcontroller: Integrated 32-bit RISC MCU (optimized for low-power operation).
* Radio Transceiver: High-sensitivity LoRa® modulation engine.
* Frequency Range: 868 MHz / 915 MHz (Region dependent).
* Maximum Output Power: Up to +22 dBm (Programmable).
* Sensitivity: Down to -148 dBm (Enabling extreme long-range links).
* Modulation Schemes: LoRa, (G)FSK, (G)MSK, and BPSK.
* Power Consumption:
  * Deep Sleep: < 2µA (Ideal for multi-year battery operation).
  * RX Mode: \~4.5mA (Ultra-low power reception).
* Interfaces: Multi-channel UART, SPI, I2C, and GPIOs for peripheral sensor integration.

***

### Key Engineering Features

#### **Industrial-Grade LPWAN Capability**

The RFM6601W leverages LoRa modulation technology to achieve significantly higher range than traditional FSK or OOK systems. Its high interference immunity ensures stable data transmission in RF-congested environments.

#### **SoC Architecture**

By integrating the MCU and the RF front-end on a single die, the RFM6601W reduces the overall PCB footprint and simplifies the hardware design. This eliminates the need for an external controller, reducing the Bill of Materials (BOM) cost for large-scale deployments.

#### **Advanced Power Management**

The module is designed with a sophisticated power distribution unit (PDU) that supports wide voltage input ranges. Its ultra-low sleep current allows for deployment in remote locations using only a small Li-SoCl2 battery or energy harvesting sources.

***

### Applications

* Smart Agriculture: Soil moisture monitoring and automated irrigation control over several kilometers.
* Industrial Monitoring: Wireless sensor networks for factory automation and predictive maintenance.
* Smart City Infrastructure: Remote utility metering (water, gas, electricity) and street lighting control.
* Asset Tracking: Long-range GPS tracking for logistics and livestock management.

Ensure your project has the range it deserves with the RFM6601W.

***

### Board Dimensions:

![RFM6601W Dimensions](https://github.com/Boardoza/Boardoza_RFM6601W_LoRa_Wireless_Breakout_Board/raw/main/assets/RFM6601W%20Dimension.png)

***

{% hint style="info" %}
Ready to integrate? You can purchase the **RFM6601W LoRa Module** directly from our [Online Store](https://www.robotshop.com/products/acrome-rfm6601w-lora-wireless-communication-module-breakout-board?qd=93de991b07d76167724c700bbcc851bd) . Worldwide shipping is available for engineering samples and production batches.
{% endhint %}


# Vibration Motor Driver Breakout Board

### Overview

The Boardoza Vibration Motor Driver is a specialized, compact breakout board designed for precision control of DC vibration motors (ERM) and Linear Resonant Actuators (LRA). Engineered for haptic feedback applications, this module provides a seamless interface between low-power microcontrollers (such as ESP32, STM32, or Arduino) and high-current vibration motors.

With its 25x25mm ultra-compact footprint, it is an ideal solution for wearable devices, handheld controllers, and industrial alert systems where tactile notification is required.

|                                                                  Front Side                                                                 |                                                                 Back Side                                                                 |
| :-----------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------: |
| ![Vibration Motor Front](https://github.com/Boardoza/Boardoza_Vibration_Motor_Breakout_Board/raw/main/assets/Vibration%20Motor%20Front.png) | ![Vibration Motor Back](https://github.com/Boardoza/Boardoza_Vibration_Motor_Breakout_Board/raw/main/assets/Vibration%20Motor%20Back.png) |

![](/files/ftdyPxwEBLHCJiK4PzHd)<br>

***

### Core Technical Specifications

* Driver Topology: High-efficiency MOSFET-based driver circuit optimized for inductive loads.
* Input Voltage: Compatible with standard logic levels (3.3V to 5V).
* Control Interface: PWM Capable: Supports Pulse Width Modulation for adjustable vibration intensity.
  * Digital Logic: Simple ON/OFF control via GPIO.
* Form Factor: 25x25mm PCB — optimized for space-constrained embedded designs.
* Connector Interface: Input: Standard 0.1" (2.54mm) pitch headers for breadboard and jumper wire compatibility.
  * Output: Dedicated motor output pads for secure soldering or JST connector integration.

***

### Key Engineering Features

#### **Precise Haptic Control**

Unlike direct GPIO driving, which can damage microcontroller pins due to back-EMF (Electromotive Force), this breakout board features integrated flyback protection. This ensures the safety of your MCU while allowing for high-frequency PWM switching to create complex haptic patterns (e.g., varying pulse strengths, ramps, and patterns).

#### **Low Power Consumption**

Designed with mobile and battery-operated applications in mind, the driver minimizes quiescent current draw, ensuring that the vibration system does not significantly impact the overall power budget of the device during idle states.

#### **Modular Integration**

The standardized pinout allows for rapid integration into existing prototyping ecosystems. The board serves as a robust power stage, translating low-current logic signals into the high-current drive required by eccentric rotating mass (ERM) motors.

#### Applications

* Wearable Haptics: Silent alerts for smartwatches and fitness trackers.
* User Interface Feedback: Tactile confirmation for touchless buttons or industrial panels.
* Alert Systems: Non-visual notification systems for noisy industrial environments.
* Medical Devices: Discrete vibration prompts for patient monitoring equipment.

***

### Board Dimensions:

![Vibration Motor Breakout Dimensions](https://github.com/Boardoza/Boardoza_Vibration_Motor_Breakout_Board/raw/main/assets/Vibration%20Motor%20Dimension.png)

***

{% hint style="info" %}
Ready to integrate? You can purchase the Boardoza Vibration Motor Driver directly from our [Online Store](https://www.robotshop.com/products/acrome-vibration-motor-driver-breakout-board?qd=d3c99ca276d16a31902168cc9c39b279). Worldwide shipping is available for engineering samples and production batches.
{% endhint %}


# Pulse S32-S3 Development Board

### Overview

The Boardoza Pulse S32-S3 is a high-performance, industrial-grade development breakout board built around the Espressif ESP32-S3-WROOM-1-N4R2 module. Engineered for rapid prototyping and seamless deployment, this board integrates advanced connectivity with robust power management in a standardized 60x60mm form factor.

Designed for professional firmware developers and hardware engineers, the Pulse S32-S3 bridges the gap between evaluation and production-ready embedded systems, specifically targeting IoT, smart industrial automation, and edge computing applications.

|                                                                                                                         Front Side                                                                                                                        |                                                                                                                        Back Side                                                                                                                        |
| :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: |
| [![Boardoza\_Pulse](https://github.com/Boardoza/Boardoza_ESP32-S3_Pulse_Development_Board/raw/main/assets/Pulse%20S32-S3%20Front.png)](https://github.com/Boardoza/Boardoza_ESP32-S3_Pulse_Development_Board/blob/main/assets/Pulse%20S32-S3%20Front.png) | [![Boardoza\_Pulse](https://github.com/Boardoza/Boardoza_ESP32-S3_Pulse_Development_Board/raw/main/assets/Pulse%20S32-S3%20Back.png)](https://github.com/Boardoza/Boardoza_ESP32-S3_Pulse_Development_Board/blob/main/assets/Pulse%20S32-S3%20Back.png) |

<div align="left"><figure><img src="/files/MB2KdPlTsISnUTuzsLA8" alt="" width="375"><figcaption></figcaption></figure></div>

***

### Core Technical Specifications

* MCU Core: Dual-core 32-bit Xtensa® LX7 microprocessor running up to 240 MHz.
* Memory Architecture:
  * Internal SRAM: 512 KB
  * External Flash: 8 MB (via QSPI)
  * External PSRAM: 2 MB (Optimized for memory-intensive AI and DSP tasks)
* Wireless Connectivity: \* Wi-Fi: IEEE 802.11 b/g/n (up to 150 Mbps)
  * Bluetooth: Bluetooth 5 (LE) with Long Range support.
* Power Management:
  * Dual-source input via USB Type-C (5V) or 1S Li-Ion Battery (3.7V).
  * Optimized LDO regulators for ultra-low power consumption in Deep Sleep mode.
  * On-board battery charging circuit for portable deployment.
* Form Factor: Industrial-standard 60x60mm PCB layout for modular compatibility.

***

### Hardware Interfaces & Connectivity

The Pulse S32-S3 is designed with a rich peripheral set to ensure maximum flexibility for sensor fusion and actuator control:

1. I2C Interface (J3 Connector): Dedicated bus for seamless sensor integration.
2. UART Interface (J4 Connector): High-speed asynchronous communication for telemetry and debugging.
3. Extensive GPIO Header: 22 multi-function GPIO pins supporting SPI, PWM, ADC, and DAC functionalities.
4. Visual Feedback: Integrated Addressable RGB LED for status monitoring and diagnostic signaling.

***

### Key Engineering Features

#### AI Acceleration & Signal Processing

The ESP32-S3 silicon includes dedicated vector instructions for accelerating Artificial Intelligence (AI) workloads and Digital Signal Processing (DSP). This makes the Pulse S32-S3 an ideal platform for high-performance edge inference and voice recognition.

#### **Robust Power Path Management**

The board features an intelligent power switching mechanism between USB and Battery inputs, ensuring continuous operation for field-deployed devices. The integrated 3.3V LDO provides stable voltage rails even under high peak currents during wireless transmission.

#### **Ecosystem Compatibility**

Fully compatible with modern development environments, including:

* ESP-IDF (Native SDK)
* Arduino IDE
* PlatformIO
* MicroPython / CircuitPython

#### Applications

* Industrial IoT (IIoT): Edge data processing and gateway communication.
* Smart Home Systems: Centralized control hubs with voice assistant capabilities.
* Wearable Technology: Energy-efficient, battery-powered health and fitness trackers.
* Remote Sensing: Long-range telemetry using Wi-Fi/BLE mesh networking.

***

### Board Dimensions

[![Pulse ESP32-S3 Development Board](https://github.com/Boardoza/Boardoza_ESP32-S3_Pulse_Development_Board/raw/main/assets/Pulse%20S32-S3%20Dimension.png)](https://github.com/Boardoza/Boardoza_ESP32-S3_Pulse_Development_Board/blob/main/assets/Pulse%20S32-S3%20Dimension.png)

***

{% hint style="info" %}
Ready to integrate? You can purchase the Boardoza **Pulse S32-S3** directly from our [Online Store](https://www.robotshop.com/products/acrome-boardoza-pulse-esp32-s3-development-board?qd=45b5b0d32f98b727df8bde026846231b),. Worldwide shipping is available for engineering samples and production batches.
{% endhint %}


# Basics

Fundamental Concepts & Sensor Applications

The Basics section is designed to introduce beginners to the fundamental principles of electronics and the Acrome SMD ecosystem. This section focuses on core concepts such as LED control, button interactions, and sensor integration. It provides a structured and easy-to-follow approach, ensuring that users understand how software and hardware interact to create functional electronic systems.

Projects in this category emphasize simplicity and fundamental learning while covering essential concepts like input/output control, automation, and basic reactive systems. These beginner-friendly projects help students and hobbyists build confidence in working with sensors and electronic modules. Whether you are new to electronics or looking to reinforce your understanding, this section serves as the ideal starting point.


# Blink

The LED Blink application is a project that allows the user to control the blinking of an LED using an [SMD ](/electronics/smd-red)and an [RGB LED Module](/electronics/add-on-modules/rgb-led-module). This project is designed for simplicity, making it an ideal starting point for those wishing to experience the SMD hardware control using [the SMD libraries](/software/libraries).

<div data-full-width="false"><figure><img src="/files/Gbpob1tlT2sbu5hoYtLj" alt=""><figcaption><p>"Blink" Project</p></figcaption></figure></div>

**About Tools and Materials:**

[SMD Red](/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](/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) ([Purchase Here](https://www.robotshop.com/products/acrome-arduino-gateway-shield-module-acrome-smd-products))

[RGB LED Module](/electronics/add-on-modules/rgb-led-module) ([Purchase Here](https://www.robotshop.com/products/acrome-rgb-led-add-on-module-acrome-smd-products))

## **Step 1: Hardware & Software Overview**

**Project Key Components**

* [**SMD**](/electronics/smd-red)

  The SMD acts as a bridge between the script and the [RGB LED Module](/electronics/add-on-modules/rgb-led-module). It is responsible for interpreting the commands sent by the script and translating them into actions that toggle the RGB module.
* [**RGB LED Module**](/electronics/add-on-modules/rgb-led-module)

  The [RGB LED Module](/electronics/add-on-modules/rgb-led-module) is designed to emit different colors, allowing users to experiment with different lighting effects.
* [**SMD Libraries**](/software/libraries)

  The SMD library is at the heart of the application. It communicates with the SMD using a specific communication protocol, sending commands to turn the RGB LED on or off, adjust the color, or set a specific blinking pattern.

**Project Key Features**

* **Detailed Control over the LED**

  The user can easily control the LED of the [RGB LED Module](/electronics/add-on-modules/rgb-led-module) colors by simply using the necessary function of SMD libraries. The LED on the module can emit all RGB color values.

## **Step 2: Assemble**

1. **Hardware Setup**
   * Connect the SMD to the PC or Arduino board using [USB Gateway Module](/electronics/gateway-modules/usb-gateway-module) or [Arduino Gateway Module](/electronics/gateway-modules/arduino-gateway-module).
   * Connect the [RGB LED Module](/electronics/add-on-modules/rgb-led-module) 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/pqmQgGt7S5WSHv1itZoh" 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 [RGB LED Module](/electronics/add-on-modules/rgb-led-module).
2. **Experience and Customize:**
   * Explore different blinking patterns, change the color of the RGB LED to suit your preferences.

## Codes

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

```python
import time
from smd.red import *
from serial.tools.list_ports import comports
from platform import system

def USB_Port():
    """
    Detects the USB serial port based on the operating system.
    Returns the detected port or None if no suitable port is found.
    """
    ports = list(comports())
    usb_names = {
        "Windows": ["USB Serial Port"],  # Serial port names specific to Windows
        "Linux": ["/dev/ttyUSB"],        # Serial port names specific to Linux
        "Darwin": [                      # Serial port names specific to macOS
            "/dev/tty.usbserial",
            "/dev/tty.usbmodem",
            "/dev/tty.SLAB_USBtoUART",
            "/dev/tty.wchusbserial",
            "/dev/cu.usbserial",
        ]
    }
    
    # Get the operating system name
    os_name = system()
    if ports:
        for port, desc, hwid in sorted(ports):
            # Check if any known USB name matches the port or its description
            if any(name in port or name in desc for name in usb_names.get(os_name, [])):
                print("Connected to:", port)
                return port
        # If no suitable port is found, display all available ports
        print("Available ports:")
        for port, desc, hwid in ports:
            print(f"Port: {port}, Description: {desc}, HWID: {hwid}")
    else:
        print("No ports detected!")
    return None

# Detect the serial port dynamically
SerialPort = USB_Port()
if not SerialPort:
    print("No suitable USB port found! Exiting...")
    exit(1)

# Define constants
baudrate = 115200       # Baud rate for communication
ID = 0                  # ID of the SMD
rgb_module_id = 5       # ID of the RGB LED module

try:
    # Initialize the Master module for communication with the SMD
    master = Master(SerialPort, baudrate)       # Sets up the USB gateway module
    master.attach(Red(ID))                      # Connects to the SMD with the specified ID
    master.scan_modules(ID)                     # Scans and identifies connected modules to the SMD

    # RGB LED control loop
    while True:
        # Set the RGB LED to red
        master.set_rgb(ID, rgb_module_id, 255, 0, 0)        # RGB values: 255 (Red), 0 (Green), 0 (Blue)
        time.sleep(0.5)                                     # Delay to control blinking frequency
        # Turn off the RGB LED
        master.set_rgb(ID, rgb_module_id, 0, 0, 0)          # RGB values: 0 (All colors off)
        time.sleep(0.5)                                     # Delay to control blinking frequency

except FileNotFoundError as e:
    # Handle the case when the serial port is not found
    print(f"Error: {e}")
    print("Make sure the specified serial port exists and is connected.")
except Exception as e:
    # Handle any unexpected errors
    print(f"Unexpected error: {e}")                                    # Value can be changed to see how the blinking frequency changes
```

{% endcode %}
{% endtab %}

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

```cpp
#include <Acrome-SMD.h>

#define ID        0           // ID of the SMD
#define BAUDRATE  115200      // Baud rate of the communication

Red master(ID, Serial, BAUDRATE);    // Defines the Arduino gateway module

int rgb_module_id = 1;              // ID of the RGB LED module
void setup() {
    master.begin();                 // Starts the communication
    master.scanModules();           // Scans for the connected modules
}

void loop() {
    master.setRGB(rgb_module_id, 255, 0, 0);    // Numbers are correspond to the R - G - B color values
    delay(500);                                 // Value can be changed to see how the blinking frequency changes
    master.setRGB(rgb_module_id, 0, 0, 0);      // Sets all colors to zero, meaning turning the RGB LED off
    delay(500);                                 // Value can be changed to see how the blinking frequency changes
}

```

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


# Action - Reaction

The LED toggle application with a button is the most used project for simple input/output project example. This project allows the user to control the [RGB LED Module](/electronics/add-on-modules/rgb-led-module) with the [Button Module](/electronics/add-on-modules/button-module) by simply toggling an LED.

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

**About Tools and Materials:**

[SMD Red](/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](/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) ([Purchase Here](https://www.robotshop.com/products/acrome-arduino-gateway-shield-module-acrome-smd-products))

[RGB LED Module](/electronics/add-on-modules/rgb-led-module) ([Purchase Here](https://www.robotshop.com/products/acrome-rgb-led-add-on-module-acrome-smd-products))

[Button Module](/electronics/add-on-modules/button-module) ([Purchase Here](https://www.robotshop.com/products/acrome-button-add-on-module-acrome-smd-products?pr_prod_strat=e5_desc\&pr_rec_id=e23ece12f\&pr_rec_pid=8120246796449\&pr_ref_pid=8121226592417\&pr_seq=uniform))

## **Step 1: Hardware & Software Overview**

**Project Key Components**

1. [**SMD**](/electronics/smd-red)

   The 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 toggle the [RGB LED Module](/electronics/add-on-modules/rgb-led-module).
2. [**RGB LED Module**](/electronics/add-on-modules/rgb-led-module)

   The [RGB LED Module](/electronics/add-on-modules/rgb-led-module) is designed to emit different colors, allowing users to experiment with different lighting effects.
3. [**Button Module**](/electronics/add-on-modules/button-module)

   The [Button Module](/electronics/add-on-modules/button-module) is the physical interface for receiving input from the user. The input can be used to trigger the script in an encoded way.
4. [**SMD Libraries**](/software/libraries)

   The SMD library is at the heart of the application. It communicates with the SMD using a specific communication protocol, sending commands to read the [Button Module](/electronics/add-on-modules/button-module) and toggle the LED on the [RGB LED Module](/electronics/add-on-modules/rgb-led-module).

**Project Key Features**

* **A Basic Physical Interaction**

  The application supports a toggle functionality, allowing the user to press the button to toggle the LED. This provides a simple physical interaction with project.
* **Visualizing the Input**

  The [RGB LED Module](/electronics/add-on-modules/rgb-led-module) serves as a visual indicator of the current state of the [Button Module](/electronics/add-on-modules/button-module). When the button is pressed, the LED turns on; when the button is not pressed, the LED turns off.

## **Step 2: Assemble**

**Getting Started**

1. **Hardware Setup**
   * Connect the SMD to the PC or Arduino board using [USB Gateway Module](/electronics/gateway-modules/usb-gateway-module) or [Arduino Gateway Module](/electronics/gateway-modules/arduino-gateway-module).
   * Connect the [RGB LED Module](/electronics/add-on-modules/rgb-led-module) and the [Button Module](/electronics/add-on-modules/button-module) 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/GWo8nyiG7bAb4RZ6WAWm" 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 [Button Module](/electronics/add-on-modules/button-module) and [RGB LED Module](/electronics/add-on-modules/rgb-led-module).
2. **Toggle LED State**
   * Press the button on the [Button Module](/electronics/add-on-modules/button-module) to toggle the RGB LED. Observe the visual feedback of the LED.

## Codes

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

```python
from serial.tools.list_ports import comports
from platform import system
from smd.red import *

baudrate = 115200       # Baud rate of communication
ID = 0                  # ID of the SMD
rgb_module_id = 5       # ID of the RGB LED module
button_module_id = 5    # ID of the button module


def 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.
    """
    # Get a list of available ports
    ports = list(comports())
    
    # Known USB port names for different operating systems
    usb_names = {
        "Windows": ["USB Serial Port"],  # Names specific to Windows
        "Linux": ["/dev/ttyUSB"],        # Names specific to Linux
        "Darwin": [                      # Names specific to macOS
            "/dev/tty.usbserial",
            "/dev/tty.usbmodem",
            "/dev/tty.SLAB_USBtoUART",
            "/dev/tty.wchusbserial",
            "/dev/cu.usbserial",
        ]
    }

    # Detect the operating system
    os_name = system()
    print(f"Operating System: {os_name}")

    if ports:
        for port, desc, hwid in sorted(ports):
            # Check if the port matches any known USB names
            if any(name in port or name in desc for name in usb_names.get(os_name, [])):
                print(f"USB device detected on port: {port}")
                return port  # Return the first matching port
        # If no suitable port is found, print the list of available ports
        print("No suitable USB device found. Available ports:")
        for port, desc, hwid in ports:
            print(f"Port: {port}, Description: {desc}, HWID: {hwid}")
    else:
        print("No ports detected!")
    return None


try:
    # Find a valid serial port
    SerialPort = USB_Port()
    if not SerialPort:
        raise Exception("No compatible USB port found. Please check your connection.")

    print(f"Using serial port: {SerialPort}")

    # Initialize the SMD module
    master = Master(SerialPort, baudrate)       # Defines the USB gateway module
    master.attach(Red(ID))                      # Gives access to the SMD of specified ID
    master.scan_modules(ID)                     # Scans and identifies the modules connected to the SMD

    # Main loop
    while True:
        # Get the button state from the SMD
        button_state = master.get_button(ID, button_module_id)

        if button_state == 1:
            # Set the RGB LED to red
            master.set_rgb(ID, rgb_module_id, 255, 0, 0)  # RGB values for red
        else:
            # Turn off the RGB LED
            master.set_rgb(ID, rgb_module_id, 0, 0, 0)    # RGB values for off

except Exception as e:
    print(f"Error: {e}")
```

{% endcode %}
{% endtab %}

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

```cpp
#include <Acrome-SMD.h>

#define ID        0           // ID of the SMD
#define BAUDRATE  115200      // Baud rate of the communication

Red master(ID, Serial, BAUDRATE);    // Defines the Arduino gateway module

int rgb_module_id = 1;              // ID of the RGB LED module
int button_module_id = 1;           // ID of the button module

int button_state = 0;               // Variable to store the button state

void setup() {
    master.begin();                 // Starts the communication
    master.scanModules();           // Scans for the connected modules
}

void loop() {
    button_state = master.getButton(button_module_id);      // Getting the button state and storing it
    
    if (button_state == 1) {
        master.setRGB(rgb_module_id, 255, 0, 0);    // Numbers are correspond to the R - G - B color values
    }

    else {
        master.setRGB(rgb_module_id, 0, 0, 0);      // Sets all colors to zero, meaning turning the RGB LED off
    }
}

```

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


# Autonomous Lighting

The autonomous lighting project is a basic environmental interaction example. It imitates a night lamp, using the [Ambient Light Sensor Module](/electronics/add-on-modules/ambient-light-sensor-module) to sense the light level and let the user decide what level is dark enough to turn on the [RGB LED Module](/electronics/add-on-modules/rgb-led-module). It also helps with energy efficiency by turning the LED when it is bright enough.

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

**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) ([Purchase Here](https://www.robotshop.com/products/acrome-arduino-gateway-shield-module-acrome-smd-products))

[RGB LED Module](https://docs.acrome.net/electronics/add-on-modules/rgb-led-module) ([Purchase Here](https://www.robotshop.com/products/acrome-rgb-led-add-on-module-acrome-smd-products))

[Ambient Light Sensor Module](/electronics/add-on-modules/ambient-light-sensor-module)  ([Purchase Here](https://www.robotshop.com/products/acrome-ambient-light-sensor-add-on-module-acrome-smd-products))

## **Step 1: Hardware & Software Overview**

**Project Key Components**

1. [**SMD**](/electronics/smd-red)

   The 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 [Ambient Light Sensor Module](/electronics/add-on-modules/ambient-light-sensor-module) and toggle the [RGB LED Module](/electronics/add-on-modules/rgb-led-module).
2. [**RGB LED Module**](/electronics/add-on-modules/rgb-led-module)

   The [RGB LED Module](/electronics/add-on-modules/rgb-led-module) is designed to emit different colors, allowing users to experiment with different lighting effects.
3. [**Ambient Light Sensor Module**](/electronics/add-on-modules/ambient-light-sensor-module)

   The [Ambient Light Sensor Module](/electronics/add-on-modules/ambient-light-sensor-module) is measures the surrounding light intensity and provides feedback of the intensity to the script, allowing the user to decide whether to turn on or off the LED.
4. [**SMD Libraries**](/software/libraries)

   The SMD library is at the heart of the application. It communicates with the SMD using a specific communication protocol, sending commands to read the [Ambient Light Sensor Module](/electronics/add-on-modules/ambient-light-sensor-module) and toggle the LED on the [RGB LED Module](/electronics/add-on-modules/rgb-led-module).

**Project Key Features**

* **Automatic Light Sensing**

  The [Ambient Light Sensor Module](/electronics/add-on-modules/ambient-light-sensor-module) is a input module and the bridge between the physical world and the script, allowing the user to read the data of the environment.
* **Energy-Efficient Operation**

  The [Ambient Light Sensor Module](/electronics/add-on-modules/ambient-light-sensor-module) allows the user to only turn on the light when it is dark and needed, thus, it helps with the energy efficiency.
* **Real-time Monitoring**

  The script can also be modified to monitor the ambient light intensity in real-time.

## **Step 2: Assemble**

**Getting Started**

1. **Hardware Setup**
   * Connect the SMD to the PC or Arduino board using [USB Gateway Module](/electronics/gateway-modules/usb-gateway-module) or [Arduino Gateway Module](/electronics/gateway-modules/arduino-gateway-module).
   * Connect the [Ambient Light Sensor Module](/electronics/add-on-modules/ambient-light-sensor-module) and the [RGB LED Module](/electronics/add-on-modules/rgb-led-module) 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/rJ7maRrLH44nQzLjLVLe" 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, the [Ambient Light Module](/electronics/add-on-modules/ambient-light-sensor-module) and the [RGB LED Module](/electronics/add-on-modules/rgb-led-module).
2. **Observe Autonomous Operation**
   * Observe how the LED automatically turns on when the environment becomes dark and turns off when there is sufficient ambient light.

## Codes

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

```python
from serial.tools.list_ports import comports
from platform import system
from smd.red import *

baudrate = 115200       # Baud rate of communication
ID = 0                  # ID of the SMD
rgb_module_id = 5       # ID of the RGB LED module
ambient_module_id = 5   # ID of the ambient light sensor module


def 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.
    """
    # Get a list of available ports
    ports = list(comports())
    
    # Known USB port names for different operating systems
    usb_names = {
        "Windows": ["USB Serial Port"],  # Names specific to Windows
        "Linux": ["/dev/ttyUSB"],        # Names specific to Linux
        "Darwin": [                      # Names specific to macOS
            "/dev/tty.usbserial",
            "/dev/tty.usbmodem",
            "/dev/tty.SLAB_USBtoUART",
            "/dev/tty.wchusbserial",
            "/dev/cu.usbserial",
        ]
    }

    # Detect the operating system
    os_name = system()
    print(f"Operating System: {os_name}")

    if ports:
        for port in ports:
            # Check if the port matches any known USB names
            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
        # If no suitable port is found, print the list of available ports
        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


try:
    # Find a valid serial port
    SerialPort = USB_Port()
    if not SerialPort:
        raise Exception("No compatible USB port found. Please check your connection.")

    print(f"Using serial port: {SerialPort}")

    # Initialize the SMD module
    master = Master(SerialPort, baudrate)       # Defines the USB gateway module
    master.attach(Red(ID))                      # Gives access to the SMD of specified ID
    master.scan_modules(ID)                     # Scans and identifies the modules connected to the SMD

    # Main loop
    while True:
        # Get ambient light data from the sensor
        light = master.get_light(ID, ambient_module_id)  # Variable to store the ambient light data
        print(f"Ambient light level: {light}")           # Print the value to observe

        if light < 30:
            # Set the RGB LED to white
            master.set_rgb(ID, rgb_module_id, 255, 255, 255)  # RGB values for white
        else:
            # Turn off the RGB LED
            master.set_rgb(ID, rgb_module_id, 0, 0, 0)        # RGB values for off

except Exception as e:
    print(f"Error: {e}")
```

{% endcode %}
{% endtab %}

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

```cpp
#include <Acrome-SMD.h>

#define ID        0           // ID of the SMD
#define BAUDRATE  115200      // Baud rate of the communication

Red master(ID, Serial, BAUDRATE);    // Defines the Arduino gateway module

int rgb_module_id = 1;              // ID of the RGB LED module
int ambient_module_id = 1;          // ID of the ambient module

int light = 0;               // Variable to store the button state

void setup() {
    master.begin();                 // Starts the communication
    master.scanModules();           // Scans for the connected modules
}

void loop() {
    light = master.getLight(ambient_module_id);      // Getting the ambient light value and storing it
    
    if (light < 30) {
        master.setRGB(rgb_module_id, 255, 255, 255);    // Numbers are correspond to the R - G - B color values
    }

    else {
        master.setRGB(rgb_module_id, 0, 0, 0);      // Sets all colors to zero, meaning turning the RGB LED off
    }
}

```

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


# Smart Doorbell

The Smart Doorbell project allows the user to interact with environment with both input and output modules. The Ultrasonic Distance Sensor Module is used to detect if there is a person or a hand in front of the doorbell. If anything is near it, it detects and sends a feedback to script, allowing the user to play a sound with a buzzer.

**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) ([Purchase Here](https://www.robotshop.com/products/acrome-arduino-gateway-shield-module-acrome-smd-products))

[Buzzer Module](/electronics/add-on-modules/buzzer-module) ([Purchase Here](https://www.robotshop.com/products/acrome-buzzer-sound-add-on-module-acrome-smd-products))

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

## **Step 1: Hardware & Software Overview**

**Project Key Components**

1. [**SMD**](/electronics/smd-red)

   The 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 [Ultrasonic Distance Sensor Module](/electronics/add-on-modules/ultrasonic-distance-sensor-module) and play an alert sound with the [Buzzer Module](/electronics/add-on-modules/buzzer-module).
2. [**Buzzer Module**](/electronics/add-on-modules/buzzer-module)

   The [Buzzer Module](/electronics/add-on-modules/buzzer-module) is connected to the system for the most crucial role for the application, that is alerting the user when something is nearby.
3. [**Ultrasonic Distance Sensor Module**](/electronics/add-on-modules/ultrasonic-distance-sensor-module)

   The [Ultrasonic Distance Sensor Module](/electronics/add-on-modules/ultrasonic-distance-sensor-module) is used to detect if anything is nearby and if there is, how many centimeters away.
4. [**SMD Libraries**](/software/libraries)

   The SMD library is at the heart of the application. It communicates with the SMD using a specific communication protocol, sending commands to read the [Ultrasonic Distance Sensor Module](/electronics/add-on-modules/ultrasonic-distance-sensor-module) and play an alert sound with the [Buzzer Module](/electronics/add-on-modules/buzzer-module).

**Project Key Features**

* **Proximity-Based Activation**

  The project uses the module with the HC-SR04 to detect the surroundings via ultrasonic sound waves. It makes a great way to understand how physics of sound works and also see that it is a way of interacting with environment with such an input sensor.
* **Adjustable Sensitivity**

  The user can change the sensivity of the distance check, customizing it to be more sensitive or unresponsive to near surroundings.
* **Real-time Monitoring**

  The script can easily provide the real-time distance monitoring if the user add a simple line. It enhances the code and gives more opportunity to monitor the surroundings.

## **Step 2: Assemble**

**Getting Started**

1. **Hardware Setup**
   * Connect the SMD to the PC or Arduino board using [USB Gateway Module](https://acrome.gitbook.io/acrome-smd-docs/electronics/gateway-modules/usb-gateway-module) or [Arduino Gateway Module](https://acrome.gitbook.io/acrome-smd-docs/electronics/gateway-modules/arduino-gateway-module).
   * Connect the [Ultrasonic Distance Sensor Module](/electronics/add-on-modules/ultrasonic-distance-sensor-module) and the [Buzzer Module](/electronics/add-on-modules/buzzer-module) 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/amZluCGWjvQBoaeoc1Dc" 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 Module](/electronics/add-on-modules/ultrasonic-distance-sensor-module) and the [Buzzer Module](/electronics/add-on-modules/buzzer-module).
2. **Observe Buzzer Activation**
   * Use an object or a hand to trigger the [Ultrasonic Distance Sensor Module](/electronics/add-on-modules/ultrasonic-distance-sensor-module), if it will detect an obstacle in the specified range, the script will send a signal to the [Buzzer Module](/electronics/add-on-modules/buzzer-module) to alert the user.

## Codes

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

```python
from serial.tools.list_ports import comports
from platform import system
from smd.red import *

baudrate = 115200          # Baud rate of communication
ID = 0                     # ID of the SMD
buzzer_module_id = 5       # ID of the buzzer module
distance_module_id = 1     # ID of the ultrasonic distance sensor module


def 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.
    """
    # Get a list of available ports
    ports = list(comports())
    
    # Known USB port names for different operating systems
    usb_names = {
        "Windows": ["USB Serial Port"],  # Names specific to Windows
        "Linux": ["/dev/ttyUSB"],        # Names specific to Linux
        "Darwin": [                      # Names specific to macOS
            "/dev/tty.usbserial",
            "/dev/tty.usbmodem",
            "/dev/tty.SLAB_USBtoUART",
            "/dev/tty.wchusbserial",
            "/dev/cu.usbserial",
        ]
    }

    # Detect the operating system
    os_name = system()
    print(f"Operating System: {os_name}")

    if ports:
        for port in ports:
            # Check if the port matches any known USB names
            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
        # If no suitable port is found, print the list of available ports
        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


try:
    # Find a valid serial port
    SerialPort = USB_Port()
    if not SerialPort:
        raise Exception("No compatible USB port found. Please check your connection.")

    print(f"Using serial port: {SerialPort}")

    # Initialize the SMD module
    master = Master(SerialPort, baudrate)       # Defines the USB gateway module
    master.attach(Red(ID))                      # Gives access to the SMD of specified ID
    master.scan_modules(ID)                     # Scans and identifies the modules connected to the SMD

    # Main loop
    while True:
        # Get distance data from the ultrasonic sensor
        distance = master.get_distance(ID, distance_module_id)  # Variable to store the distance data
        print(f"Distance: {distance} cm")                      # Print the value to observe

        if distance < 15:
            # Set the buzzer frequency to 600 Hz
            master.set_buzzer(ID, buzzer_module_id, 600)        # Number corresponds to the frequency of the buzzer
        else:
            # Turn off the buzzer
            master.set_buzzer(ID, buzzer_module_id, 0)          # Sets the buzzer frequency to 0

except Exception as e:
    print(f"Error: {e}")
```

{% endcode %}
{% endtab %}

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

```cpp
#include <Acrome-SMD.h>

#define ID        0           // ID of the SMD
#define BAUDRATE  115200      // Baud rate of the communication

Red master(ID, Serial, BAUDRATE);       // Defines the Arduino gateway module

int buzzer_module_id = 1;               // ID of the buzzer module
int distance_module_id = 1;             // ID of the ultrasonic distance sensor module

int distance = 0;                       // Variable to store the distance data

void setup() {
    master.begin();                     // Starts the communication
    master.scanModules();               // Scans for the connected modules
}

void loop() {
    distance = master.getDistance(distance_module_id);      // Getting the distance data and storing it
    
    if (distance < 15) {
        master.setBuzzer(buzzer_module_id, 600);            // Number is correspond to the frequency of the buzzer
    }

    else {
        master.setBuzzer(buzzer_module_id, 0);              // Sets the buzzer frequency to 0, meaning turning the buzzer off
    }
}

```

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


# Security System

The Security System project is a simple yet useful real-life scenario application. It uses a [Ultrasonic Distance Sensor Module](https://acrome.gitbook.io/acrome-smd-docs/electronics/add-on-modules/ultrasonic-distance-sensor-module), the [Buzzer Module](/electronics/add-on-modules/buzzer-module) and the [RGB LED Module](/electronics/add-on-modules/rgb-led-module) to work like a geniune security system. The system is designed to be activated when there is a movement in designated area.

**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) ([Purchase Here](https://www.robotshop.com/products/acrome-arduino-gateway-shield-module-acrome-smd-products))

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

[Buzzer Module](/electronics/add-on-modules/buzzer-module) ([Purchase Here](https://www.robotshop.com/products/acrome-buzzer-sound-add-on-module-acrome-smd-products))

[RGB LED Module](https://docs.acrome.net/electronics/add-on-modules/rgb-led-module) ([Purchase Here](https://www.robotshop.com/products/acrome-rgb-led-add-on-module-acrome-smd-products))

## **Step 1: Hardware & Software Overview**

**Project Key Components**

1. [**SMD**](/electronics/smd-red)

   The 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 [Ultrasonic Distance Sensor Module](https://acrome.gitbook.io/acrome-smd-docs/electronics/add-on-modules/ultrasonic-distance-sensor-module) and actuate the visual and audible warning signals.
2. [**Ultrasonic Distance Sensor Module**](/electronics/add-on-modules/ultrasonic-distance-sensor-module)

   The [Ultrasonic Distance Sensor Module](/electronics/add-on-modules/ultrasonic-distance-sensor-module) measures the distance between the sensor and an object in its path. It provides distance data to the script for security monitoring.
3. [**Buzzer Module**](/electronics/add-on-modules/buzzer-module)

   The [Buzzer Module](/electronics/add-on-modules/buzzer-module) serves as the audible warning. It emits sound when activated when there is an object in the designated area.
4. [**RGB LED Module**](/electronics/add-on-modules/rgb-led-module)

   The [RGB LED Module](/electronics/add-on-modules/rgb-led-module) is used to provide visual warning. It can emit different colors and light intensities as programmed.
5. [**SMD Libraries**](/software/libraries)

   The SMD library is at the heart of the application. It communicates with the SMD using a specific communication protocol, sending commands to read the [Ultrasonic Distance Sensor Module](https://acrome.gitbook.io/acrome-smd-docs/electronics/add-on-modules/ultrasonic-distance-sensor-module) and actuate the visual and audible warnings, the [RGB LED Module](/electronics/add-on-modules/rgb-led-module) and the [Buzzer Module](/electronics/add-on-modules/buzzer-module).

**Project Key Features**

* **Distance-based Security Monitoring**

  The Security System continuously monitors the distance measured by the [Ultrasonic Distance Sensor Module](/electronics/add-on-modules/ultrasonic-distance-sensor-module). If the distance of the detected object is equal or closer than the determined distance value, the alert system will be activated.
* **Visual Feedback with the** [**RGB LED Module**](/electronics/add-on-modules/rgb-led-module)

  The [RGB LED Module](/electronics/add-on-modules/rgb-led-module) displays red and blue lights to indicate the security status. Red lights may represent an alert or danger, while blue lights indicate a normal or safe condition.
* **Audible Feedback with the** [**Buzzer Module**](/electronics/add-on-modules/buzzer-module)

  The [Buzzer Module](/electronics/add-on-modules/buzzer-module) emits a sound when the system detects a potential security threat, providing an audible alert to draw attention to the situation.

## **Step 2: Assemble**

**Getting Started**

1. **Hardware Setup**
   * Connect the SMD to the PC or Arduino board using [USB Gateway Module](https://acrome.gitbook.io/acrome-smd-docs/electronics/gateway-modules/usb-gateway-module) or [Arduino Gateway Module](https://acrome.gitbook.io/acrome-smd-docs/electronics/gateway-modules/arduino-gateway-module).
   * Connect the [Ultrasonic Distance Sensor Module](https://acrome.gitbook.io/acrome-smd-docs/electronics/add-on-modules/ultrasonic-distance-sensor-module), the [Buzzer Module](https://acrome.gitbook.io/acrome-smd-docs/electronics/add-on-modules/buzzer-module) and the [RGB LED Module](/electronics/add-on-modules/rgb-led-module) 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/5D0zD6aeEtAuB91E8jPy" alt=""><figcaption></figcaption></figure>

## Step 3: Run & Test

1. **Run the Application**
   * Execute the script, initiating the Security System application.
   * Observe the [RGB LED Module](/electronics/add-on-modules/rgb-led-module) displaying colors and the [Buzzer Module](/electronics/add-on-modules/buzzer-module) emitting sound based on the detected distance.
2. **Customize Security Thresholds**
   * Adjust the predetermined distance threshold in the script to customize the security monitoring levels.
   * Experiment with different colors and sound patterns for the LED and buzzer to suit specific security scenarios.

## Codes

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

```python
from serial.tools.list_ports import comports
from platform import system
from smd.red import *
import time

baudrate = 115200          # Baud rate of communication
ID = 0                     # ID of the SMD
buzzer_module_id = 5       # ID of the buzzer module
distance_sensor_id = 1     # ID of the ultrasonic distance sensor module
rgb_led_id = 5             # ID of the RGB LED module


def 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.
    """
    # Get a list of available ports
    ports = list(comports())
    
    # Known USB port names for different operating systems
    usb_names = {
        "Windows": ["USB Serial Port"],  # Names specific to Windows
        "Linux": ["/dev/ttyUSB"],        # Names specific to Linux
        "Darwin": [                      # Names specific to macOS
            "/dev/tty.usbserial",
            "/dev/tty.usbmodem",
            "/dev/tty.SLAB_USBtoUART",
            "/dev/tty.wchusbserial",
            "/dev/cu.usbserial",
        ]
    }

    # Detect the operating system
    os_name = system()
    print(f"Operating System: {os_name}")

    if ports:
        for port in ports:
            # Check if the port matches any known USB names
            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
        # If no suitable port is found, print the list of available ports
        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


try:
    # Find and initialize the USB port
    SerialPort = USB_Port()
    if not SerialPort:
        raise Exception("No compatible USB port found. Please check your connection.")

    # Initialize the SMD module
    master = Master(SerialPort, baudrate)       # Defines the USB gateway module
    master.attach(Red(ID))                      # Gives access to the SMD of specified ID
    master.scan_modules(ID)                     # Scans and identifies the modules connected to the SMD

    # Main loop
    while True:
        # Get distance data from the ultrasonic sensor
        distance = master.get_distance(ID, distance_sensor_id)  # Variable to store the distance data
        print(f"Distance: {distance} cm")                      # Print the value to observe

        if distance is not None:
            if distance < 15:
                # Activate the buzzer and set RGB LED to red
                master.set_buzzer(ID, buzzer_module_id, 600)          # Set buzzer frequency to 600 Hz
                master.set_rgb(ID, rgb_led_id, red=255, green=0, blue=0)  # Set LED to red
                time.sleep(0.5)                                       # Wait for half a second
                master.set_rgb(ID, rgb_led_id, red=0, green=0, blue=255)  # Change LED to blue
            else:
                # Deactivate the buzzer and turn off the RGB LED
                master.set_buzzer(ID, buzzer_module_id, 0)            # Turn off the buzzer
                master.set_rgb(ID, rgb_led_id, red=0, green=0, blue=0)  # Turn off the LED

        time.sleep(0.1)  # Delay for smooth operation

except Exception as e:
    print(f"Error: {e}")
```

{% endcode %}
{% endtab %}

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

```cpp
#include <Acrome-SMD.h>

// Definitions
#define ID 0                   // ID of the SMD
#define BAUDRATE 115200         // Baud rate of communication
#define BUZZER_MODULE_ID 5      // ID of the buzzer module
#define DISTANCE_SENSOR_ID 1    // ID of the ultrasonic distance sensor module
#define RGB_LED_ID 5            // ID of the RGB LED module

Red master(ID, Serial, BAUDRATE);  // Defines the USB gateway module

void setup() {
    Serial.begin(BAUDRATE);  // Initialize serial communication
    master.begin();          // Start communication with the SMD
    master.scanModules();    // Scan and identify connected modules
}

void loop() {
    // Get distance data from the ultrasonic sensor
    int distance = master.getDistance(DISTANCE_SENSOR_ID);
    Serial.print("Distance: ");
    Serial.print(distance);
    Serial.println(" cm");

    if (distance > 0) {  // If a valid distance value is received
        if (distance < 15) {
            // Activate the buzzer and set RGB LED to red
            master.setBuzzer(BUZZER_MODULE_ID, 600);  // Set buzzer frequency to 600 Hz
            master.setRGB(RGB_LED_ID, 255, 0, 0);     // Set LED to red
            delay(500);  // Wait for half a second
            master.setRGB(RGB_LED_ID, 0, 0, 255);     // Change LED to blue
        } else {
            // Deactivate the buzzer and turn off the RGB LED
            master.setBuzzer(BUZZER_MODULE_ID, 0);
            master.setRGB(RGB_LED_ID, 0, 0, 0);
        }
    }

    delay(100);  // Delay for smooth operation
}
```

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


# Distance Buzzer Warning

This project centers around creating a distance-based feedback system using the ACROME [Smart Motion Device (SMD)](/electronics/smd-red) platform. The system incorporates a [distance sensor](/electronics/add-on-modules/ultrasonic-distance-sensor-module), [RGB LED lights](/electronics/add-on-modules/rgb-led-module), and a [buzzer ](/electronics/add-on-modules/buzzer-module)to provide real-time feedback based on the distance of an object from the sensor. The system also includes a graphical user interface (GUI) for users to monitor the sensor readings and adjust distance settings. The [RGB lights](/electronics/add-on-modules/rgb-led-module) and [buzzer](/electronics/add-on-modules/buzzer-module) provide visual and auditory signals, respectively, based on the proximity of the object to the sensor.

**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) ([Purchase Here](https://www.robotshop.com/products/acrome-arduino-gateway-shield-module-acrome-smd-products))

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

[RGB LED Module](/electronics/add-on-modules/rgb-led-module) ([Purchase Here](https://www.robotshop.com/products/acrome-rgb-led-add-on-module-acrome-smd-products))

[Buzzer Module](/electronics/add-on-modules/buzzer-module) ([Purchase Here](https://www.robotshop.com/products/acrome-buzzer-sound-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>

**Key Components:**

1. [SMD (Smart Motion Device) ](/electronics/smd-red)\
   The [SMD ](/electronics/smd-red)acts as the communication hub, connecting and controlling the[ distance sensor](/electronics/add-on-modules/ultrasonic-distance-sensor-module), [RGB lights](/electronics/add-on-modules/rgb-led-module), and [buzzer](/electronics/add-on-modules/buzzer-module). It processes sensor data and translates it into corresponding [RGB](/electronics/add-on-modules/rgb-led-module) and [buzzer](/electronics/add-on-modules/buzzer-module) feedback, ensuring that the system functions in real-time.
2. [Ultrasonic Distance Sensor](/electronics/add-on-modules/ultrasonic-distance-sensor-module) \
   The [distance sensor](/electronics/add-on-modules/ultrasonic-distance-sensor-module) measures the distance between itself and nearby objects. This data is continuously sent to the [SMD](/electronics/smd-red), which then determines the appropriate feedback to provide based on predefined distance thresholds.
3. [RGB LED Module ](/electronics/add-on-modules/rgb-led-module)\
   The [RGB LED Module](/electronics/add-on-modules/rgb-led-module) displays different colors depending on the distance between the sensor and the object. Colors such as green, yellow, and red are used to indicate different proximity ranges, providing users with an intuitive visual cue for the distance.
4. [Buzzer Module](/electronics/add-on-modules/buzzer-module)\
   The [buzzer module](/electronics/add-on-modules/buzzer-module) emits sound at varying frequencies based on the object's distance from the sensor. Lower frequencies indicate a larger distance, while higher frequencies signal closer proximity, adding an auditory layer to the feedback.

**Project Key Features:**

1. Distance-Based [RGB](/electronics/add-on-modules/rgb-led-module) and [Buzzer](/electronics/add-on-modules/buzzer-module) Feedback \
   The system defines three key distance ranges: far, medium, and near. These ranges are associated with different [RGB](/electronics/add-on-modules/rgb-led-module) colors and [buzzer ](/electronics/add-on-modules/buzzer-module)frequencies.
   1. Far Distance: When an object is far (above a certain threshold), the system shows a green LED and the buzzer is silent.&#x20;
   2. Medium Distance: As the object gets closer, the LED changes to yellow, and the buzzer emits a low-frequency sound.&#x20;
   3. Near Distance: For very close objects, the LED turns red, and the buzzer produces a higher-pitched sound.
2. Real-Time Distance Monitoring \
   The [distance sensor](/electronics/add-on-modules/ultrasonic-distance-sensor-module) continuously measures the object’s proximity, sending this data to the [SMD](/electronics/smd-red). The system processes this information and updates the [RGB ](/electronics/add-on-modules/rgb-led-module)lights and [buzzer ](/electronics/add-on-modules/buzzer-module)in real time, ensuring immediate feedback for the user.
3. Customizable Distance Thresholds \
   Users can customize the distance thresholds through a user-friendly GUI. The GUI allows them to input values for the far and medium distance thresholds, which directly affect when the [LED](/electronics/add-on-modules/rgb-led-module) and [buzzer](/electronics/add-on-modules/buzzer-module) change states. These settings can be saved and loaded for future use.
4. User-Friendly Graphical Interface (GUI) \
   The GUI is created using Tkinter, providing real-time updates on [distance](/electronics/add-on-modules/ultrasonic-distance-sensor-module), [RGB ](/electronics/add-on-modules/rgb-led-module)color, and [buzzer ](/electronics/add-on-modules/buzzer-module)frequency. It also offers fields where users can enter new distance thresholds, ensuring that the system is flexible and adaptable to different environments or applications.
5. Threaded Operation for Continuous Monitoring \
   The system runs the distance monitoring process in a separate thread, allowing the GUI to remain responsive while the sensor continuously collects data. This ensures smooth operation even as the user interacts with the interface.

## **Step 2: Assemble** <a href="#step-2-assemble" id="step-2-assemble"></a>

**Getting Started**

1. **Hardware Setup**
   * Connect the SMD to the PC or Arduino board using [USB Gateway Module](https://docs.acrome.net/electronics/gateway-modules/usb-gateway-module) or [Arduino Gateway Module](https://docs.acrome.net/electronics/gateway-modules/arduino-gateway-module).
   * Connect [RGB LED Module](https://docs.acrome.net/electronics/add-on-modules/rgb-led-module), [Ultrasonic Distance Sensor](/electronics/add-on-modules/ultrasonic-distance-sensor-module) and [Buzzer Module](/electronics/add-on-modules/buzzer-module) 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/2MTTu5gMPpOfIqMUdgUc" alt=""><figcaption></figcaption></figure>

## Step 3: Run & Test

* Distance Monitoring: The system continuously monitors the distance of an object using the [distance sensor,](/electronics/add-on-modules/ultrasonic-distance-sensor-module) and the data is processed in real time.&#x20;
* Feedback Response: Based on the object's distance, the [RGB LED](/electronics/add-on-modules/rgb-led-module) and [buzzer](/electronics/add-on-modules/buzzer-module) are activated with corresponding colors and frequencies.&#x20;
* GUI Interaction: The user can view the real-time data in the GUI and adjust the distance thresholds for the far and medium ranges.&#x20;
* Threshold Customization: Users can input new values for the distance thresholds, apply them, and save these settings for future use.

## Codes

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

```python
import keyboard
from smd.red import *
import time
import tkinter as tk
from threading import Thread
import json
import os
from serial.tools.list_ports import comports
from platform import system
import logging


# Serial Communication Settings
baudrate = 115200            # Baud rate of communication
module_id = 0                # ID of the SMD module
distance_sensor_id = 1       # ID of the distance sensor module
rgb_led_id = 5               # ID of the RGB LED module
buzzer_module_id = 5         # ID of the buzzer module


# Constants for Distance and Colors
FAR_DISTANCE = 50           # Threshold for far distance
MEDIUM_DISTANCE = 20        # Threshold for medium distance
GREEN = (0, 255, 0)         # RGB color for far distance
YELLOW = (255, 255, 0)      # RGB color for medium distance
RED = (255, 0, 0)           # RGB color for near distance


# Logging Configuration
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)


def 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 = USB_Port()
if not SerialPort:
    raise Exception("No compatible USB port found. Please check your connection.")

master = Master(SerialPort, baudrate)
master.attach(Red(module_id))
print("Connected Modules:", master.scan_modules(module_id))


# Functions for Distance Settings
def load_settings():
    """
    Loads distance settings from 'settings.json'. If the file doesn't exist, default values are used.
    """
    global FAR_DISTANCE, MEDIUM_DISTANCE
    if os.path.exists("settings.json"):
        with open("settings.json", "r") as f:
            settings = json.load(f)
            FAR_DISTANCE = settings.get("FAR_DISTANCE", FAR_DISTANCE)
            MEDIUM_DISTANCE = settings.get("MEDIUM_DISTANCE", MEDIUM_DISTANCE)
    else:
        logger.info("Settings file not found. Using default values.")


def save_settings():
    """
    Saves the current distance settings to 'settings.json'.
    """
    settings = {
        "FAR_DISTANCE": FAR_DISTANCE,
        "MEDIUM_DISTANCE": MEDIUM_DISTANCE
    }
    with open("settings.json", "w") as f:
        json.dump(settings, f, indent=4)
    logger.info("Settings saved to settings.json")


# Load distance settings at startup
load_settings()


# GUI Setup
window = tk.Tk()
window.title("Distance Sensor Feedback")
window.geometry("400x300")


# GUI Labels
distance_label = tk.Label(window, text="Distance: ", font=("Helvetica", 14))
distance_label.pack(pady=10)

rgb_label = tk.Label(window, text="RGB Color: ", font=("Helvetica", 14))
rgb_label.pack(pady=10)

buzzer_label = tk.Label(window, text="Buzzer Frequency: ", font=("Helvetica", 14))
buzzer_label.pack(pady=10)


def update_gui(distance, rgb, buzzer_freq):
    """
    Updates the GUI labels and background color based on the sensor readings.

    Args:
        distance (float): The current distance measured by the sensor, in cm.
        rgb (tuple): RGB color tuple (R, G, B).
        buzzer_freq (int): Buzzer frequency in Hz.
    """
    distance_label.config(text=f"Distance: {distance:.2f} cm")
    rgb_label.config(text=f"RGB Color: R={rgb[0]}, G={rgb[1]}, B={rgb[2]}")
    buzzer_label.config(text=f"Buzzer Frequency: {buzzer_freq} Hz")
    window.configure(bg=f'#{rgb[0]:02x}{rgb[1]:02x}{rgb[2]:02x}')


# Distance Monitoring and Control
def monitor_distance():
    """
    Continuously monitors the distance sensor and updates RGB color and buzzer based on distance thresholds.
    """
    global FAR_DISTANCE, MEDIUM_DISTANCE
    try:
        while True:
            distance = master.get_distance(module_id, distance_sensor_id)
            logger.info(f"Distance: {distance} cm")

            if distance > FAR_DISTANCE:
                rgb, buzzer_freq = GREEN, 0
            elif MEDIUM_DISTANCE < distance <= FAR_DISTANCE:
                rgb, buzzer_freq = YELLOW, 500
            else:
                rgb, buzzer_freq = RED, 1000

            master.set_rgb(module_id, 1, *rgb)
            master.set_buzzer(module_id, 1, buzzer_freq)
            update_gui(distance, rgb, buzzer_freq)

            if keyboard.is_pressed('q'):
                logger.info("Exiting...")
                master.set_rgb(module_id, 1, 0, 0, 0)
                master.set_buzzer(module_id, 1, 0)
                window.destroy()
                break

            time.sleep(0.1)
    except Exception as e:
        logger.error(f"Error in monitor_distance: {e}")


# Start Distance Monitoring in a Thread
monitor_thread = Thread(target=monitor_distance, daemon=True)
monitor_thread.start()

# Run the GUI Main Loop
window.mainloop()
```

{% endcode %}
{% endtab %}

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

```cpp
#include <Acrome-SMD.h>  // Include the ACROME SMD library

#define ID         0           // ID for the SMD
#define BAUDRATE   115200      // Baud rate for serial communication

Red master(ID, Serial, BAUDRATE);    // Define the main module

int distance_module_id = 1;          // ID of the distance sensor module
int rgb_module_id = 5;               // ID of the RGB LED module
int buzzer_module_id = 5;            // ID of the buzzer module

// Distance thresholds
int FAR_DISTANCE = 50;               // Far distance threshold
int MEDIUM_DISTANCE = 20;            // Medium distance threshold

void setup() {
    Serial.begin(115200);            // Initialize serial communication
    master.begin();                  // Start the ACROME-SMD main module
    master.scanModules();            // Scan and detect connected modules
}

void loop() {
    int distance = master.getDistance(distance_module_id);  // Get the distance value

    // Control RGB LED and buzzer based on the detected distance
    if (distance > FAR_DISTANCE) {
        // If the object is far, turn on green LED and keep the buzzer off
        master.setRGB(rgb_module_id, 0, 255, 0);           // Set LED to green
        master.setBuzzer(buzzer_module_id, 0);             // Turn off the buzzer
    } 
    else if (distance > MEDIUM_DISTANCE) {
        // If the object is at a medium distance, turn on yellow LED and set a low-frequency buzzer sound
        master.setRGB(rgb_module_id, 255, 255, 0);         // Set LED to yellow
        master.setBuzzer(buzzer_module_id, 500);           // Set buzzer frequency to 500 Hz (low frequency)
    } 
    else {
        // If the object is near, turn on red LED and set a high-frequency buzzer sound
        master.setRGB(rgb_module_id, 255, 0, 0);           // Set LED to red
        master.setBuzzer(buzzer_module_id, 1000);          // Set buzzer frequency to 1000 Hz (high frequency)
    }

    delay(500);  // Wait for 0.5 seconds before the next loop iteration
}
```

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

**Conclusion:** \
This project showcases the versatility of the [ACROME SMD](/electronics/smd-red) platform in integrating a [distance sensor](/electronics/add-on-modules/ultrasonic-distance-sensor-module) with [RGB lights](/electronics/add-on-modules/rgb-led-module) and a [buzzer](/electronics/add-on-modules/buzzer-module) to provide real-time feedback. The combination of distance-based RGB feedback, customizable thresholds, and a user-friendly GUI makes the system both practical and adaptable. Whether used for safety, automation, or interactive installations, this project highlights the potential of the [SMD](/electronics/smd-red) platform in creating dynamic, sensor-driven environments.


# Distance Auto Stop

This project showcases a dynamic motor control system utilizing the [ACROME SMD](/electronics/smd-red) 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) ([Purchase Here](https://www.robotshop.com/products/acrome-arduino-gateway-shield-module-acrome-smd-products))

[BDC Motor](/electronics/electrical-motors/brushed-dc-motors-bdc) ([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) ([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)\
   The [ACROME SMD](/electronics/smd-red) 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)\
   A distance sensor is used to measure the object's position in real-time.
3. [BDC Motor](/electronics/electrical-motors/brushed-dc-motors-bdc)\
   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)to the PC or Arduino board using [USB Gateway Module](/electronics/gateway-modules/usb-gateway-module) or [Arduino Gateway Module](/electronics/gateway-modules/arduino-gateway-module).
   * Connect the [Ultrasonic Distance Sensor ](/electronics/add-on-modules/ultrasonic-distance-sensor-module)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).

## 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) 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.


# Smart Light Control

This project focuses on creating an interactive lighting system using the [ACROME SMD](/electronics/smd-red) platform, incorporating an [Ambient Light Sensor](/electronics/add-on-modules/ambient-light-sensor-module), an [RGB LED Module](/electronics/add-on-modules/rgb-led-module), and a [Button Module](/electronics/add-on-modules/button-module). The system allows for automatic lighting control based on ambient light conditions and provides user interactivity to change the LED color. Additionally, the [Button Module](/electronics/add-on-modules/button-module) allows the user to cycle through colors, and when held down, it will quickly transition between colors. The LED will retain the last selected color after the button is released.

**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) ([Purchase Here](https://www.robotshop.com/products/acrome-arduino-gateway-shield-module-acrome-smd-products))

[RGB LED Module](https://docs.acrome.net/electronics/add-on-modules/rgb-led-module) ([Purchase Here](https://www.robotshop.com/products/acrome-rgb-led-add-on-module-acrome-smd-products))

[Button Module](/electronics/add-on-modules/button-module) ([Purchase Here](https://www.robotshop.com/products/acrome-button-add-on-module-acrome-smd-products?pr_prod_strat=e5_desc\&pr_rec_id=e23ece12f\&pr_rec_pid=8120246796449\&pr_ref_pid=8121226592417\&pr_seq=uniform))

[Ambient Light Sensor Module](https://docs.acrome.net/electronics/add-on-modules/ambient-light-sensor-module) ([Purchase Here](https://www.robotshop.com/products/acrome-ambient-light-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>

**Key Components:**

1. [SMD](/electronics/smd-red)\
   The [SMD](/electronics/smd-red) serves as the central communication hub between the different modules. It manages the interaction between the [Ambient Light Sensor](/electronics/add-on-modules/ambient-light-sensor-module), [RGB LED Module](/electronics/add-on-modules/rgb-led-module), and [Button Module](/electronics/add-on-modules/button-module), executing the logic as defined in the script.
2. [RGB LED Module ](/electronics/add-on-modules/rgb-led-module)\
   The [RGB LED Module](/electronics/add-on-modules/rgb-led-module) emits light in different colors by mixing red, green, and blue channels. This allows users to create a variety of lighting effects, controlled via the [Button Module](/electronics/add-on-modules/button-module).
3. [Button Module ](/electronics/add-on-modules/button-module)\
   The [Button Module ](/electronics/add-on-modules/button-module)serves as a physical interface for user input. Users can press the button to cycle through different colors for the [RGB LED Module](/electronics/add-on-modules/rgb-led-module), and if the button is held down, the system will rapidly cycle through colors, allowing for faster color selection.
4. [Ambient Light Sensor Module ](/electronics/add-on-modules/ambient-light-sensor-module)\
   The [Ambient Light Sensor](/electronics/add-on-modules/ambient-light-sensor-module) detects the intensity of the surrounding light and allows the system to decide when to automatically turn on or off the [RGB LED Module](/electronics/add-on-modules/rgb-led-module), depending on the environment’s lighting conditions.

**Project Key Features:**

1. Automatic Light Sensing \
   The [Ambient Light Sensor Module ](/electronics/add-on-modules/ambient-light-sensor-module)continuously monitors the environmental light levels. When the light intensity falls below a predefined threshold, the system automatically activates the [RGB LED Module](/electronics/add-on-modules/rgb-led-module). This ensures that the light is only turned on when needed, enhancing energy efficiency and creating an adaptive lighting environment.
2. Manual Color Control \
   The user can interact with the [Button Module](/electronics/add-on-modules/button-module) to manually change the color of the [RGB LED Module](/electronics/add-on-modules/rgb-led-module). Each button press cycles through a preset list of colors (e.g., red, green, blue, yellow, magenta, cyan). Additionally, holding the button down accelerates the color transitions, allowing users to quickly move between colors.
3. Energy-Efficient Operation \
   The [Ambient Light Sensor Module](/electronics/add-on-modules/ambient-light-sensor-module) makes the system more energy-efficient by turning the light off when ambient light levels are sufficient. This feature ensures that the [RGB LED Module](/electronics/add-on-modules/rgb-led-module) operates only in low-light conditions, minimizing unnecessary energy usage.
4. Seamless Module Communication \
   The [SMD](/electronics/smd-red) ensures seamless communication between all components. It reads the ambient light data from the [Ambient Light Sensor](/electronics/add-on-modules/ambient-light-sensor-module), controls the color output of the [RGB LED](/electronics/add-on-modules/rgb-led-module), and processes user input from the [Button Module](/electronics/add-on-modules/button-module). This integration allows the project to react dynamically to both environmental changes and user commands.

## **Step 2: Assemble**

**Getting Started**

1. **Hardware Setup**
   * Connect the SMD to the PC or Arduino board using [USB Gateway Module](https://docs.acrome.net/electronics/gateway-modules/usb-gateway-module) or [Arduino Gateway Module](https://docs.acrome.net/electronics/gateway-modules/arduino-gateway-module).
   * Connect the [Ambient Light Sensor Module](https://docs.acrome.net/electronics/add-on-modules/ambient-light-sensor-module) and the [RGB LED Module](https://docs.acrome.net/electronics/add-on-modules/rgb-led-module) 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/grFZD8x6asti9phIOB8g" alt=""><figcaption></figcaption></figure>

## Step 3: Run & Test

* Light Monitoring: The system constantly reads ambient light data using the [Ambient Light Sensor](/electronics/add-on-modules/ambient-light-sensor-module).
* Automatic Light Control: If the environment is too dark, the [RGB LED Module](/electronics/add-on-modules/rgb-led-module) is automatically turned on, and if the environment is bright, the [RGB LED Module](/electronics/add-on-modules/rgb-led-module) turns off.
* User Interaction: The [Button Module](/electronics/add-on-modules/button-module) allows the user to cycle through colors manually. A single press changes the color, and holding the button down rapidly switches between the colors.
* Color Retention: When the button is released, the LED remains on the last selected color until further interaction.

## **Codes**

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

```python
from smd.red import *
import time
import tkinter as tk
from tkinter import messagebox
from threading import Thread
import json
import os
from serial.tools.list_ports import comports
from platform import system


# Serial Communication Settings
baudrate = 115200          # Baud rate of communication
ID = 0                     # ID of the SMD module
button_module_id = 5       # ID of the button module
light_sensor_id = 5        # ID of the light sensor module
rgb_led_id = 5             # ID of the RGB LED module


def 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",
        ]
    }

    # Detect the operating system
    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 = USB_Port()
if not SerialPort:
    raise Exception("No compatible USB port found. Please check your connection.")

master = Master(SerialPort, baudrate)
master.attach(Red(ID))
print("Connected Modules:", master.scan_modules(ID))


# Color Management Functions
def load_colors_from_json():
    """
    Load colors from a JSON file. If the file doesn't exist, return an empty list.

    Returns:
        list: A list of RGB color tuples, or an empty list if the file is not found.
    """
    if os.path.exists("rgbsetting.json"):
        with open("rgbsetting.json", "r") as f:
            data = json.load(f)
            return data.get("colors", [])
    return []


def save_color_to_json():
    """
    Save the current list of colors to a JSON file.
    """
    data = {"colors": colors}
    with open("rgbsetting.json", "w") as f:
        json.dump(data, f, indent=4)
    print("Colors saved to rgbsetting.json")


# Default Colors
default_colors = [(255, 0, 0), (0, 255, 0), (0, 0, 255), (255, 255, 0), (255, 0, 255), (0, 255, 255)]
colors = load_colors_from_json() or default_colors
color_index = 0  # Tracks the current color index


# GUI Setup
window = tk.Tk()
window.title("LED Color Controller")
window.geometry("400x300")


# GUI Widgets
light_label = tk.Label(window, text="Light Status: ", font=("Helvetica", 14))
light_label.pack(pady=10)

button_label = tk.Label(window, text="Button State: ", font=("Helvetica", 14))
button_label.pack(pady=10)

color_label = tk.Label(window, text="Current Color: ", font=("Helvetica", 14))
color_label.pack(pady=10)

r_label = tk.Label(window, text="R:", font=("Helvetica", 12))
r_label.pack(side=tk.LEFT, padx=(10, 0))
r_entry = tk.Entry(window, width=5)
r_entry.pack(side=tk.LEFT)

g_label = tk.Label(window, text="G:", font=("Helvetica", 12))
g_label.pack(side=tk.LEFT, padx=(10, 0))
g_entry = tk.Entry(window, width=5)
g_entry.pack(side=tk.LEFT)

b_label = tk.Label(window, text="B:", font=("Helvetica", 12))
b_label.pack(side=tk.LEFT, padx=(10, 0))
b_entry = tk.Entry(window, width=5)
b_entry.pack(side=tk.LEFT)

save_var = tk.BooleanVar()
save_checkbox = tk.Checkbutton(window, text="Save color to file", variable=save_var)
save_checkbox.pack(pady=5)

add_button = tk.Button(window, text="Add Color", command=lambda: add_color())
add_button.pack(pady=10)


# Helper Functions
def validate_rgb_value(value):
    """
    Validates whether the given value is an integer between 0 and 255.

    Args:
        value (str): RGB value as string.
    Returns:
        bool: True if valid, False otherwise.
    """
    try:
        value = int(value)
        return 0 <= value <= 255
    except ValueError:
        return False


def add_color():
    """
    Adds a new color to the colors list and saves it to a JSON file if required.
    """
    r, g, b = r_entry.get(), g_entry.get(), b_entry.get()
    if validate_rgb_value(r) and validate_rgb_value(g) and validate_rgb_value(b):
        r, g, b = int(r), int(g), int(b)
        colors.append((r, g, b))
        print(f"New color added: R={r}, G={g}, B={b}")
        if save_var.get():
            save_color_to_json()
    else:
        messagebox.showerror("Invalid Input", "RGB values must be integers between 0 and 255.")


def update_gui(light_status, button_status, current_color):
    """
    Updates the GUI labels and background color based on the current state.

    Args:
        light_status (str): Current status of the light (On/Off).
        button_status (str): Current state of the button (Pressed/Released).
        current_color (tuple): RGB values of the current LED color.
    """
    light_label.config(text=f"Light Status: {light_status}")
    button_label.config(text=f"Button State: {button_status}")
    color_label.config(text=f"Current Color: R={current_color[0]}, G={current_color[1]}, B={current_color[2]}")
    window.configure(bg=f'#{current_color[0]:02x}{current_color[1]:02x}{current_color[2]:02x}')


# Main Control Loop
def control_loop():
    """
    Main control loop for managing the RGB LED light and updating GUI elements.
    """
    global color_index
    button_held = False

    while True:
        light = master.get_light(ID, light_sensor_id)
        button_pressed = master.get_button(ID, button_module_id)

        # Determine light status based on sensor reading
        if light is not None and light < 100:
            light_status = "On"
        else:
            light_status = "Off"

        # Handle button press to change colors
        if button_pressed == 1 and not button_held:
            button_held = True
            color_index = (color_index + 1) % len(colors)
            r, g, b = colors[color_index]
            master.set_rgb(ID, rgb_led_id, r, g, b)
        elif button_pressed == 0:
            button_held = False

        # Update GUI with the current state
        r, g, b = colors[color_index] if light_status == "On" else (0, 0, 0)
        update_gui(light_status, "Pressed" if button_pressed else "Released", (r, g, b))
        time.sleep(0.1)


# Start control loop in a separate thread
control_thread = Thread(target=control_loop)
control_thread.daemon = True
control_thread.start()

# Run the GUI main loop
window.mainloop()
```

{% endcode %}
{% endtab %}

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

```cpp
#include <Acrome-SMD.h>

#define ID        0           // ID of the SMD module
#define BAUDRATE  115200      // Baud rate for communication

Red master(ID, Serial, BAUDRATE);    // Defines the Arduino gateway module

const int rgb_module_id = 5;         // ID of the RGB LED module
const int button_module_id = 5;      // ID of the button module (assuming it's the same as the RGB module)
const int light_sensor_module_id = 5; // ID of the light sensor module (assuming it's the same as the RGB module)

// RGB color array
const int COLOR_COUNT = 6;
int colors[][3] = {
  {255, 0, 0},    // Red
  {0, 255, 0},    // Green
  {0, 0, 255},    // Blue
  {255, 255, 0},  // Yellow
  {255, 0, 255},  // Magenta
  {0, 255, 255}   // Cyan
};

int colorIndex = 0;
bool currentButtonState = false;

void setup() {
    master.begin();                 // Initialize communication
    master.scanModules();           // Scan for connected modules
    Serial.begin(BAUDRATE);
}

void loop() {
    // Read ambient light level
    int lightLevel = master.getLight(light_sensor_module_id);
    Serial.println(lightLevel);
    
    // Determine whether the light should be on or off
    bool shouldLightBeOn = (lightLevel > 100);

    // Read button state
    bool currentButtonState = master.getButton(button_module_id);

    // Change color when the button is pressed
    if (currentButtonState) {
        colorIndex = (colorIndex + 1) % COLOR_COUNT;
    }

    // Update RGB LED based on light level
    if (shouldLightBeOn) {
        master.setRGB(rgb_module_id, colors[colorIndex][0], colors[colorIndex][1], colors[colorIndex][2]);
    } else {
        master.setRGB(rgb_module_id, 0, 0, 0);  // Turn off the LED
    }

    delay(100);  // Short delay to control the loop speed
}
```

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

**Conclusion:**

This project exemplifies how the [ACROME SMD](/electronics/smd-red) platform can integrate with various modules to create a smart lighting solution that is both interactive and energy-efficient. By using the [Ambient Light Sensor](/electronics/add-on-modules/ambient-light-sensor-module), [RGB LED](/electronics/add-on-modules/rgb-led-module), and [Button Module](/electronics/add-on-modules/button-module), the system combines automatic control with manual user inputs, providing a flexible and customizable lighting experience.


# Interactive

Motion Control & User Interaction

The Interactive section is aimed at users with an intermediate understanding of electronics, focusing on projects that integrate joysticks, motors, and other input/output devices to create interactive systems. This category is perfect for those who want to explore real-time control systems, user feedback mechanisms, and advanced motion-based applications.

These projects provide hands-on experience in joystick-based navigation, motorized control, and multi-module integration. Users will develop skills applicable to game controllers, robotic motion systems, and interactive feedback mechanisms. Each project serves as a stepping stone towards mastering real-time control and automation.


# Automatic Trash Bin

The Automatic Trash Bin project demonstrates how robotics can simplify everyday tasks, integrating innovative technology into real-life applications. This system utilizes a 100 RPM BDC Motor with Encoder alongside an [**Ultrasonic Distance Sensor Module**](/electronics/add-on-modules/ultrasonic-distance-sensor-module) to automate the opening and closing of a trash bin lid. By detecting the presence of a hand or a nearby object, the ultrasonic sensor sends a signal to the motor, which precisely controls the lid’s movement.

**About Tools and Materials:**

[SMD Red](/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](/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) ([Purchase Here](https://www.robotshop.com/products/acrome-arduino-gateway-shield-module-acrome-smd-products))

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

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

## **Step 1: Hardware & Software Overview**

**Project Key Components**

* [**SMD**](https://acrome.gitbook.io/acrome-smd-docs/electronics/smd-red)

  The 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 [Ultrasonic Distance Sensor Module](/electronics/add-on-modules/ultrasonic-distance-sensor-module) and actuate the DC motor precisely.
* [BDC Motor](/electronics/electrical-motors/brushed-dc-motors-bdc)&#x20;

  The 100 RPM BDC Motor with Encoder is the actuator of the system. It moves the trash bin lid up.
* [**Ultrasonic Distance Sensor Module**](/electronics/add-on-modules/ultrasonic-distance-sensor-module)

  The [Ultrasonic Distance Sensor Module](/electronics/add-on-modules/ultrasonic-distance-sensor-module) is used to detect the approaching person or the hand.
* [**SMD Libraries**](/software/libraries)

  The SMD library is at the heart of the application. It communicates with the SMD using a specific communication protocol, sending commands to read the [Ultrasonic Distance Sensor Module](/electronics/add-on-modules/ultrasonic-distance-sensor-module) and actuate the BDC motor.

**Project Key Features**

* **Hands-free Operation**

  The [Ultrasonic Distance Sensor Module](/electronics/add-on-modules/ultrasonic-distance-sensor-module) makes it easy in terms of hygiene and automation, automatic trash bin lid project makes life easier.&#x20;
* **Adjustable Sensitivity**

  The script include parameters that can be edited by the user to change the sensivity of the system, it helps to avoid unwanted activations of the BDC motor.

## **Step 2: Assemble**

1. **Hardware Setup**
   * Connect the SMD to the PC or Arduino board using [USB Gateway Module](https://acrome.gitbook.io/acrome-smd-docs/electronics/gateway-modules/usb-gateway-module) or [Arduino Gateway Module](https://acrome.gitbook.io/acrome-smd-docs/electronics/gateway-modules/arduino-gateway-module).
   * Connect the 100 RPM BDC Motor with Encoder to the motor ports of the SMD and the [Ultrasonic Distance Sensor Module](/electronics/add-on-modules/ultrasonic-distance-sensor-module) 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/PdPxLGjDAtitJ7BvdYD2" alt=""><figcaption></figcaption></figure>

## **Step 3: Run & Test**

1. **Run the Script**
   * Execute the script, initiating the Automatic Trash Bin application.
   * Approach the trash bin, and observe how the lid opens automatically when the user is in close proximity.
2. **Enhance and Customize**
   * Fine-tune the sensitivity parameters in the script based on the user feedback and the specific requirements of the environment.
   * Explore additional features, such as automatic lid closing after a specified period or incorporating status indicators.

## Codes

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

```python
from serial.tools.list_ports import comports
from platform import system
import time
from smd.red import *

baudrate = 115200           # Baud rate of communication
ID = 0                      # ID of the SMD
distance_id = 1             # ID of the ultrasonic distance sensor module


def 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.
    """
    # Get a list of available ports
    ports = list(comports())
    
    # Known USB port names for different operating systems
    usb_names = {
        "Windows": ["USB Serial Port"],  # Names specific to Windows
        "Linux": ["/dev/ttyUSB"],        # Names specific to Linux
        "Darwin": [                      # Names specific to macOS
            "/dev/tty.usbserial",
            "/dev/tty.usbmodem",
            "/dev/tty.SLAB_USBtoUART",
            "/dev/tty.wchusbserial",
            "/dev/cu.usbserial",
        ]
    }

    # Detect the operating system
    os_name = system()
    print(f"Operating System: {os_name}")

    if ports:
        for port in ports:
            # Check if the port matches any known USB names
            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
        # If no suitable port is found, print the list of available ports
        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


try:
    # Find a valid serial port
    SerialPort = USB_Port()
    if not SerialPort:
        raise Exception("No compatible USB port found. Please check your connection.")

    print(f"Using serial port: {SerialPort}")

    # Initialize the SMD module
    master = Master(SerialPort, baudrate)       # Defines the USB gateway module
    master.attach(Red(ID))                      # Gives access to the SMD of specified ID

    # Motor and control configuration
    master.set_shaft_rpm(ID, 100)                               # Sets the RPM value of the motor
    master.set_shaft_cpr(ID, 6533)                              # Sets the CPR value of the motor
    master.set_operation_mode(ID, 1)                            # Sets the operation mode to 'Position Control'
    master.set_control_parameters_position(ID, 10, 0, 50)       # Sets the PID parameters, can be auto-tuned instead
    master.enable_torque(ID, 1)                                 # Enables the motor to spin if any command says so

    # Main loop
    while True:
        # Get distance data from the ultrasonic sensor
        distance = master.get_distance(ID, distance_id)         # Variable to store the distance data
        print(f"Distance: {distance} cm")                       # Printing the value to observe

        if distance < 10:                                       # If it sees a person nearby 10 cm
            master.set_position(ID, 1000)                       # Motor lifts the trash bin lid
            time.sleep(2)                                       # Delay before putting the lid down
        else:
            master.set_position(ID, 0)                          # Motor puts the lid down

except Exception as e:
    print(f"Error: {e}")
```

{% endcode %}
{% endtab %}

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

```cpp
#include <Acrome-SMD.h>

#define ID        0                 // ID of the SMD
#define BAUDRATE  115200            // Baud rate of the communication

Red master(ID, Serial, BAUDRATE);   // Defines the Arduino gateway module

int distance_id = 1;                // ID of the ultrasonic distance sensor module

int distance = 0;                   // Variable to store the distance data

void setup() {
    master.begin();                 // Starts the communication
    master.scanModules();           // Scans for the connected modules

    master.setMotorRPM(100);        // Sets the RPM value of the motor
    master.setMotorCPR(6533);       // Sets the CPR value of the motor

    master.setOperationMode(PositionControl);                           // Sets the operation mode to 'Position Control'
    master.setControlParameters(PositionControl, 10, 0, 50, 0, 0);       // Sets the PID parameters, can be auto-tuned instead
    master.torqueEnable(1);                                             // Enables the motor to spin if any command say so
}

void loop() {
    distance = master.getLight(distance_id);        // Getting the distance data and storing it
    
    if (distance < 10) {                            // If it sees a person nearby 10 cm
        master.setpoint(PositionControl, 1000);     // Motor lifts the trash bin lid, change position value if it doesn't lift
        delay(2000);
    }

    else {
        master.setpoint(PositionControl, 0);        // Motor puts the lid down
    }
}

```

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


# Radar

The Radar project is a comprehensive project that combines software, hardware and mechanics of the SMD family. There are specially designed 3D parts for the mount system of the Ultrasonic Distance Sensor Module. The mount system and 100 RPM BDC Motor with Encoder work together to turn around the Ultrasonic Distance Sensor Module to have a radar-like working principle.

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

**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) ([Purchase Here](https://www.robotshop.com/products/acrome-arduino-gateway-shield-module-acrome-smd-products))

[BDC Motor](/electronics/electrical-motors/brushed-dc-motors-bdc)  ([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) ([Purchase Here](https://www.robotshop.com/products/acrome-ultrasonic-distance-sensor-add-on-module-acrome-smd-products))

3D Printed Parts

## **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. [**SMD**](/electronics/smd-red)

   The 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 [Ultrasonic Distance Sensor Module](https://acrome.gitbook.io/acrome-smd-docs/electronics/add-on-modules/ultrasonic-distance-sensor-module) and meanwhile, actuate the motor for the continuous reading of the script.
2. [BDC Motor](/electronics/electrical-motors/brushed-dc-motors-bdc)

   The 100 RPM BDC Motor with Encoder is used to rotate the radar mechanism in a full circle. The user can precisely control the motor and get the position through the built-in encoder.
3. [**Ultrasonic Distance Sensor Module**](/electronics/add-on-modules/ultrasonic-distance-sensor-module)

   The Ultrasonic Distance Sensor Module measures the surroundings every cycle through its spin.&#x20;
4. **3D Printed Parts**

   Custom 3D printed parts allow the user to mount the Ultrasonic Distance Sensor Module on top of the BDC motor.
5. [**SMD Libraries**](/software/libraries)

   The SMD library is at the heart of the application. It communicates with the SMD using a specific communication protocol, sending commands to read the [Ultrasonic Distance Sensor Module](https://acrome.gitbook.io/acrome-smd-docs/electronics/add-on-modules/ultrasonic-distance-sensor-module) and actuate the BDC motor to spin the module around.

**Project Key Features**

* **Rotating Radar Scan**

  The rotation of the Ultrasonic Distance Sensor Module make the system seem like a geniune radar.
* **Real-time Distance Visualization**

  The script receives distance data continuously, allowing the user to visualize the data around a circle plot, just like a radar.

## **Step 2: Assemble**

**Getting Started**

1. **Hardware Setup**
   * Connect the SMD to the PC or Arduino board using [USB Gateway Module](https://acrome.gitbook.io/acrome-smd-docs/electronics/gateway-modules/usb-gateway-module) or [Arduino Gateway Module](https://acrome.gitbook.io/acrome-smd-docs/electronics/gateway-modules/arduino-gateway-module).
   * Mount the custom 3D printed mount parts on the BDC motor.
   * Connect the 100 RPM BDC Motor with Encoder to the motor ports of the SMD and the [Ultrasonic Distance Sensor Module](https://acrome.gitbook.io/acrome-smd-docs/electronics/add-on-modules/ultrasonic-distance-sensor-module) to the SMD using an RJ-45 cable.
   * Mount the [Ultrasonic Distance Sensor Module](https://acrome.gitbook.io/acrome-smd-docs/electronics/add-on-modules/ultrasonic-distance-sensor-module) on top of the motor mount parts
   * Make sure that the SMD is powered and all connections are correct.

#### Project Wiring Diagram

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

## Step 3: Run & Test

1. **Run the Application**
   * Execute the Python script, initiating the Radar application.
   * Observe the rotation of the [Ultrasonic Distance Sensor Module](https://acrome.gitbook.io/acrome-smd-docs/electronics/add-on-modules/ultrasonic-distance-sensor-module) in a full circle.
   * See the continuous data from the terminal.
2. **Experiment and Customize**
   * Experiment with different scanning speeds, put different objects near the radar.
   * Implement a plotting library and plot the data on a circle plot.

## Codes

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

```python
from serial.tools.list_ports import comports
from platform import system
from smd.red import *

baudrate = 115200          # Baud rate of communication
ID = 0                     # ID of the SMD
motor_module_id = 0        # ID of the motor module
distance_sensor_id = 1     # ID of the ultrasonic distance sensor module


def 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.
    """
    # Get a list of available ports
    ports = list(comports())
    
    # Known USB port names for different operating systems
    usb_names = {
        "Windows": ["USB Serial Port"],  # Names specific to Windows
        "Linux": ["/dev/ttyUSB"],        # Names specific to Linux
        "Darwin": [                      # Names specific to macOS
            "/dev/tty.usbserial",
            "/dev/tty.usbmodem",
            "/dev/tty.SLAB_USBtoUART",
            "/dev/tty.wchusbserial",
            "/dev/cu.usbserial",
        ]
    }

    # Detect the operating system
    os_name = system()
    print(f"Operating System: {os_name}")

    if ports:
        for port in ports:
            # Check if the port matches any known USB names
            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
        # If no suitable port is found, print the list of available ports
        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


try:
    # Find a valid serial port
    SerialPort = USB_Port()
    if not SerialPort:
        raise Exception("No compatible USB port found. Please check your connection.")

    print(f"Using serial port: {SerialPort}")

    # Initialize the SMD module
    master = Master(SerialPort, baudrate)       # Defines the USB gateway module
    master.attach(Red(ID))                      # Gives access to the SMD of specified ID
    master.scan_modules(ID)                     # Scans and identifies the modules connected to the SMD

    # Configure the motor module
    master.set_operation_mode(motor_module_id, 2)  # Set operation mode to 'Velocity Control'
    master.enable_torque(motor_module_id, True)    # Enable motor torque
    master.set_velocity(motor_module_id, 500)      # Set initial velocity
    master.set_shaft_rpm(motor_module_id, 100)     # Set RPM to 100
    master.set_shaft_cpr(motor_module_id, 6533)    # Set CPR (Counts Per Revolution)

    # Main loop
    while True:
        # Get distance data from the ultrasonic sensor
        distance = master.get_distance(ID, distance_sensor_id)  # Variable to store the distance data
        encoder_position = master.get_position(motor_module_id)  # Get motor position

        # Print the distance and position
        print(f"Distance: {distance} cm, Motor Position: {encoder_position}")

        # Control motor direction based on position
        if encoder_position > 9000:
            master.set_velocity(motor_module_id, -500)  # Reverse direction
        elif encoder_position < 0:
            master.set_velocity(motor_module_id, 500)   # Forward direction

        time.sleep(0.1)  # Delay for smooth operation

except Exception as e:
    print(f"Error: {e}")
```

{% endcode %}
{% endtab %}

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

```cpp
#include <Acrome-SMD.h>

#define ID         0
#define BAUDRATE   115200

Red master(ID, Serial, BAUDRATE);

void setup() {
    Serial.begin(BAUDRATE);
    master.begin();
    master.scanModules();

    // Motoru sıfırlayalım
    master.setOperationMode(2);
    master.setpoint(1,0);
    master.torqueEnable(1);
    master.setMotorRPM(100);
    master.setMotorCPR(6533);
    master.setControlParameters(1, 10, 1, 0, 0, 0);
    master.setpoint(2,500);
}

void loop() {
    int distance = master.getDistance(5);
    
    int encoder_counts = master.getPosition();
    
    Serial.print("Pozisyon (derece): ");
    Serial.print(encoder_counts);
    Serial.print(", Mesafe: ");
    Serial.println(distance);

    if (encoder_counts > 9000) {
        master.setpoint(2,-500);
    } else if (encoder_counts < 0) {
        master.setpoint(2,500);
    }
    
    delay(100);
}
```

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

#### Hardware Designs

{% file src="/files/fiLxoBVUAIy7huJxE17U" %}

{% file src="/files/K87BCcDerAq2a3olSVuw" %}


# Chrome Dino Game Player

The Chrome Dino Game Player project is an innovative application that combines hardware and software to spark the joy in robotic projects. There is a 100 RPM BDC Motor with an Encoder is used as an actuator, and an [Ambient Light Sensor Module](/electronics/add-on-modules/ambient-light-sensor-module) is used as the input sensor, to differentiate the dark colored obstacles from the free road

**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) ([Purchase Here](https://www.robotshop.com/products/acrome-arduino-gateway-shield-module-acrome-smd-products))

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

[**Ambient Light Sensor Module**](/electronics/add-on-modules/ambient-light-sensor-module) ([Purchase Here](https://www.robotshop.com/products/acrome-ambient-light-sensor-add-on-module-acrome-smd-products))

## **Step 1: Hardware & Software Overview**

**Project Key Components**

1. [**SMD**](/electronics/smd-red)

   The 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 [Ambient Light Sensor Module](/electronics/add-on-modules/ambient-light-sensor-module) and actuate the DC motor precisely.
2. [BDC Motor](/electronics/electrical-motors/brushed-dc-motors-bdc)

   The 100 RPM BDC Motor with Encoder allows the user to press the spacebar when an obstacle is detected. The built-in encoder is the key to control the position of the motor, thus, the user can use the motor to rapidly and repeteadly press the key and get high scores.
3. [**Ambient Light Sensor Module**](/electronics/add-on-modules/ambient-light-sensor-module)

   The [Ambient Light Sensor Module](/electronics/add-on-modules/ambient-light-sensor-module) is used to detect the emitted light differences of the dark obstacles and white free road. The module can differentiate thousands of levels of ambient light in terms of lux.
4. [**SMD Libraries**](/software/libraries)

   The SMD library is at the heart of the application. It communicates with the SMD using a specific communication protocol, sending commands to read the [Ambient Light Sensor Module](/electronics/add-on-modules/ambient-light-sensor-module) and actuate the BDC motor.

**Project Key Features**

* **Dynamic Obstacle Detection**

  The Ambient Light Sensor Module that is controlled by the SMD can detect surroundings ambient light intensity several times in a second. It allows to the system to be dynamic and responsive.
* **Responsive and Real-time Gameplay**

  The script continuously monitors the ambient light level, it can be printed on the terminal for more precise control editings and monitoring.

## **Step 2: Assemble**

**Getting Started**

1. **Hardware Setup**
   * Connect the SMD to the PC or Arduino board using [USB Gateway Module](https://acrome.gitbook.io/acrome-smd-docs/electronics/gateway-modules/usb-gateway-module) or [Arduino Gateway Module](https://acrome.gitbook.io/acrome-smd-docs/electronics/gateway-modules/arduino-gateway-module).
   * Connect the 100 RPM BDC Motor with Encoder to the motor ports of the SMD and the [Ambient Light Sensor Module](/electronics/add-on-modules/ambient-light-sensor-module) to the SMD using an RJ-45 cable.
   * Make sure that the SMD is powered and all connections are correct.
2. **Software Integration**
   * Implement the cursor of the BDC motor to the spacebar of the keyboard, test the code if the motor can precisely press and release the spacebar. Change the position values in `set_position` function if key is not pressed and released correctly.

**Project Wiring Diagram**

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

## Step 3: Run & Test

1. **Run the Application**
   * Execute the script and launch the Chrome Dino Game.
   * Observe how the DC motor actuates according to the ambient light intensity and make high scores.

## Codes

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

```python
from serial.tools.list_ports import comports
from platform import system
import time
from smd.red import *

baudrate = 115200           # Baud rate of communication
ID = 0                      # ID of the SMD board
ambient_module_id = 5       # ID of the ambient light sensor module


def 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.
    """
    # Get a list of available ports
    ports = list(comports())
    
    # Known USB port names for different operating systems
    usb_names = {
        "Windows": ["USB Serial Port"],  # Names specific to Windows
        "Linux": ["/dev/ttyUSB"],        # Names specific to Linux
        "Darwin": [                      # Names specific to macOS
            "/dev/tty.usbserial",
            "/dev/tty.usbmodem",
            "/dev/tty.SLAB_USBtoUART",
            "/dev/tty.wchusbserial",
            "/dev/cu.usbserial",
        ]
    }

    # Detect the operating system
    os_name = system()
    print(f"Operating System: {os_name}")

    if ports:
        for port in ports:
            # Check if the port matches any known USB names
            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
        # If no suitable port is found, print the list of available ports
        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


try:
    # Find a valid serial port
    SerialPort = USB_Port()
    if not SerialPort:
        raise Exception("No compatible USB port found. Please check your connection.")

    print(f"Using serial port: {SerialPort}")

    # Initialize the SMD module
    master = Master(SerialPort, baudrate)       # Defines the USB gateway module
    master.attach(Red(ID))                      # Gives access to the SMD of specified ID

    # Motor and control configuration
    master.set_shaft_rpm(ID, 100)                               # Sets the RPM value of the motor
    master.set_shaft_cpr(ID, 6533)                              # Sets the CPR value of the motor
    master.set_operation_mode(ID, 1)                            # Sets the operation mode to 'Position Control'
    master.set_control_parameters_position(ID, 10, 0, 50)       # Sets the PID parameters, can be auto-tuned instead
    master.enable_torque(ID, 1)                                 # Enables the motor to spin if any command says so

    # Main loop
    while True:
        # Get ambient light data from the sensor
        light = master.get_light(ID, ambient_module_id)         # Variable to store the ambient light data
        print(f"Ambient light level: {light}")                  # Printing the value to observe

        if light < 30:                                          # If it detects obstacles (black reflects less light)
            master.set_position(ID, 1000)                       # Motor moves to the spacebar key location
            time.sleep(0.2)
            master.set_position(ID, 0)                          # Motor returns to the start position
        else:
            master.set_position(ID, 0)                          # Stays at the start position if there are no obstacles

except Exception as e:
    print(f"Error: {e}")
```

{% endcode %}
{% endtab %}

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

```cpp
#include <Acrome-SMD.h>

#define ID        0           // ID of the SMD board
#define BAUDRATE  115200      // Baud rate of the communication

Red master(ID, Serial, BAUDRATE);   // Defines the Arduino gateway module

int ambient_module_id = 1;          // ID of the ambient light sensor module

int light = 0;                      // Variable to store the ambient light data

void setup() {
    master.begin();                 // Starts the communication
    master.scanModules();           // Scans for the connected modules

    master.setMotorRPM(100);        // Sets the RPM value of the motor
    master.setMotorCPR(6533);       // Sets the CPR value of the motor

    master.setOperationMode(PositionControl);                           // Sets the operation mode to 'Position Control'
    master.setControlParameters(PositionControl, 10, 0, 50, 0, 0);       // Sets the PID parameters, can be auto-tuned instead
    master.torqueEnable(1);                                             // Enables the motor to spin if any command say so
}

void loop() {
    light = master.getLight(ambient_module_id);     // Getting the ambient light value and storing it
    
    if (light < 30) {                               // If it sees obstacles, which are black, so will emit less light than other colors
        master.setpoint(PositionControl, 1000);     // Motor goes to the spacebar key location, change position value if it doesn't reach
        delay(200);
        master.setpoint(PositionControl, 0);        // Motor goes back to the start position
    }

    else {
        master.setpoint(PositionControl, 0);        // Stays at the start position if there are no obstacles
    }
}

```

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


# Play Chrome Dino Game With Joystick

This project allows users to control the Google Chrome Dino game using a [joystick](/electronics/add-on-modules/joystick-module) connected through the [ACROME SMD](/electronics/smd-red) platform. The [joystick ](/electronics/add-on-modules/joystick-module)is mapped to the jump and duck actions in the game. When the [joystick ](/electronics/add-on-modules/joystick-module)is pushed up, the game character jumps (using the spacebar key), and when the [joystick ](/electronics/add-on-modules/joystick-module)is pushed down, the character ducks (using the down arrow key).

**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))

[Joystick Module](/electronics/add-on-modules/joystick-module) ([Purchase Here](https://www.robotshop.com/products/acrome-joystick-2-axis-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>

**Key Components:**

1. [ACROME SMD](/electronics/smd-red) \
   The [ACROME SMD](/electronics/smd-red) platform acts as the communication hub, reading [joystick ](/electronics/add-on-modules/joystick-module)inputs and transmitting them to control the game. It collects data from the [joystick ](/electronics/add-on-modules/joystick-module)and processes it in real-time to translate movements into actions.
2. [Joystick Module ](/electronics/add-on-modules/joystick-module)\
   The [joystick ](/electronics/add-on-modules/joystick-module)is used to control the actions in the Dino game. Vertical movements (up and down) control the character’s ability to jump and duck, with the [joystick ](/electronics/add-on-modules/joystick-module)acting as a physical input interface.
3. GUI (Tkinter)\
   The graphical user interface (GUI) provides real-time feedback to the user, showing the current state of the [joystick ](/electronics/add-on-modules/joystick-module)and the action being performed (jump or duck). This ensures transparency in how the [joystick ](/electronics/add-on-modules/joystick-module)movements are translated into game actions.

**Project Key Features:**

1. Real-Time [Joystick ](/electronics/add-on-modules/joystick-module)Control \
   The [joystick](/electronics/add-on-modules/joystick-module) allows the user to control the Dino character’s movements. Moving the [joystick ](/electronics/add-on-modules/joystick-module)up makes the Dino jump, while moving it down makes the Dino duck.
2. Smooth Action Interpolation \
   To make the [joystick ](/electronics/add-on-modules/joystick-module)movements smoother and more responsive, interpolation is applied to the [joystick ](/electronics/add-on-modules/joystick-module)values. This ensures the actions are triggered only when the [joystick ](/electronics/add-on-modules/joystick-module)movement crosses a certain threshold.
3. Key State Management \
   The system ensures that the keys (spacebar for jumping, down arrow for ducking) are held down or released at the appropriate times based on the [joystick ](/electronics/add-on-modules/joystick-module)input. This prevents unnecessary key presses and makes the actions more accurate.
4. Graphical Feedback \
   The GUI continuously displays the current X and Y values of the [joystick ](/electronics/add-on-modules/joystick-module)and the action being performed, providing visual feedback for the user to monitor their input.

## **Step 2: Assemble** <a href="#step-2-assemble" id="step-2-assemble"></a>

**Getting Started**

1. **Hardware Setup**
   * Connect the SMD to the PC or Arduino board using [USB Gateway Module](https://docs.acrome.net/electronics/gateway-modules/usb-gateway-module) or [Arduino Gateway Module](https://docs.acrome.net/electronics/gateway-modules/arduino-gateway-module).
   * Connect the [Joystick Module](/electronics/add-on-modules/joystick-module) 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/jENstWcJBQzFM4hM7a8h" alt=""><figcaption></figcaption></figure>

## Step 3: Run & Test

1. Joystick Input Monitoring: The system continuously reads the [joystick's ](/electronics/add-on-modules/joystick-module)X and Y values. The Y-axis value is the primary input for controlling the jump and duck actions.
2. Jump and Duck Actions: When the [joystick ](/electronics/add-on-modules/joystick-module)is moved upward (beyond a threshold), the system simulates a key press of the spacebar to make the Dino jump. When moved downward, it presses the down arrow key to make the Dino duck.
3. Key Release Management: When the [joystick ](/electronics/add-on-modules/joystick-module)returns to its neutral position, the system releases any pressed keys (spacebar or down arrow) to reset the character’s action in the game.
4. GUI Updates: The GUI continuously updates with the latest [joystick ](/electronics/add-on-modules/joystick-module)values and the current action (jump, duck, or none), giving the user real-time feedback on their input and the corresponding actions in the game.

## Code

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

```python
import pyautogui
import tkinter as tk
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


# Serial Communication Settings
baudrate = 115200           # Baud rate for communication
module_id = 0               # ID of the SMD module
joystick_module_id = 5      # ID of the joystick module


# Joystick Thresholds
threshold = 0.10            # Minimum movement threshold for joystick activation
max_val = 100               # Maximum joystick value for normalization


# Dictionary to track key states
keys_state = {
    'space': False,         # Space key (jump action)
    'down': False           # Down arrow key (duck action)
}


def 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 = USB_Port()
if not SerialPort:
    raise Exception("No compatible USB port found. Please check your connection.")

master = Master(SerialPort, baudrate)
master.attach(Red(module_id))
print("Connected Modules:", master.scan_modules(module_id))


# GUI Setup
root = tk.Tk()
root.title("Dino Game Controller")


# GUI Labels
joystick_label = tk.Label(root, text="Joystick State: (0, 0)", font=("Helvetica", 14))
joystick_label.pack(pady=10)

action_label = tk.Label(root, text="Action: None", font=("Helvetica", 14))
action_label.pack(pady=10)


def update_gui(x_val, y_val, action):
    """
    Updates the GUI to display the current joystick state and action.

    Args:
        x_val (float): The current x-axis value of the joystick.
        y_val (float): The current y-axis value of the joystick.
        action (str): The current action being performed (e.g., "Jump", "Duck", "None").
    """
    joystick_label.config(text=f"Joystick State: ({x_val:.2f}, {y_val:.2f})")
    action_label.config(text=f"Action: {action}")


def interpolate_value(value):
    """
    Normalizes joystick values and smooths movement.

    Args:
        value (float): The joystick input value.

    Returns:
        float: The interpolated value with smooth acceleration effect.
    """
    return (value / max_val) ** 2 * (1 if value > 0 else -1)


def joystick_control():
    """
    Continuously reads joystick data and translates movements into key presses.

    - Moves up (jump) when pushing joystick forward (Y > threshold).
    - Moves down (duck) when pulling joystick backward (Y < -threshold).
    - Releases keys when joystick is neutral.
    """
    action = "None"

    while True:
        joystick = master.get_joystick(module_id, joystick_module_id)

        if joystick is not None:
            x_val, y_val = joystick[0], joystick[1]
            y_val_smooth = interpolate_value(y_val)

            if abs(y_val_smooth) > threshold:
                # Jump (Up movement - Space key)
                if y_val_smooth > threshold:
                    if not keys_state['space']:
                        pyautogui.keyDown('space')
                        keys_state['space'] = True
                        action = "Jump"
                        update_gui(x_val, y_val, action)
                
                # Duck (Down movement - Down arrow key)
                elif y_val_smooth < -threshold:
                    if not keys_state['down']:
                        pyautogui.keyDown('down')
                        keys_state['down'] = True
                        action = "Duck"
                        update_gui(x_val, y_val, action)
            else:
                # Release keys if joystick is in neutral position
                if keys_state['space']:
                    pyautogui.keyUp('space')
                    keys_state['space'] = False
                    action = "None"
                
                if keys_state['down']:
                    pyautogui.keyUp('down')
                    keys_state['down'] = False
                    action = "None"

            # Update GUI
            update_gui(x_val, y_val, action)

        # Short delay to prevent excessive loop execution
        time.sleep(0.01)


# Start Joystick Control Thread
joystick_thread = Thread(target=joystick_control, daemon=True)
joystick_thread.start()

# Start GUI Main Loop
root.mainloop()
```

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

**Conclusion:** \
This project demonstrates how the [ACROME SMD ](/electronics/smd-red)platform can be used to create a joystick-controlled system for playing the Dino game. By integrating real-time [joystick](/electronics/add-on-modules/joystick-module) input, smooth interpolation, and graphical feedback, the system offers a fun and interactive way to control the game.


# Snake Game With Joystick

This code integrates a [joystick ](/electronics/add-on-modules/joystick-module)with a simple Snake Game using the pygame library. It also utilizes the [ACROME SMD](/electronics/smd-red) platform to receive [joystick](/electronics/add-on-modules/joystick-module) inputs and provide feedback, like turning on a [buzzer](/electronics/add-on-modules/buzzer-module) when food is consumed.

**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))

[Buzzer Module](/electronics/add-on-modules/buzzer-module) ([Purchase Here](https://www.robotshop.com/products/acrome-buzzer-sound-add-on-module-acrome-smd-products))

[Joystick Module](/electronics/add-on-modules/joystick-module) ([Purchase Here](https://www.robotshop.com/products/acrome-joystick-2-axis-add-on-module-acrome-smd-products))

## **Step 1: Hardware & Software Overview**

**Key Component:**

1. [Buzzer Module](/electronics/add-on-modules/buzzer-module)\
   Every time the snake eats the food[ Buzzer Module](/electronics/add-on-modules/buzzer-module) makes a sound.
2. [Joystick Module](/electronics/add-on-modules/joystick-module)\
   Handles snake movement.
3. pygame\
   Handles the graphics and user interface for the snake game. It displays the snake, food, score, and manages input events.
4. [ACROME SMD](/electronics/smd-red)\
   Communicates with the [joystick](/electronics/add-on-modules/joystick-module) and handles[ joystick ](/electronics/add-on-modules/joystick-module)input as well as [buzzer](/electronics/add-on-modules/buzzer-module) feedback.

**Project Key Features:**

1. Joystick Input: \
   The joystick connected via the ACROME SMD platform is used to control the snake's direction. The snake moves left, right, up, or down based on the joystick's X and Y-axis values. A button on the joystick can be used to pause and resume the game.
2. Start and Game Over Menus: \
   The game starts with a simple menu where you can choose to start the game or quit. If the game ends (snake hits a wall or itself), a game over menu is displayed, with options to retry or quit.
3. Game Logic: \
   The snake grows when it eats food, and the length is increased. The snake's movement speed is fixed but can be controlled by the joystick. A buzzer sound is triggered when the snake eats the food.
4. Pause Functionality: \
   A button on the joystick allows pausing and resuming the game.

## **Step 2: Assemble**

**Getting Started**

1. **Hardware Setup**
   * Connect the SMD to the PC or Arduino board using [USB Gateway Module](https://docs.acrome.net/electronics/gateway-modules/usb-gateway-module).
   * Connect the [Buzzer Module](/electronics/add-on-modules/buzzer-module) and the [Joystick Module](/electronics/add-on-modules/joystick-module) 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/F0UzNskSCmUJQi3lf3eI" alt=""><figcaption></figcaption></figure>

## Step 3: Run & Test

Start Menu: \
When the program is run, the start menu is displayed. The user can click on "Start" to begin the game or "Quit" to exit.

Snake Movement: \
During the game, the [joystick's ](/electronics/add-on-modules/joystick-module)position controls the snake's movement. Moving the [joystick ](/electronics/add-on-modules/joystick-module)in any direction updates the snake’s position.

Eating Food: \
When the snake's head collides with the food, the snake grows, and a [buzzer ](/electronics/add-on-modules/buzzer-module)sound is triggered.

Game Over: \
The game ends when the snake hits the boundaries or itself. A "Game Over" menu is displayed with options to retry or quit.

Pausing the Game: \
The game can be paused and resumed using the [joystick's ](/electronics/add-on-modules/joystick-module)button<br>

## Codes

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

```python
import pygame
import time
import random
from smd.red import *
from serial.tools.list_ports import comports
from platform import system

# SMD Module Settings
BAUDRATE = 115200       # Baud rate for communication
ID = 0                  # SMD module ID
JOYSTICK_ID = 5         # Joystick module ID
BUZZER_ID = 5           # Buzzer module ID

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()
    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, [])):
                return port.device
        print("No suitable USB device found.")
    else:
        print("No ports detected!")
    return None


# Initialize SMD module
serial_port = detect_usb_port()
if not serial_port:
    raise Exception("No compatible USB port found. Please check your connection.")

master = Master(serial_port, BAUDRATE)
master.attach(Red(ID))
print("Connected Modules:", master.scan_modules(ID))

# Initialize Pygame
pygame.init()

# Display Settings
WIDTH, HEIGHT = 600, 400
display = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption('Snake Game')

# Clock to control game speed
clock = pygame.time.Clock()

# Snake Settings
SNAKE_BLOCK = 10
SNAKE_SPEED = 15

# Colors
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
RED = (213, 50, 80)
GREEN = (0, 255, 0)

# Font styles
font_style = pygame.font.SysFont("bahnschrift", 25)
score_font = pygame.font.SysFont("comicsansms", 35)


def display_score(score):
    """ Displays the player's score on the screen. """
    value = score_font.render("Score: " + str(score), True, BLACK)
    display.blit(value, [0, 0])


def draw_snake(snake_block, snake_list):
    """ Draws the snake on the screen. """
    for x in snake_list:
        pygame.draw.rect(display, BLACK, [x[0], x[1], snake_block, snake_block])


def message(msg, color, y_displace=0):
    """ Displays a message on the screen. """
    mesg = font_style.render(msg, True, color)
    display.blit(mesg, [WIDTH / 6, HEIGHT / 3 + y_displace])


def buzzer_alert():
    """ Plays a short buzzer sound for feedback. """
    master.set_buzzer(ID, BUZZER_ID, 500, 100)  # 500Hz frequency, 100ms duration


def game_loop():
    """ Main game loop for Snake Game. """
    game_over = False
    close_game = False

    # Initial snake position and movement
    x1, y1 = WIDTH // 2, HEIGHT // 2
    x1_change, y1_change = 0, 0

    # Snake body and food
    snake_list = []
    snake_length = 1
    food_x = round(random.randrange(0, WIDTH - SNAKE_BLOCK) / 10.0) * 10.0
    food_y = round(random.randrange(0, HEIGHT - SNAKE_BLOCK) / 10.0) * 10.0

    while not game_over:
        while close_game:
            display.fill(RED)
            message("Game Over! Press Q to Quit or C to Restart", WHITE)
            display_score(snake_length - 1)
            pygame.display.update()

            for event in pygame.event.get():
                if event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_q:
                        game_over = True
                        close_game = False
                    if event.key == pygame.K_c:
                        game_loop()

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                game_over = True

        # Joystick control
        joystick = master.get_joystick(ID, JOYSTICK_ID)
        if joystick:
            x_axis, y_axis = joystick[0], joystick[1]
            if x_axis < -50:  # Left
                x1_change, y1_change = -SNAKE_BLOCK, 0
            elif x_axis > 50:  # Right
                x1_change, y1_change = SNAKE_BLOCK, 0
            elif y_axis < -50:  # Up
                x1_change, y1_change = 0, -SNAKE_BLOCK
            elif y_axis > 50:  # Down
                x1_change, y1_change = 0, SNAKE_BLOCK

        x1 += x1_change
        y1 += y1_change

        # Collision with boundaries
        if x1 >= WIDTH or x1 < 0 or y1 >= HEIGHT or y1 < 0:
            close_game = True
            buzzer_alert()  # Play buzzer when game over

        display.fill(WHITE)
        pygame.draw.rect(display, GREEN, [food_x, food_y, SNAKE_BLOCK, SNAKE_BLOCK])

        # Update snake position
        snake_head = [x1, y1]
        snake_list.append(snake_head)
        if len(snake_list) > snake_length:
            del snake_list[0]

        # Collision with itself
        for block in snake_list[:-1]:
            if block == snake_head:
                close_game = True
                buzzer_alert()  # Play buzzer when game over

        draw_snake(SNAKE_BLOCK, snake_list)
        display_score(snake_length - 1)

        # Food collision
        if x1 == food_x and y1 == food_y:
            food_x = round(random.randrange(0, WIDTH - SNAKE_BLOCK) / 10.0) * 10.0
            food_y = round(random.randrange(0, HEIGHT - SNAKE_BLOCK) / 10.0) * 10.0
            snake_length += 1
            master.set_buzzer(ID, BUZZER_ID, 1000, 100)  # Buzzer beep for eating food

        pygame.display.update()
        clock.tick(SNAKE_SPEED)

    pygame.quit()
    quit()


# Start the game loop
game_loop()
```

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

**Conclusion:** \
This is a fun and interactive way to use the [ACROME SMD](/electronics/smd-red) [joystick ](/electronics/add-on-modules/joystick-module)to control the classic Snake game, providing a hardware-based gaming experience.


# Pan-Tilt with Joystick Module

The Pan-Tilt Control System is a project that is widely used in many areas. It contains the [Joystick Module](/electronics/add-on-modules/joystick-module), two servo motors, two [Servo Modules](/electronics/add-on-modules/servo-module). The two servo motors provide a 2 DOF movement to the mechanism, one is horizontal (pan) and the other one is vertical (tilt) DOFs. These movement axes can be controlled through the [Joystick Module](/electronics/add-on-modules/joystick-module). A webcam or a [Ultrasonic Distance Sensor Module](/electronics/add-on-modules/ultrasonic-distance-sensor-module) can be connected to the Pan-Tilt Control System.

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

**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))

2x [Servo Module](/electronics/add-on-modules/servo-module) ([Purchase Here](https://www.robotshop.com/products/acrome-rc-servo-add-on-module-acrome-smd-products))

[Joystick Module](/electronics/add-on-modules/joystick-module) ([Purchase Here](https://www.robotshop.com/products/acrome-joystick-2-axis-add-on-module-acrome-smd-products))

[Ultrasonic Distance Sensor](/electronics/add-on-modules/ultrasonic-distance-sensor-module) ([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. [**SMD**](/electronics/smd-red)

   The 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 [Joystick Module](/electronics/add-on-modules/joystick-module) and control the two servo motors by the [Servo Modules](/electronics/add-on-modules/servo-module) in 2 different axes.
2. [**Servo Module**](/electronics/add-on-modules/servo-module)

   The Servo Module drives the servo motor that is connected to it. It can be controlled through the [SMD libraries](/software/libraries).
3. [**Joystick Module**](/electronics/add-on-modules/joystick-module)

   The [Joystick Module](/electronics/add-on-modules/joystick-module) allows the user to control the two servo motors, thus, two axes simultaneously.
4. [Ultrasonic Distance Sensor](/electronics/add-on-modules/ultrasonic-distance-sensor-module)\
   The [Ultrasonic Distance Sensor](/electronics/add-on-modules/ultrasonic-distance-sensor-module) enhances the Pan-Tilt System by enabling real-time object detection and tracking. Mounted on the tilt axis, it measures distances and can trigger alerts for nearby obstacles.
5. [**SMD Libraries**](/software/libraries)

   The SMD library is at the heart of the application. It communicates with the SMD using a specific communication protocol, sending commands to read the [Joystick Module](/electronics/add-on-modules/joystick-module) and send the servo motor control inputs to the Servo Modules.

**Project Key Features**

* **Flexible Position Control**\
  The Pan-Tilt Control System allows the user to control the mounted object in a flexible vay due to two servo motors and the precise motor driving capability of the SMD.
* **Intuitive Manual Control**\
  Through the [Joystick Module](/electronics/add-on-modules/joystick-module), the users can intuitively control the 2 DOF Pan-Tilt Control System.

## **Step 2: Assemble**

**Getting Started**

1. **Hardware Setup**
   * Connect the SMD to the PC or Arduino board using [USB Gateway Module](https://acrome.gitbook.io/acrome-smd-docs/electronics/gateway-modules/usb-gateway-module) .
   * Connect the [Joystick Module](/electronics/add-on-modules/joystick-module) and two [Servo Modules](/electronics/add-on-modules/servo-module) to the SMD using an RJ-45 cable.
   * Attach the servo motors to the designated axes for pan (horizontal) and tilt (vertical) movements.
   * Connect the each servo motor to the [Servo Modules](/electronics/add-on-modules/servo-module).
   * Make sure that the SMD is powered and all connections are correct.

#### Project Wiring Diagram

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

## Step 3: Run & Test

1. **Run the Script**
   * Execute the script, initiating the Pan-Tilt Control System application.
   * Move the joystick to see how the system works when different axes of joystick are used.

## **Codes**

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

```python
from smd.red import *
import numpy as np
from serial.tools.list_ports import comports
from platform import system

baudrate = 115200          # Baud rate of communication
ID = 0                     # ID of the SMD
joystick_id = 5            # ID of the joystick module
servo_pan_id = 5           # ID of the pan servo
servo_tilt_id = 5          # ID of the tilt servo


def 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.
    """
    # Get a list of available ports
    ports = list(comports())

    # Known USB port names for different operating systems
    usb_names = {
        "Windows": ["USB Serial Port"],  # Names specific to Windows
        "Linux": ["/dev/ttyUSB"],        # Names specific to Linux
        "Darwin": [                      # Names specific to macOS
            "/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",
        ]
    }

    # Detect the operating system
    os_name = system()
    print(f"Operating System: {os_name}")

    if ports:
        for port in ports:
            # Check if the port matches any known USB names
            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
        # If no suitable port is found, print the list of available ports
        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


try:
    # Find and initialize the USB port
    SerialPort = USB_Port()
    if not SerialPort:
        raise Exception("No compatible USB port found. Please check your connection.")

    # Initialize the SMD module
    master = Master(SerialPort, baudrate)       # Defines the USB gateway module
    master.attach(Red(ID))                      # Gives access to the SMD of specified ID
    print("Driver Info:", master.get_driver_info(ID))  # Print driver information
    print("Connected Modules:", master.scan_modules(ID))  # Scan and display connected modules

    # Main loop for joystick control
    while True:
        joystick_position = master.get_joystick(ID, joystick_id)  # Read joystick position
        if joystick_position is None:
            print("SMD connection issue:", master.get_driver_info(ID))
        else:
            # Adjust joystick X-axis value
            joystick_position[0] += 20
            if joystick_position[0] < 0:
                joystick_position[0] = np.interp(joystick_position[0], (-80, 0), (-100, 0))
            else:
                joystick_position[0] = np.interp(joystick_position[0], (0, 120), (0, 100))

            # Print joystick positions for debugging
            print("Joystick Y:", joystick_position[1])
            print("Joystick X:", joystick_position[0])

            # Set servo angles based on joystick position
            pan_angle = int(np.interp(joystick_position[0], (-100, 100), (0, 180)))
            tilt_angle = int(np.interp(joystick_position[1], (-100, 100), (0, 180)))
            master.set_servo(ID, servo_pan_id, pan_angle)  # Pan axis servo control
            master.set_servo(ID, servo_tilt_id, tilt_angle)  # Tilt axis servo control

except Exception as e:
    print(f"Error: {e}")
```

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


# Joystick Mouse Control

This project is an interactive system that controls the computer's mouse cursor using a [Joystick Module](/electronics/add-on-modules/joystick-module) connected to the [ACROME SMD](/electronics/smd-red). The user can adjust the mouse sensitivity dynamically through a graphical interface and perform mouse clicks using the [Joystick Module](/electronics/add-on-modules/joystick-module). The system continuously monitors [Joystick Module](/electronics/add-on-modules/joystick-module) inputs and responds accordingly, providing a seamless user experience for controlling the mouse cursor.

**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))

[Joystick Module](/electronics/add-on-modules/joystick-module) ([Purchase Here](https://www.robotshop.com/products/acrome-joystick-2-axis-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>

**Key Components:**

1. [ACROME SMD](/electronics/smd-red) \
   The [ACROME SMD](/electronics/smd-red) acts as the communication hub between the [Joystick Module](/electronics/add-on-modules/joystick-module) and the computer. It collects [Joystick Module](/electronics/add-on-modules/joystick-module) data, processes user input, and translates it into mouse movements and clicks.
2. [Joystick Module](/electronics/add-on-modules/joystick-module)\
   The [Joystick Module](/electronics/add-on-modules/joystick-module) serves as the main input device. The user can move the [Joystick Module](/electronics/add-on-modules/joystick-module) to control the mouse pointer’s X and Y coordinates on the screen. Additionally, the [Joystick Module](/electronics/add-on-modules/joystick-module) button can be used to trigger mouse clicks.
3. GUI (Tkinter) \
   A graphical user interface (GUI) is used to display real-time [Joystick Module](/electronics/add-on-modules/joystick-module) values (X and Y axes), sensitivity levels, and the button status. The GUI also allows the user to manually adjust the sensitivity for finer control.

**Project Features:**

1. Real-Time Joystick Mouse Control\
   The system continuously reads the X and Y values from the [Joystick Module](/electronics/add-on-modules/joystick-module) and moves the mouse pointer based on those inputs. The [Joystick Module](/electronics/add-on-modules/joystick-module)’s button is mapped to mouse clicks, allowing users to interact with on-screen elements.
2. Dynamic Sensitivity Adjustment\
   The system features dynamic sensitivity control, which adjusts the mouse movement speed based on the [Joystick Module](/electronics/add-on-modules/joystick-module)’s input magnitude. Users can also manually set the base sensitivity via the GUI for greater precision.
3. Graphical Interface for Feedback\
   The GUI provides real-time feedback to the user, displaying the current X and Y values of the [Joystick Module](/electronics/add-on-modules/joystick-module), the sensitivity, and whether the [Joystick Module](/electronics/add-on-modules/joystick-module) button is pressed or released. This ensures transparency in how the [Joystick Module](/electronics/add-on-modules/joystick-module) movements are translated into mouse actions.
4. Manual Sensitivity Input\
   The user can adjust the base sensitivity through an input field in the GUI. Once entered, the new sensitivity is applied, and the system updates the sensitivity label accordingly.
5. Multithreading for Real-Time Control\
   To ensure the mouse control happens smoothly without interrupting the GUI, the system uses a separate thread for handling the joystick inputs and mouse control. This ensures that both the GUI and joystick functionalities run in parallel without delays.

## **Step 2: Assemble**

**Workflow:**

1. [Joystick Module](/electronics/add-on-modules/joystick-module) Data Monitoring\
   The system continuously reads the [Joystick Module](/electronics/add-on-modules/joystick-module)'s X, Y, and button values. These inputs control the mouse pointer’s movements and clicks.
2. Mouse Movement Control\
   Based on the [Joystick Module](/electronics/add-on-modules/joystick-module)’s X and Y axis values, the system calculates the new mouse pointer position and moves the cursor accordingly. The movement speed is influenced by both the base sensitivity and dynamic multiplier, which adjusts based on the [Joystick Module](/electronics/add-on-modules/joystick-module)'s movement magnitude.
3. Button Click Simulation\
   If the [Joystick Module](/electronics/add-on-modules/joystick-module)’s button is pressed, the system simulates a mouse click. The button press also temporarily increases the base sensitivity for quicker movements.
4. GUI Updates\
   The GUI continuously updates with the latest [Joystick Module](/electronics/add-on-modules/joystick-module) values, sensitivity, and button status, providing visual feedback to the user.

#### Getting Started

1. **Connect the SMD**: Connect the [ACROME SMD](/electronics/smd-red)  to your PC using a [USB Gateway Module](/electronics/gateway-modules/usb-gateway-module) .
2. **Set Up the Joystick Module**: Connect the [Joystick Module](/electronics/add-on-modules/joystick-module) to the SMD using an RJ-45 cable.
3. **Power Connections**: Ensure that the [SMD ](/electronics/smd-red)is powered and that all connections are securely made.

#### Project Wiring Diagram

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

## Step 3: Run & Test

1. **Run the Application**:
   * Execute the provided Python script to start the Joystick Mouse Control application.
   * Once the application is running, move the [Joystick Module](/electronics/add-on-modules/joystick-module) to control the mouse cursor on your screen. Experiment with different [Joystick Module](/electronics/add-on-modules/joystick-module) movements to understand how they translate to mouse actions.
2. **Adjust Sensitivity**: Use the GUI to adjust the sensitivity settings for finer control as needed.

## Codes

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

```python
from smd.red import *
import time
import pyautogui
import tkinter as tk
from threading import Thread
from serial.tools.list_ports import comports
from platform import system

pyautogui.FAILSAFE = False

baudrate = 115200          # Baud rate of communication
ID = 0                     # ID of the SMD
joystick_id = 5            # ID of the joystick module
button_id = 5              # ID of the button module


def 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.
    """
    # Get a list of available ports
    ports = list(comports())

    # Known USB port names for different operating systems
    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",
        ]
    }

    # Detect the operating system
    os_name = system()
    print(f"Operating System: {os_name}")

    if ports:
        for port in ports:
            # Check if the port matches any known USB names
            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
        # If no suitable port is found, print the list of available ports
        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


# Find and initialize the USB port
SerialPort = USB_Port()
if not SerialPort:
    raise Exception("No compatible USB port found. Please check your connection.")

# Initialize the SMD module
master = Master(SerialPort, baudrate)
master.attach(Red(ID))
print("Connected Modules:", master.scan_modules(ID))


# Sensitivity settings
base_sensitivity = 0.5  # Default sensitivity
dynamic_multiplier = 1.0  # Multiplier for dynamic sensitivity


# GUI setup
window = tk.Tk()
window.title("Joystick Mouse Control")
window.geometry("300x300")

x_label = tk.Label(window, text="X Value: 0", font=("Helvetica", 14))
x_label.pack(pady=10)

y_label = tk.Label(window, text="Y Value: 0", font=("Helvetica", 14))
y_label.pack(pady=10)

sensitivity_label = tk.Label(window, text="Sensitivity: 0.5", font=("Helvetica", 14))
sensitivity_label.pack(pady=10)

button_status_label = tk.Label(window, text="Button Status: Released", font=("Helvetica", 14))
button_status_label.pack(pady=10)

sensitivity_entry = tk.Entry(window)
sensitivity_entry.pack(pady=10)
sensitivity_entry.insert(0, str(base_sensitivity))


def update_gui(x_val, y_val, sensitivity, button_status):
    """
    Updates GUI elements with joystick values, sensitivity, and button status.
    """
    x_label.config(text=f"X Value: {x_val:.2f}")
    y_label.config(text=f"Y Value: {y_val:.2f}")
    sensitivity_label.config(text=f"Sensitivity: {sensitivity:.2f}")
    button_status_label.config(text=f"Button Status: {button_status}")


def update_sensitivity():
    """
    Updates the base sensitivity for joystick control based on user input.
    """
    global base_sensitivity
    try:
        base_sensitivity = float(sensitivity_entry.get())
        sensitivity_label.config(text=f"Sensitivity: {base_sensitivity:.2f}")
    except ValueError:
        sensitivity_label.config(text="Invalid sensitivity value")


apply_button = tk.Button(window, text="Apply Sensitivity", command=update_sensitivity)
apply_button.pack(pady=10)


def joystick_control():
    """
    Handles joystick input for mouse control.
    """
    global base_sensitivity, dynamic_multiplier

    while True:
        joystick = master.get_joystick(ID, joystick_id)
        if joystick is None:
            print("Joystick not connected!")
            continue

        x_val, y_val = joystick[0], joystick[1]
        button_status = "Pressed" if master.get_button(ID, button_id) == 1 else "Released"

        # Update dynamic multiplier
        dynamic_multiplier = max(1.0, min(5.0, (abs(x_val) + abs(y_val)) / 50))

        # Adjust sensitivity
        x_val *= base_sensitivity * dynamic_multiplier
        y_val *= base_sensitivity * dynamic_multiplier
        y_val *= -1  # Invert Y-axis for proper mouse movement

        # Update mouse position
        if abs(x_val) > 5 or abs(y_val) > 5:
            pyautogui.moveRel(x_val, y_val)

        # Handle button click
        if joystick[2] == 1:
            pyautogui.click()

        # Update GUI
        update_gui(joystick[0], joystick[1], base_sensitivity, button_status)

        time.sleep(0.01)


# Start joystick control in a separate thread
joystick_thread = Thread(target=joystick_control)
joystick_thread.daemon = True
joystick_thread.start()

# Run the GUI loop
window.mainloop()
```

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

**Conclusion:** \
This project demonstrates how the [ACROME SMD](/electronics/smd-red)  can be used to create an interactive joystick-controlled system for managing mouse movements. By integrating real-time [Joystick Module](/electronics/add-on-modules/joystick-module) input with dynamic sensitivity control and a graphical interface for user feedback, the system provides an intuitive and customizable solution for precise cursor control.


# Rev Up the Engine

The Rev Up the Engine project is a fun project that imitates the revving of an engine through software and hardware. It has both visual and physical interaction modules. There is the Button Module for the user to interact and imitate a gas pedal. There are also the [Buzzer Module](/electronics/add-on-modules/buzzer-module) and the [RGB LED Module](/electronics/add-on-modules/rgb-led-module) as rev limiter sound and rev level indicator.

**About Tools and Materials:**

[SMD Red](/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](/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) ([Purchase Here](https://www.robotshop.com/products/acrome-arduino-gateway-shield-module-acrome-smd-products))

[RGB LED Module](/electronics/add-on-modules/rgb-led-module) ([Purchase Here](https://www.robotshop.com/products/acrome-rgb-led-add-on-module-acrome-smd-products))

[Button Module](/electronics/add-on-modules/button-module) ([Purchase Here](https://www.robotshop.com/products/acrome-button-add-on-module-acrome-smd-products?pr_prod_strat=e5_desc\&pr_rec_id=e23ece12f\&pr_rec_pid=8120246796449\&pr_ref_pid=8121226592417\&pr_seq=uniform))

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

[Buzzer Module](/electronics/add-on-modules/buzzer-module) ([Purchase Here](https://www.robotshop.com/products/acrome-buzzer-sound-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. [**SMD**](/electronics/smd-red)

   The 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](/electronics/add-on-modules/button-module) and actuate the BDC motor, the [RGB LED Module](/electronics/add-on-modules/rgb-led-module) and the [Buzzer Module](/electronics/add-on-modules/buzzer-module).
2. [BDC Motor](/electronics/electrical-motors/brushed-dc-motors-bdc)&#x20;

   The 100 RPM BDC Motor with Encoder is used to imitate an engine running. The speed of the motor can be controlled precisely thanks to the built-in encoder.
3. [**Button Module**](/electronics/add-on-modules/button-module)

   The Button Module is used as an physical interaction device for the user. It imitates a gas pedal, revving the engine while it is pressed.
4. [RGB LED Module](/electronics/add-on-modules/rgb-led-module)\
   Changes colors based on engine speed, acting as a visual rev limiter indicator.
5. [Buzzer Module](/electronics/add-on-modules/buzzer-module)\
   Produces revving sounds that match engine speed for a realistic experience.
6. [**SMD Libraries**](/software/libraries)

   The SMD library is at the heart of the application. It communicates with the SMD using a specific communication protocol, sending commands to read the [Button Module](/electronics/add-on-modules/button-module) and actuate the BDC motor, also the other modules.

**Project Key Features**

* **Dynamic Engine Revving**

  The project allows the user to use the modules to interact and imitate an engine. It is a great project for seeing the results of the physical interaction. Holding the [Button Module](/electronics/add-on-modules/button-module) will result in rev increase and releasing it will decrease the rev.
* **Real-time Speed Control**

  The script continuously can store and monitor the current velocity level of the motor. The user can use these values to modify the project.
* **Customizable Speed Profile**

  The user can customize the step time or rev increase amount per step. Also, the [RGB LED Module](/electronics/add-on-modules/rgb-led-module) can be used to emit different light levels and colors.

## **Step 2: Assemble**

**Getting Started**

1. **Hardware Setup**
   * Connect the SMD to the PC or Arduino board using [USB Gateway Module](https://acrome.gitbook.io/acrome-smd-docs/electronics/gateway-modules/usb-gateway-module) or [Arduino Gateway Module](https://acrome.gitbook.io/acrome-smd-docs/electronics/gateway-modules/arduino-gateway-module).
   * Connect the 100 RPM BDC Motor with Encoder to the motor ports of the SMD and the [Button Module](/electronics/add-on-modules/button-module), the [RGB LED Module](/electronics/add-on-modules/rgb-led-module) and the [Buzzer Module](/electronics/add-on-modules/buzzer-module) 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/SlHHAvWeDopJH4v7dR3v" alt=""><figcaption></figcaption></figure>

## Step 3: Run & Test

1. **Run the Script**
   * Execute the script, initiating the Rev Up the Engine project.
   * Press or hold the [Button Module](/electronics/add-on-modules/button-module) to see the engine revving and other visual experiences.
2. **Experience the Engine Revving**
   * Observe how the motor speed increases gradually while the button is held down.
   * Release the button and notice the motor speed decreasing until it comes to a stop.
3. **Customize and Experiment**
   * Experiment with different parameter values in the script to customize the speed profile.
   * Explore additional features, such as the buzzer sound and frequency and RGB LED colors and intensities.

## Codes:

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

```python
from smd.red import*
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)
m.attach(Red(0))

print(m.scan_modules(0))

m.set_operation_mode(0, 0)
m.enable_torque(0, True)

button_prev = 0
pwm = 0

while True:
    time.sleep(0.05)
    button = m.get_button(0, 1)
    print(button)

    if button != None:
            if button == 1:
                if button_prev == 0:  # Button was just pressed
                    for pwm in range(51):
                        m.set_duty_cycle(0, pwm)
                        time.sleep(0.1)
                        red_value = int(pwm * 255 / 50)
                        green_value = int((50 - pwm) * 255 / 50)
                        light = m.set_rgb(0, 1, red=red_value, green=green_value, blue=0)
                        if pwm == 50:
                             m.set_buzzer(0, 1, 1000)  # Activate the buzzer
                    button_prev = 1
            elif button == 0:
                if button_prev == 1:  # Button was just released
                    for pwm in range(50, -1, -1):
                        m.set_duty_cycle(0, pwm)
                        time.sleep(0.1)
                        red_value = int(pwm * 255 / 50)
                        green_value = int((50 - pwm) * 255 / 50)
                        light = m.set_rgb(0, 1, red=red_value, green=green_value, blue=0)
                        if pwm == 0:
                            m.set_buzzer(0, 1, 0)  # Deactivate the buzzer

                    button_prev = 0
```

{% endcode %}
{% endtab %}

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

```cpp
#include <Acrome-SMD.h>

#define ID 0
#define BAUDRATE 115200

Red master(ID, Serial, BAUDRATE);

bool button_prev = false;
int pwm = 0;

void setup() {
    master.begin();
    master.scanModules();
    master.setOperationMode(0);
    master.torqueEnable(1);
}

void loop() {
    bool button = master.getButton(5);

    if (button) {
        if (!button_prev) {  
            for (pwm = 0; pwm <= 50; pwm++) {
                master.setpoint(0, pwm);
                delay(100);
                int red_value = pwm * 255 / 50;
                int green_value = (50 - pwm) * 255 / 50;
                master.setRGB(5, red_value, green_value, 0); 
                if (pwm == 50) {
                    master.setBuzzer(5, 1000);
                }
            }
            button_prev = true;
        }
    } else {
        if (button_prev) { 
            for (pwm = 50; pwm >= 0; pwm--) {
                master.setpoint(0, pwm); 
                delay(100);
                int red_value = pwm * 255 / 50;
                int green_value = (50 - pwm) * 255 / 50;
                master.setRGB(5, red_value, green_value, 0); 
                if (pwm == 0) {
                    master.setBuzzer(5, 0);
                }
            }
            button_prev = false;
        }
    }
}
```

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


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

**About Tools and Materials:**

[SMD Red](/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](/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) ([Purchase Here](https://www.robotshop.com/products/acrome-arduino-gateway-shield-module-acrome-smd-products))

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

## **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. [**SMD**](/electronics/smd-red)\
   The 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](/electronics/add-on-modules/button-module) and actuate the BDC motor, the [RGB LED Module](/electronics/add-on-modules/rgb-led-module) and the [Buzzer Module](/electronics/add-on-modules/buzzer-module).
2. [BDC Motor](/electronics/electrical-motors/brushed-dc-motors-bdc)\
   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.

## **Step 2: Assemble**

**Getting Started**

1. **Hardware Setup**
   * Connect the SMD to the PC or Arduino board using [USB Gateway Module](https://acrome.gitbook.io/acrome-smd-docs/electronics/gateway-modules/usb-gateway-module) or [Arduino Gateway Module](https://acrome.gitbook.io/acrome-smd-docs/electronics/gateway-modules/arduino-gateway-module).
   * Connect the 100 RPM [BDC Motor](/electronics/electrical-motors/brushed-dc-motors-bdc) 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

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

## Step 3: Run & Test

Run the Script

1. Execute the script to initiate the Motor Rotation Based on Turn Input Value project.
2. Enter different turn values in the control interface to observe the motor behavior.
3. Input a positive value to rotate the motor clockwise (CW).
4. &#x20;Input a negative value to rotate the motor counterclockwise (CCW).
5. &#x20;Input zero (0) to stop the motor.
6. 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

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

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

{% endcode %}
{% endtab %}

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

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

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


# Basic Motor Speed Control Application

This program demonstrates a basic motor control application that adjusts the motor's speed based on user input. It communicates with the motor controller via USB and sets the motor speed (velocity) according to the user's specified value. This allows for simple motor speed control, where the user can input a desired speed, and the motor will rotate accordingly.

**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](https://docs.acrome.net/electronics/gateway-modules/arduino-gateway-module) ([Purchase Here](https://www.robotshop.com/products/acrome-arduino-gateway-shield-module-acrome-smd-products))

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

## **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. [**SMD**](https://docs.acrome.net/electronics/smd-red) The 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](https://docs.acrome.net/electronics/add-on-modules/button-module) and actuate the BDC motor, the [RGB LED Module](https://docs.acrome.net/electronics/add-on-modules/rgb-led-module) and the [Buzzer Module](https://docs.acrome.net/electronics/add-on-modules/buzzer-module).
2. [BDC Motor](https://docs.acrome.net/electronics/electrical-motors/brushed-dc-motors-bdc) The motor is controlled using velocity commands, allowing for smooth acceleration and deceleration.

**Project Key Features:**

1. **USB Port Detection**:
   1. The program starts by detecting the available USB serial port for communication with the motor. It uses the `serial` module to find connected serial devices.
   2. The program supports multiple platforms (Windows, Linux, and macOS) and automatically identifies the correct port based on the operating system.
2. **Motor Control with SMD Red**:
   1. The motor is controlled through the `smd.red` library, which allows sending commands to the motor via the Red controller.
   2. A `Master` object is used to establish communication with the motor, and the motor is attached using the `Red(ID)` method.
3. **Motor Speed Configuration**:
   1. The program allows the user to input a speed value (in RPM or another suitable unit). The motor's velocity is set to this value using the `m.set_velocity()` method.
   2. The motor's other parameters, such as the revolutions per minute (RPM) and control settings, are preconfigured for optimal operation.
4. **User Input**:
   1. The program prompts the user to input the desired motor speed, and then it sets the motor’s velocity accordingly. The speed is used to control how fast the motor will rotate.
5. **Feedback to User**:
   1. After setting the motor speed, the program confirms the set speed with a printed message: `"The engine rotates at speed {speed}."`

## **Step 2: Assemble**

**Getting Started**

1. **Hardware Setup**
   * Connect the SMD to the PC or Arduino board using [USB Gateway Module](https://acrome.gitbook.io/acrome-smd-docs/electronics/gateway-modules/usb-gateway-module) or [Arduino Gateway Module](https://acrome.gitbook.io/acrome-smd-docs/electronics/gateway-modules/arduino-gateway-module).
   * Connect the 100 RPM [BDC Motor](/electronics/electrical-motors/brushed-dc-motors-bdc) 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

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

## Step 3: Run & Test

#### Run the Script

1\. Upload the Arduino code to the SMD Master Controller using the Arduino IDE.

2\. Open the Serial Monitor (set baud rate to 115200).

3\. Enter a speed value (0 to 5000) to adjust the motor speed.

#### Experience Speed Control

• Observe how the motor starts at 50 RPM (default) and adjusts based on the entered speed.

• Enter a higher speed value to increase the motor velocity.

• Enter zero (0) to stop the motor.

## Codes

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

```python
from smd.red import *  # Import the SMD Red motor control library
from serial.tools.list_ports import comports  # Import serial communication tools
from platform import system  # Import system information module
import math
import os

# Function to detect and return the correct USB port for communication
def USB_Port():
    ports = list(comports())  # Get a list of available serial ports
    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",
            "/dev/cu.usbmodem",
            "/dev/cu.SLAB_USBtoUART",
            "/dev/cu.wchusbserial",
        ]
    }
    
    os_name = system()  # Detect the operating system
    if ports:  # If ports are available
        for port, desc, hwid in sorted(ports):  # Iterate through detected ports
            # Check if the port name or description matches the expected USB names
            if any(name in port or name in desc for name in usb_names.get(os_name, [])):
                return port  # Return the detected port
        
        # If no matching port was found, print the available ports
        print("Current ports:")
        for port, desc, hwid in ports:
            print(f"Port: {port}, Description: {desc}, Hardware ID: {hwid}")
    else:
        print("No port found")  # Print message if no ports are detected
    return None  # Return None if no suitable port is found

# Get the detected USB port
port = USB_Port()

# Initialize the motor controller using the detected port
m = Master(port)

# Define motor ID
ID = 0

# Attach the motor to the master controller
m.attach(Red(ID))

# Configure motor settings
m.set_shaft_cpr(ID, 6533)  # Set encoder counts per revolution (CPR)
m.set_shaft_rpm(ID, 100)  # Set shaft rotation speed in RPM
m.set_operation_mode(ID, OperationMode.Velocity)  # Set motor to velocity control mode
m.set_control_parameters_velocity(ID, 30.0, 5.0, 0.0)  # Set PID control parameters (P, I, D)
m.enable_torque(ID, True)  # Enable motor torque

# Get user input for speed
speed = input("Speed: ")

# Set the velocity of the motor based on user input
m.set_velocity(ID, float(speed))

# Print the motor's current speed
print("The motor rotates at speed " + speed + ".")
```

{% endcode %}
{% endtab %}

{% tab title="Arduino Code" %}

```cpp
#include <Acrome-SMD.h>  // Include the Acrome-SMD library

#define ID         0  // Define motor ID
#define CPR        6533  // Encoder counts per revolution
#define RPM        100  // Shaft speed in RPM
#define BAUDRATE   115200  // Baud rate for serial communication

Red master(ID, Serial, BAUDRATE);  // Initialize the motor controller

void setup() {
    Serial.begin(BAUDRATE);  // Start Serial Monitor
    delay(500);  // Wait to stabilize serial communication

    master.begin();  // Initialize SMD motor communication

    Serial.println("Detecting SMD motor...");
    
    // Set motor settings
    master.setMotorCPR(CPR);  // Set encoder CPR
    master.setMotorRPM(RPM);  // Set motor RPM
    master.setOperationMode(2);  // Set motor to velocity control mode (2 = Velocity Mode)
    
    // Set PID control parameters: (OperationMode, P, I, D, Deadband, Feedforward)
    master.setControlParameters(2, 30.0, 5.0, 0.0, 0.0, 0.0);
    
    // Enable motor torque
    master.torqueEnable(1);

    Serial.println("Motor is ready.");
}

void loop() {
    Serial.println("Enter the speed:");

    // Wait for user input
    while (Serial.available() == 0) {
        delay(100);
    }

    // Read input speed from Serial Monitor
    int speed = Serial.parseInt();
    Serial.println("Speed entered: " + String(speed));

    // Set motor speed
    master.setpoint(2, speed);

    // Print confirmation message
    Serial.println("The motor rotates at speed " + String(speed) + ".");
    
    delay(100);  // Small delay to avoid overloading the system
}
```

{% endtab %}
{% endtabs %}


# Basic Motor Control Application Using PWM Input

This program demonstrates a fundamental motor control application, where the motor’s behavior is controlled through Pulse Width Modulation (PWM) input specified by the user. The script sets up the motor, establishes communication, and allows the user to input a PWM value to control the motor's rotation speed and direction. PWM is a common method to adjust motor speed in motor control applications.

**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](https://docs.acrome.net/electronics/gateway-modules/arduino-gateway-module) ([Purchase Here](https://www.robotshop.com/products/acrome-arduino-gateway-shield-module-acrome-smd-products))

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

## **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. [**SMD**](https://docs.acrome.net/electronics/smd-red)**:** The 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](https://docs.acrome.net/electronics/add-on-modules/button-module) and actuate the BDC motor, the [RGB LED Module](https://docs.acrome.net/electronics/add-on-modules/rgb-led-module) and the [Buzzer Module](https://docs.acrome.net/electronics/add-on-modules/buzzer-module).
2. [BDC Motor](https://docs.acrome.net/electronics/electrical-motors/brushed-dc-motors-bdc): The motor is controlled using velocity commands, allowing for smooth acceleration and deceleration.

#### **Project Key Features**

1. **USB Port Detection**:
   1. The script first identifies and connects to the appropriate USB serial port based on the operating system. It uses the `serial` module to scan for connected serial devices.
   2. The program is compatible with Windows, Linux, and macOS, using different naming conventions for the USB port depending on the OS.
2. **Motor Initialization and Configuration**:
   1. The `Master` and `Red` objects from the `smd.red` library are used to set up the motor and establish communication.
   2. The motor's essential parameters are initialized, such as counts per revolution (`set_shaft_cpr`) and shaft RPM (`set_shaft_rpm`).
3. **PWM Input for Motor Control**:
   1. After configuring the motor, the program prompts the user to input a PWM value, which will control the motor’s rotation speed and direction.
   2. PWM values can vary, with positive values for one direction and negative values for the opposite. This input is passed to the motor using `m.set_duty_cycle(0, -int(pwm))`.
   3. By inputting a PWM value, the user directly controls the motor’s duty cycle, affecting both the speed and direction.
4. **User Feedback**:
   1. After setting the PWM, the program prints a confirmation message indicating that the motor is running at the specified PWM level.

## **Step 2: Assemble** <a href="#step-2-assemble" id="step-2-assemble"></a>

#### **Getting Started**

1. **Hardware Setup**
   * Connect the SMD to the PC or Arduino board using [USB Gateway Module](https://acrome.gitbook.io/acrome-smd-docs/electronics/gateway-modules/usb-gateway-module) or [Arduino Gateway Module](https://acrome.gitbook.io/acrome-smd-docs/electronics/gateway-modules/arduino-gateway-module).
   * Connect the 100 RPM [BDC Motor](https://docs.acrome.net/electronics/electrical-motors/brushed-dc-motors-bdc) with Encoder to the motor ports of the SMD Red.
   * Make sure that the SMD is powered and all connections are correct.

#### **Project Wiring Diagram**

<figure><img src="/files/1bc65n9gm1iZlqh9GDn8" alt=""><figcaption></figcaption></figure>

## Step 3: Run & Test <a href="#step-3-run-and-test" id="step-3-run-and-test"></a>

#### Run the Script

• Execute the script to initiate the Basic Motor Control Application Using PWM Input.

• The script will automatically detect the USB port and establish communication with the SMD Master Controller.

• Enter a PWM value (0 to 255) when prompted to adjust the motor speed.

#### Experience PWM-Based Motor Control

• Observe how the motor speed increases as the PWM value increases.

• Enter zero (0) to stop the motor completely.

• Notice how the PWM signal directly influences the motor speed, providing smooth and efficient control.

## Codes

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

```python
from smd.red import *  # Import the SMD Red motor control library
import math
import os

from serial.tools.list_ports import comports  # Import serial communication tools
from platform import system  # Import system detection module

# Function to detect and return the correct USB port for communication
def USB_Port():
    ports = list(comports())  # Get a list of available serial ports
    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",
            "/dev/cu.usbmodem",
            "/dev/cu.SLAB_USBtoUART",
            "/dev/cu.wchusbserial",
        ]
    }
    
    os_name = system()  # Detect the operating system
    if ports:  # If ports are available
        for port, desc, hwid in sorted(ports):  # Iterate through detected ports
            # Check if the port name or description matches the expected USB names
            if any(name in port or name in desc for name in usb_names.get(os_name, [])):
                return port  # Return the detected port
        
        # If no matching port was found, print the available ports
        print("Current ports:")
        for port, desc, hwid in ports:
            print(f"Port: {port}, Description: {desc}, Hardware ID: {hwid}")
    else:
        print("No port found")  # Print message if no ports are detected
    return None  # Return None if no suitable port is found

# Get the detected USB port
port = USB_Port()

# Initialize the motor controller using the detected port
m = Master(port)

# Attach the motor with ID 0
m.attach(Red(0))

# Set motor parameters
m.set_shaft_cpr(0, 6533)  # Set encoder counts per revolution (CPR)
m.set_shaft_rpm(0, 100)  # Set shaft speed in RPM

# Initialize control variables
motor_speed = 0
angle_degrees = 0
current_limit = 100  # Maximum allowable current
current_value = 0
previous_current = 0  # Store the previous current value for monitoring

# Configure motor operation modes and control parameters
m.set_operation_mode(0, OperationMode.Velocity)  # Set velocity control mode
m.set_control_parameters_velocity(0, 30.0, 5.0, 0.0)  # Set PID parameters for velocity control
m.set_control_parameters_position(0, 0.5, 0.0, 20.0)  # Set PID parameters for position control
m.set_control_parameters_torque(0, 3.0, 0.1, 0.0)  # Set PID parameters for torque control

# Enable motor torque to allow movement
m.enable_torque(0, True)

# Switch the motor to PWM control mode
m.set_operation_mode(0, OperationMode.PWM)

# Ask user to enter PWM value
pwm = input("PWM: ")

# Set motor PWM duty cycle (negative value for reverse direction)
m.set_duty_cycle(0, -int(pwm))

# Print confirmation message
print(f"The motor is running with a PWM value of {pwm}.")
```

{% endcode %}
{% endtab %}

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

```cpp
#include <Acrome-SMD.h>

// Define motor parameters
#define MOTOR_ID 0       // SMD Red Motor ID
#define BAUDRATE 115200  // Serial Communication Baud Rate
#define CPR 6533         // Encoder Counts Per Revolution (CPR)
#define DEFAULT_RPM 100  // Default motor speed in RPM

// 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.setShaftCpr(CPR);    // Set Encoder Counts Per Revolution (CPR)
    motor.setShaftRpm(DEFAULT_RPM);  // Set default motor speed in RPM

    // Configure control parameters
    motor.setOperationMode(OperationMode::Velocity);  // Set to Velocity Control Mode
    motor.setControlParametersVelocity(30.0, 5.0, 0.0);  // PID for Velocity Control
    motor.setControlParametersPosition(0.5, 0.0, 20.0);  // PID for Position Control
    motor.setControlParametersTorque(3.0, 0.1, 0.0);  // PID for Torque Control

    // Enable motor torque
    motor.enableTorque(true);

    // Switch motor to PWM control mode
    motor.setOperationMode(OperationMode::PWM);
}

void loop() {
    if (Serial.available() > 0) {
        String input = Serial.readStringUntil('\n');  // Read user input
        int pwmValue = input.toInt();  // Convert input to integer

        if (pwmValue >= -255 && pwmValue <= 255) {  // Limit PWM range
            motor.setDutyCycle(pwmValue);  // Apply PWM value
            Serial.print("The motor is running with a PWM value of ");
            Serial.println(pwmValue);
        } else {
            Serial.println("Invalid PWM value! Enter a number between -255 and 255.");
        }
    }
}
```

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


# Basic Motor Position Control Application

In this application, you will learn how to control a DC motor’s **exact position** in degrees using the **Position Mode** of the SMD Red module. You will enter a target angle between `0` and `360`, and the motor will rotate precisely to that point using encoder feedback.

**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](https://docs.acrome.net/electronics/gateway-modules/arduino-gateway-module) ([Purchase Here](https://www.robotshop.com/products/acrome-arduino-gateway-shield-module-acrome-smd-products))

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

## **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. [SMD Red](/electronics/smd-red): Controls the brushed DC motor and reads encoder feedback for accurate position control.
2. [BDC Motor](/electronics/electrical-motors/brushed-dc-motors-bdc): Converts electrical energy to mechanical rotation and provides position feedback via encoder signals.

#### **Project Key Features**

1. **Precise angle-based control**: Move the motor shaft to an exact angle between 0° and 360°.
2. **Real-time encoder feedback**: Monitor actual shaft position with high-resolution encoder data.
3. **Tunable PID position control**: Customize responsiveness and stability using:\
   `set_control_parameters_position`
4. **Encoder-integrated control loop**: Closed-loop control ensures accurate positioning over time.

## **Step 2: Assemble** <a href="#step-2-assemble" id="step-2-assemble"></a>

#### **Getting Started**

**Hardware Setup**

* Connect the SMD to the PC or Arduino board using [USB Gateway Module](https://acrome.gitbook.io/acrome-smd-docs/electronics/gateway-modules/usb-gateway-module) or [Arduino Gateway Module](https://acrome.gitbook.io/acrome-smd-docs/electronics/gateway-modules/arduino-gateway-module).
* Connect the 100 RPM [BDC Motor](https://docs.acrome.net/electronics/electrical-motors/brushed-dc-motors-bdc) with Encoder to the motor ports of the SMD Red.
* Make sure that the SMD is powered and all connections are correct.

#### **Project Wiring Diagram**

<figure><img src="/files/1bc65n9gm1iZlqh9GDn8" alt=""><figcaption></figcaption></figure>

## Step 3: Run & Test <a href="#step-3-run-and-test" id="step-3-run-and-test"></a>

#### Run the Script

After launching the script, you will be prompted to enter a desired angle between `0` and `360` degrees.\
The motor will rotate to the target position using encoder feedback and stop.

## Codes

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

```python
from smd.red import *  # Import SMD Red control library
from serial.tools.list_ports import comports  # For listing available serial ports
from platform import system  # To detect the operating system
import time  # For sleep/delay
import math  # For mathematical operations

# Automatically detect and return the correct USB port connected to SMD Red
def USB_Port():
    ports = list(comports())
    usb_names = {
        "Windows": ["USB Serial Port"],
        "Linux": ["/dev/ttyUSB"],
        "Darwin": ["/dev/cu."]  # macOS ports usually start with /dev/cu.
    }
    os_name = system()
    for port, desc, _ in ports:
        if any(name in port or name in desc for name in usb_names.get(os_name, [])):
            return port
    return None

def main():
    port = USB_Port()
    if not port:
        print("No port found.")  # If no port is found, exit the program
        return

    master = Master(port)  # Create a Master object to control SMD Red
    motor_id = 1  # ID of the connected motor
    CPR = 6533  # Encoder Counts Per Revolution

    # Attach the motor and configure its basic parameters
    master.attach(Red(motor_id))
    master.set_shaft_cpr(motor_id, CPR)  # Set encoder resolution
    master.set_shaft_rpm(motor_id, 100)  # Set nominal RPM
    master.set_control_parameters_position(motor_id, 0.5, 0.0, 20.0)  # Set PID gains for position control
    master.set_operation_mode(motor_id, OperationMode.Position)  # Enable position control mode
    master.enable_torque(motor_id, True)  # Enable torque so the motor can move

    while True:
        try:
            # Get target angle from user input and keep it in [0, 360) range
            angle = float(input("Enter target angle (0-360°): ")) % 360

            # Convert angle in degrees to encoder counts
            target = angle * (CPR / 360)

            # Send position command to the motor
            master.set_position(motor_id, target)

            # Wait for movement to complete
            time.sleep(0.5)

            # Read actual encoder position
            current = master.get_position(motor_id)

            # Convert encoder counts back to degrees
            actual = current * (360 / CPR)

            # Print both target and actual angles
            print(f"Target: {angle:.2f}°, Actual: {actual:.2f}°\n")

        except KeyboardInterrupt:
            # On user interrupt (Ctrl+C), disable torque and stop the motor
            master.enable_torque(motor_id, False)
            break

# Entry point of the script
if __name__ == "__main__":
    main()
```

{% endcode %}
{% endtab %}

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

```cpp
#include <Acrome-SMD.h>
#define BAUDRATE 115200         // Serial communication speed
#define CPR 6533                // Counts per revolution of the encoder
#define ID 1                    // ID of the SMD Red module

Red master(ID, Serial, BAUDRATE);  // Create SMD Red object

void setup() {
  Serial.begin(115200);             // Start serial monitor
  master.begin();                   // Initialize communication with SMD Red
  master.torqueEnable(1);          // Enable motor torque
  master.setOperationMode(PositionControl);  // Set operation mode to Position Control
}

void loop() {
  // Read joystick X and Y values from module 1
  int joystickX = master.getJoystickX(1);
  int joystickY = master.getJoystickY(1);

  // If joystick is moved beyond dead zone
  if (abs(joystickX) > 10 || abs(joystickY) > 10) {
    // Calculate angle based on joystick direction
    float angle = atan2(joystickY / 100.0, joystickX / 100.0);
    float angleDegrees = fmod(degrees(angle) + 360.0, 360.0);  // Normalize angle to 0–360°
    
    // Convert angle in degrees to encoder position (CPR)
    int position = angleDegrees * (CPR / 360.0);

    master.setpoint(1, position);  // Send position command to motor

    // Debug output
    Serial.print("Target Angle: "); Serial.println(angleDegrees);
    Serial.print("Target CPR: "); Serial.println(position);
  }

  delay(100);  // Small delay for stability
}
```

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


# Basic Motor Torque Control Application

In this application, you will learn how to control the **torque (current)** of a brushed DC motor using the **Torque Mode** of the SMD Red module. You will input a torque value between `-100` and `100`, and observe the motor’s response. This control mode is particularly useful for applications that require **force feedback**, **current-limited motion**, or **haptic interaction**.

**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](https://docs.acrome.net/electronics/gateway-modules/arduino-gateway-module) ([Purchase Here](https://www.robotshop.com/products/acrome-arduino-gateway-shield-module-acrome-smd-products))

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

## **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. [SMD Red](/electronics/smd-red): Drives the DC motor and manages current control via internal PID loop.
2. [BDC Motor](/electronics/electrical-motors/brushed-dc-motors-bdc): Converts electrical energy into mechanical torque.

#### **Project Key Features**

1. Real-time torque input via command line
2. Bidirectional torque control (±100)
3. Live current measurement feedback
4. PID-based torque regulation

## **Step 2: Assemble** <a href="#step-2-assemble" id="step-2-assemble"></a>

#### **Getting Started**

**Hardware Setup**

* Connect the SMD to the PC or Arduino board using [USB Gateway Module](https://acrome.gitbook.io/acrome-smd-docs/electronics/gateway-modules/usb-gateway-module) or [Arduino Gateway Module](https://acrome.gitbook.io/acrome-smd-docs/electronics/gateway-modules/arduino-gateway-module).
* Connect the 100 RPM [BDC Motor](https://docs.acrome.net/electronics/electrical-motors/brushed-dc-motors-bdc) with Encoder to the motor ports of the SMD Red.
* Make sure that the SMD is powered and all connections are correct.

#### **Project Wiring Diagram**

<figure><img src="/files/1bc65n9gm1iZlqh9GDn8" alt=""><figcaption></figcaption></figure>

## Step 3: Run & Test <a href="#step-3-run-and-test" id="step-3-run-and-test"></a>

#### Run the Script

You will be prompted to enter a torque value in the range of `-100` to `100`.\
The motor will apply the specified current, and the system will print both the target and actual measured torque.

## Codes

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

```python
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()
```

{% endcode %}
{% endtab %}

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

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

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


# Motor Rotation Based on Joystick  Counting

This Python code demonstrates a joystick-controlled motor rotation system that enables a user to count joystick inputs and control the motor's rotations accordingly. The application uses a **USB-connected motor controller** to read joystick inputs and perform precise motor movements based on the input count. Below is a step-by-step explanation of the code.

**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))

[Joystick Module](https://docs.acrome.net/electronics/add-on-modules/joystick-module) ([Purchase Here](https://www.robotshop.com/products/acrome-joystick-2-axis-add-on-module-acrome-smd-products))

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

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

**Key Components:**

1. [ACROME SMD](https://docs.acrome.net/electronics/smd-red)\
   The [ACROME SMD](https://docs.acrome.net/electronics/smd-red) acts as the communication hub between the [Joystick Module](https://docs.acrome.net/electronics/add-on-modules/joystick-module) and the computer. It collects [Joystick Module](https://docs.acrome.net/electronics/add-on-modules/joystick-module) data, processes user input, and translates it into mouse movements and clicks.
2. [Joystick Module](https://docs.acrome.net/electronics/add-on-modules/joystick-module)\
   The [Joystick Module](https://docs.acrome.net/electronics/add-on-modules/joystick-module) serves as the main input device. The user can move the [Joystick Module](https://docs.acrome.net/electronics/add-on-modules/joystick-module) to control the mouse pointer’s X and Y coordinates on the screen. Additionally, the [Joystick Module](https://docs.acrome.net/electronics/add-on-modules/joystick-module) button can be used to trigger mouse clicks.
3. [BDC Motor](https://docs.acrome.net/electronics/electrical-motors/brushed-dc-motors-bdc) \
   &#x20;The motor is controlled using velocity commands, allowing for smooth acceleration and deceleration.

#### **Project Features:**

* **Button Press Detection**: Reads the joystick button state from the motor controller.
* **Entering Counting Mode**: Holding the button for 5 seconds activates counting mode.
* **Incrementing the Counter**: In counting mode, pressing and releasing the button increases the counter.
* **Triggering Motor Rotation**: Holding the button for another 5 seconds rotates the motor according to the counter value.

## **Step 2: Assemble** <a href="#step-2-assemble" id="step-2-assemble"></a>

**Getting Started**

1. **Hardware Setup**
   * Connect the SMD to the PC or Arduino board using [USB Gateway Module](https://docs.acrome.net/electronics/gateway-modules/usb-gateway-module) .
   * Connect the [BDC Motor](https://docs.acrome.net/electronics/electrical-motors/brushed-dc-motors-bdc)  and the [Joystick Module](https://docs.acrome.net/electronics/add-on-modules/joystick-module) to 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 Joystick Counting project.

• The script will automatically detect the USB port and establish communication with the SMD Master Controller.

• Move the joystick to control the motor’s rotation and observe the response.

#### Experience Joystick-Based Motor Control

• Move the joystick forward to rotate the motor clockwise (CW).

• Move the joystick backward to rotate the motor counterclockwise (CCW).

• Return the joystick to the center position to stop the motor.

• Observe how the motor speed and direction change dynamically based on joystick movement.

## Codes

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

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

# Detect USB Port
def detect_usb_port():
    ports = list(comports())
    usb_names = {
        "Windows": ["USB Serial Port"],
        "Linux": ["/dev/ttyUSB"],
        "Darwin": ["/dev/tty.usbserial", "/dev/tty.usbmodem", "/dev/cu.usbserial"]
    }
    os_name = system()
    for port in ports:
        if any(name in port.device or name in port.description for name in usb_names.get(os_name, [])):
            return port.device
    return None

# Initialize SMD Red Connection
serial_port = detect_usb_port()
if not serial_port:
    print("No compatible USB port found.")
    exit(1)

master = Master(serial_port)
motor_id = 0
joystick_id = 5  # Joystick module ID

master.attach(Red(motor_id))
master.set_operation_mode(motor_id, 0)  # Set motor to PWM mode
master.enable_torque(motor_id, True)

# Control Motor with Joystick
def control_motor():
    while True:
        joystick_data = master.get_joystick(motor_id, joystick_id)
        if joystick_data is None:
            print("Joystick data could not be read.")
            time.sleep(0.1)
            continue

        x_axis, y_axis = joystick_data[0], joystick_data[1]

        # Convert joystick Y-axis input to PWM signal
        speed = int(abs(y_axis) * 100 / 100)  
        if y_axis > 0:
            master.set_duty_cycle(motor_id, speed)   # Move forward
        elif y_axis < 0:
            master.set_duty_cycle(motor_id, -speed)  # Move backward
        else:
            master.set_duty_cycle(motor_id, 0)       # Stop

        print(f"Joystick: X={x_axis}, Y={y_axis} | PWM: {speed}")
        time.sleep(0.05)

# Start Motor Control
control_motor()
```

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


# Morse Code Transmitter

The Morse Code Transmitter turns the basic “blinking light” demonstration into a desktop app that transmits Morse code. Using an RGB LED module and a Buzzer module driven by an SMD Red, the project converts any text you type into audible + visual Morse code. A simple Tkinter GUI lets you enter the text, follow progress on a bar, and see the exact “dot-dash” string before you send it. All this feedback and these features help the user to understand Morse code better.

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) ([Purchase Here](https://www.robotshop.com/products/acrome-arduino-gateway-shield-module-acrome-smd-products))

[RGB LED Module](/electronics/add-on-modules/rgb-led-module) ([Purchase Here](https://www.robotshop.com/products/acrome-rgb-led-add-on-module-acrome-smd-products))

[Buzzer Module](/electronics/add-on-modules/buzzer-module) ([Purchase Here](https://www.robotshop.com/products/acrome-buzzer-sound-add-on-module-acrome-smd-products))

## Step 1: Hardware and Software Overview

1. [SMD Red](/electronics/smd-red)\
   The SMD acts as a bridge between the script and the modules. It is responsible for interpreting the commands the script sends and translating them into actions that actuate the [RGB LED Module](https://docs.acrome.net/electronics/add-on-modules/rgb-led-module) and the[ Buzzer Module](https://docs.acrome.net/electronics/add-on-modules/buzzer-module).&#x20;
2. [RGB LED Module](/electronics/add-on-modules/rgb-led-module)\
   Flashes white light for each dot or dash so you can “see” the code in real time. Long flashes for dashes and short flashes for dots.
3. [Buzzer Module](/electronics/add-on-modules/buzzer-module)\
   Generating short and long beeps that match the LED flashes adds an audible feedback to the user. This feedback helps the user follow along with the Morse code while reading it.
4. SMD Libraries\
   The official Acrome SMD Python library handles low-level serial communication, device scanning, and module control, letting you focus on the Morse logic and GUI.

## Project Key Features

* Visual + Audible Morse Output

Every symbol is simultaneously flashed and beeped for clear feedback.

* Real-time Progress Indicator

A GUI progress bar moves from 0% to 100% as the message transmits.

* Dot-dash Visualization

The dots and dashes get visualized in the Tkinter UI.&#x20;

* Adjustable Timing

Modify the DOT\_DURATION constant to speed up or slow down transmission of the Morse code.

## Step 2: Assemble

Getting Started

1. Hardware Setup

* Connect the SMD to the PC or Arduino board using[ the USB Gateway Module](https://acrome.gitbook.io/acrome-smd-docs/electronics/gateway-modules/usb-gateway-module) or[ the Arduino Gateway Module](https://acrome.gitbook.io/acrome-smd-docs/electronics/gateway-modules/arduino-gateway-module).
* Connect the[ ](https://docs.acrome.net/electronics/add-on-modules/button-module)[RGB LED Module](https://docs.acrome.net/electronics/add-on-modules/rgb-led-module) and the[ Buzzer Module](https://docs.acrome.net/electronics/add-on-modules/buzzer-module) 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="https://lh7-qw.googleusercontent.com/docsz/AD_4nXeKo7CaD9wJd6goSE_LJO7p4zdfPDd7q63Cxa3P-7WOQgwWI6DDZVefzWST5FT93nk8acmS_P_htExJvgqMRtR_AHupgl0nURVX9s0AgDVg18TEy4y0y02ZtqKxogk0guH88r3qqA?key=mFTQQ0XjEt2gxdoCYIMrQA" alt=""><figcaption></figcaption></figure>

## Step 3: Run & Test

1. Install Libraries and Run the Script

* Install necessary libraries such as Tkinter, serial, and acrome-smd.
* Execute the script, initiating the Morse Code Transmitter project and opening the Tkinter UI where you can enter your text.

2. Experience the Morse Transmission

* Observe the synchronized light and sound for each dot and dash.
* Write longer texts to experience longer Morse transmissions.

3. Customize and Experiment

* Experiment with changing symbol timings to create “fast” or “slow” Morse.
* Explore switching LED colors

## Codes

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

```python
import os, sys
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))


import time
import threading
import tkinter as tk
from tkinter import ttk, messagebox
from serial.tools.list_ports import comports
from platform import system
from smd.red import Master, Red


# Morse-code timing
DOT_DURATION   = 0.2
DASH_DURATION  = DOT_DURATION * 3
SYMBOL_PAUSE   = DOT_DURATION
LETTER_PAUSE   = DOT_DURATION * 3
WORD_PAUSE     = DOT_DURATION * 7


# Morse lookup
def build_morse_map():
   return {
       'A': '.-', 'B': '-...', 'C': '-.-.', 'D': '-..', 'E': '.',
       'F': '..-.', 'G': '--.', 'H': '....', 'I': '..', 'J': '.---',
       'K': '-.-', 'L': '.-..', 'M': '--', 'N': '-.', 'O': '---',
       'P': '.--.', 'Q': '--.-', 'R': '.-.', 'S': '...', 'T': '-',
       'U': '..-', 'V': '...-', 'W': '.--', 'X': '-..-', 'Y': '-.--',
       'Z': '--..',
       '0': '-----', '1': '.----', '2': '..---', '3': '...--', '4': '....-',
       '5': '.....', '6': '-....', '7': '--...', '8': '---..', '9': '----.'
   }
MORSE_CODE = build_morse_map()


# Hardware layer
def find_usb_port():
   ports = list(comports())
   os_name = system()
   usb_names = {
       "Windows": ["USB Serial Port"],
       "Linux": ["/dev/ttyUSB"],
       "Darwin": ["/dev/tty.usbserial", "/dev/tty.usbmodem", "/dev/cu.usbserial"]
   }
   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
   return None


class MorseHardware:
   def __init__(self, port, baud=115200, smd_id=0, led_id=5, buzzer_id=5):
       self.master = Master(port, baud)
       self.master.attach(Red(smd_id))
       self.master.scan_modules(smd_id)
       self.smd_id = smd_id
       self.led_id = led_id
       self.buzzer_id = buzzer_id


   def led_on(self):
       self.master.set_rgb(self.smd_id, self.led_id, 255, 255, 255)


   def led_off(self):
       self.master.set_rgb(self.smd_id, self.led_id, 0, 0, 0)


   def beep(self, dur):
       # dur in seconds
       ms = int(dur * 1000)
       # Start beep
       self.master.set_buzzer(self.smd_id, self.buzzer_id, ms)
       time.sleep(dur)
       # Stop beep
       self.master.set_buzzer(self.smd_id, self.buzzer_id, 0)


   def close(self):
       ser = getattr(self.master, 'serial', None)
       if ser and hasattr(ser, 'close'):
           ser.close()


# Morse logic
def transmit_symbol(symbol, hw):
   dur = DOT_DURATION if symbol == '.' else DASH_DURATION
   hw.led_on()
   hw.beep(dur)
   hw.led_off()
   time.sleep(SYMBOL_PAUSE)


def transmit_message(msg, hw, on_progress=None):
   cleaned = msg.strip().upper()
   symbols = [sym for ch in cleaned if ch != ' ' for sym in MORSE_CODE.get(ch, '')]
   total = len(symbols)
   count = 0
   for word in cleaned.split():
       for ch in word:
           for sym in MORSE_CODE.get(ch, ''):
               transmit_symbol(sym, hw)
               count += 1
               if on_progress and total:
                   on_progress(int(count / total * 100))
           time.sleep(LETTER_PAUSE - SYMBOL_PAUSE)
       time.sleep(WORD_PAUSE - LETTER_PAUSE)
   if on_progress:
       on_progress(100)


# GUI
def to_morse_string(msg):
   words = []
   for word in msg.strip().upper().split():
       letters = [MORSE_CODE.get(ch, '') for ch in word]
       words.append(' '.join(filter(None, letters)))
   return ' / '.join(words)


class MorseGUI(tk.Tk):
   def __init__(self):
       super().__init__()
       self.title("Morse Code Transmitter")
       self.resizable(False, False)


       port = find_usb_port()
       if not port:
           messagebox.showerror("Error", "No USB gateway detected.")
           self.destroy()
           sys.exit(1)
       self.hw = MorseHardware(port)


       ttk.Label(self, text="Enter message:").grid(row=0, column=0, padx=8, pady=(10, 2), sticky="w")
       self.msg_var = tk.StringVar()
       entry = ttk.Entry(self, textvariable=self.msg_var, width=42)
       entry.grid(row=1, column=0, columnspan=2, padx=8, sticky="ew")
       entry.focus()
       self.msg_var.trace_add("write", self._update_code)


       ttk.Label(self, text="Morse code:").grid(row=2, column=0, padx=8, pady=(6, 2), sticky="w")
       self.code_lbl = tk.Label(self, text="", font=("Courier", 10), justify="left", wraplength=300)
       self.code_lbl.grid(row=3, column=0, columnspan=2, padx=8, sticky="w")


       self.tx_btn = ttk.Button(self, text="Transmit", command=self._start)
       self.tx_btn.grid(row=4, column=0, padx=8, pady=10, sticky="e")
       self.progress = ttk.Progressbar(self, mode="determinate", length=200)
       self.progress.grid(row=4, column=1, padx=(0, 8), pady=10, sticky="w")
       self.protocol("WM_DELETE_WINDOW", self._on_close)


   def _update_code(self, *_):
       self.code_lbl.config(text=to_morse_string(self.msg_var.get()))


   def _start(self):
       msg = self.msg_var.get().strip()
       if not msg:
           messagebox.showinfo("Input", "Enter a message.")
           return
       self.tx_btn.state(["disabled"])
       self.progress["value"] = 0
       threading.Thread(target=self._worker, args=(msg,), daemon=True).start()


   def _worker(self, msg):
       try:
           transmit_message(msg, self.hw, self._prog)
       except Exception as e:
           messagebox.showerror("Error", str(e))
       finally:
           self.tx_btn.state(["!disabled"])
           self.progress["value"] = 0


   def _prog(self, p):
       self.progress["value"] = p


   def _on_close(self):
       self.hw.close()
       self.destroy()


if __name__ == '__main__':
   MorseGUI().mainloop()
```

{% endcode %}
{% endtab %}

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

```cpp
#include <Acrome-SMD.h>
#include <ctype.h>          // toupper()


#define SMD_ID       0      // master ID on the SMD bus
#define BAUDRATE     115200 // USB (and Serial Monitor) baud
#define LED_ID       5      // port number of RGB LED Module
#define BUZZER_ID    5      // port number of Buzzer Module


Red master(SMD_ID, Serial, BAUDRATE);


/* ---------- Morse-code timing (milliseconds) ---------- */
const uint16_t DOT_DURATION   = 200;
const uint16_t DASH_DURATION  = DOT_DURATION * 3;
const uint16_t SYMBOL_PAUSE   = DOT_DURATION;
const uint16_t LETTER_PAUSE   = DOT_DURATION * 3;
const uint16_t WORD_PAUSE     = DOT_DURATION * 7;


/* ---------- Lookup table: A–Z, 0–9 ---------- */
struct MorsePair { char ch; const char *code; };
const MorsePair MORSE_TABLE[] PROGMEM = {
 { 'A', ".-"   }, { 'B', "-..." }, { 'C', "-.-." }, { 'D', "-.."  }, { 'E', "."    },
 { 'F', "..-." }, { 'G', "--."  }, { 'H', "...." }, { 'I', ".."   }, { 'J', ".---" },
 { 'K', "-.-"  }, { 'L', ".-.." }, { 'M', "--"   }, { 'N', "-."   }, { 'O', "---"  },
 { 'P', ".--." }, { 'Q', "--.-" }, { 'R', ".-."  }, { 'S', "..."  }, { 'T', "-"    },
 { 'U', "..-"  }, { 'V', "...-" }, { 'W', ".--"  }, { 'X', "-..-" }, { 'Y', "-.--" },
 { 'Z', "--.." },
 { '0', "-----"}, { '1', ".----"}, { '2', "..---"}, { '3', "...--"}, { '4', "....-"},
 { '5', "....."}, { '6', "-...."}, { '7', "--..."}, { '8', "---.."}, { '9', "----."}
};
const uint8_t TABLE_LEN = sizeof(MORSE_TABLE) / sizeof(MORSE_TABLE[0]);


/* Look up a character – returns nullptr if unsupported */
const char* morseLookup(char c) {
 c = toupper(c);
 for (uint8_t i = 0; i < TABLE_LEN; ++i) {
   if (pgm_read_byte(&MORSE_TABLE[i].ch) == c)
     return (const char*)pgm_read_word(&MORSE_TABLE[i].code);
 }
 return nullptr;
}


/* ---------- Low-level helpers ---------- */
void ledOn()  { master.setRGB(LED_ID, 255, 255, 255); }
void ledOff() { master.setRGB(LED_ID, 0, 0, 0); }


void beep(uint16_t durMs) {
 master.setBuzzer(BUZZER_ID, durMs);   // buzzer auto-stops after durMs
 delay(durMs);
}


void transmitSymbol(char sym) {
 uint16_t dur = (sym == '.') ? DOT_DURATION : DASH_DURATION;
 ledOn();
 beep(dur);
 ledOff();
 delay(SYMBOL_PAUSE);
}


/* ---------- Transmit an entire message ---------- */
void transmitMessage(const char *msg) {
 while (*msg) {
   char c = *msg++;
   if (c == ' ') {                       // space → word gap
     delay(WORD_PAUSE - LETTER_PAUSE);
     continue;
   }
   const char *pattern = morseLookup(c);
   if (!pattern) continue;               // skip unsupported chars
   while (*pattern) {
     transmitSymbol(*pattern++);
   }
   delay(LETTER_PAUSE - SYMBOL_PAUSE);   // gap between letters
 }
}


/* ---------- Setup & Main Loop ---------- */
void setup() {
 Serial.begin(BAUDRATE);
 while (!Serial) ;                       // wait for PC


 master.begin();
 master.scanModules();
 Serial.println(F("=== SMD Morse Code Transmitter ==="));
 Serial.println(F("Type a line of text and press ENTER.\n"));
}


String line = "";


void loop() {
 // Collect one line from Serial Monitor
 while (Serial.available()) {
   char ch = Serial.read();
   if (ch == '\n' || ch == '\r') {
     if (line.length() > 0) {
       Serial.print(F("Sending: \"")); Serial.print(line); Serial.println('"');
       transmitMessage(line.c_str());
       Serial.println(F("Done.\n"));
       line = "";
     }
   } else {
     line += ch;
   }
 }
}
```

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


# Simon Says Game

A Python-based Simon Says memory game that uses an SMD Red gateway with the RGB LED Module and Buzzer Module for visual and audio feedback. The game presents an ever-growing sequence of colors that the player must repeat correctly to advance to the next round.

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) ([Purchase Here](https://www.robotshop.com/products/acrome-arduino-gateway-shield-module-acrome-smd-products))

[RGB LED Module](/electronics/add-on-modules/rgb-led-module) ([Purchase Here](https://www.robotshop.com/products/acrome-rgb-led-add-on-module-acrome-smd-products))

[Buzzer Module](/electronics/add-on-modules/buzzer-module) ([Purchase Here](https://www.robotshop.com/products/acrome-buzzer-sound-add-on-module-acrome-smd-products))

## Step 1: Hardware and Software Overview

1. [SMD Red](/electronics/smd-red)\
   The SMD acts as a bridge between the script and the modules. It is responsible for interpreting the commands the script sends and translating them into actions that actuate the [RGB LED Module](https://docs.acrome.net/electronics/add-on-modules/rgb-led-module) and the[ Buzzer Module](https://docs.acrome.net/electronics/add-on-modules/buzzer-module).
2. [RGB LED Module](/electronics/add-on-modules/rgb-led-module)\
   Depending on the game sequence, this module lights up in Red, Green, or Blue. It helps the player visually memorize the pattern.
3. [Buzzer Module](/electronics/add-on-modules/buzzer-module)\
   Emits a short beep along with the LED flash for audio feedback. This pairing enhances the user’s memory and reaction.
4. SMD Libraries\
   The official Acrome SMD Python library handles low-level serial communication, device scanning, and module control, letting you focus on the Simon Says logic and GUI.

### Project Key Features

* Visual + Audible Feedback

Each color is accompanied by a synchronized flash and beep.

* Growing Memory Challenge

The sequence grows with each successful round, increasing difficulty.

* Tkinter Graphical Interface

Simple UI with buttons for Red, Green, and Blue, a start button, and a status message.

* Built-in Hardware Warm-Up

The RGB LED is initialized once before gameplay to bypass any first-flash issues.

## Step 2: Assemble

Getting Started

1. Hardware Setup

* Connect the SMD to the PC or Arduino board using[ the USB Gateway Module](https://acrome.gitbook.io/acrome-smd-docs/electronics/gateway-modules/usb-gateway-module) or[ the Arduino Gateway Module](https://acrome.gitbook.io/acrome-smd-docs/electronics/gateway-modules/arduino-gateway-module).
* Connect the[ ](https://docs.acrome.net/electronics/add-on-modules/button-module)[RGB LED Module](https://docs.acrome.net/electronics/add-on-modules/rgb-led-module) and the[ Buzzer Module](https://docs.acrome.net/electronics/add-on-modules/buzzer-module) 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="https://lh7-qw.googleusercontent.com/docsz/AD_4nXc8NSK0FpsjsKTaIdRvCrRQHK9lphi-2JvJr4ssVgtGLe153kYozejBq_PhGojGCLlgJEujiWFi06StvgXwUQuf3ubGN69Qb6N8c8N2RxDusZDP042-rq9aMSpE37bobuqoRwJp5g?key=iN1LfuB2rKLGjoje9im4lw" alt=""><figcaption></figcaption></figure>

## Step 3: Run & Test

1. Install Libraries and Run the Script

* Install necessary libraries such as Tkinter, serial, and acrome-smd.
* Execute the script, initiating the Simon Says project and opening the Tkinter UI where you can enter your text.

2. Play the Simon Says Game

* Click Start to begin.
* Watch the color sequence.
* Repeat the sequence using the buttons.
* If correct, the game adds one more color and continues.
* If wrong, the game ends and can be restarted.

## Codes:

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

```python
import os, sys
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))


import time
import random
import tkinter as tk
from tkinter import ttk, messagebox
from serial.tools.list_ports import comports
from platform import system
from smd.red import Master, Red


# ─── Hardware Layer ───────────────────────────────────────────────────────────
def find_usb_port():
   ports = list(comports())
   os_name = system()
   usb_names = {
       "Windows": ["USB Serial Port"],
       "Linux": ["/dev/ttyUSB"],
       "Darwin": ["/dev/tty.usbserial", "/dev/tty.usbmodem", "/dev/cu.usbserial"]
   }
   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
   return None


class Device:
   def __init__(self, port, baud=115200, smd_id=0, led_id=5, buzzer_id=5):
       self.master = Master(port, baud)
       self.master.attach(Red(smd_id))
       self.master.scan_modules(smd_id)
       self.smd_id = smd_id
       self.led_id = led_id
       self.buzzer_id = buzzer_id


   def led_color(self, r, g, b):
       self.master.set_rgb(self.smd_id, self.led_id, r, g, b)


   def led_off(self):
       self.led_color(0, 0, 0)


   def beep(self, duration=0.2):
       ms = int(duration * 1000)
       self.master.set_buzzer(self.smd_id, self.buzzer_id, ms)
       time.sleep(duration)
       self.master.set_buzzer(self.smd_id, self.buzzer_id, 0)


   def close(self):
       ser = getattr(self.master, 'serial', None)
       if ser and hasattr(ser, 'close'):
           ser.close()


# ─── Simon Says GUI ────────────────────────────────────────────────────────────
COLORS = [
   ("Red",   (255, 0,   0)),
   ("Green", (0,   255, 0)),
   ("Blue",  (0,   0,   255))
]


class SimonSaysApp(tk.Tk):
   def __init__(self, device):
       super().__init__()
       self.title("Simon Says Game")
       self.resizable(False, False)
       self.device = device


       self.sequence = []
       self.user_index = 0
      
       self.device.led_color(*COLORS[0][1])
       self.device.beep(0.8)
       self.device.led_off()
       time.sleep(1.0)
      
       self._build_ui()
      


   def _build_ui(self):
       btn_frame = ttk.Frame(self)
       btn_frame.pack(pady=10)


       self.buttons = []
       for i, (name, color) in enumerate(COLORS):
           hexc = "#%02x%02x%02x" % color
           btn = tk.Button(btn_frame, text=name, bg=hexc, width=8,
                           command=lambda i=i: self._user_press(i))
           btn.grid(row=0, column=i, padx=5)
           self.buttons.append((btn, color))


       control = ttk.Frame(self)
       control.pack(pady=5)


       self.status = ttk.Label(self, text="Press Start to play")
       self.status.pack(pady=(0,5))


       self.start_btn = ttk.Button(control, text="Start", command=self._start_game)
       self.start_btn.pack()


   def _start_game(self):
       self.sequence.clear()
       self._next_round()


   def _next_round(self):
       self.start_btn.config(state="disabled")
       self.user_index = 0
       self.sequence.append(random.randrange(len(COLORS)))
       self.status.config(text=f"Round {len(self.sequence)} – watch...")
       # schedule playback on main thread
       self.after(500, self._play_sequence, 0)


   def _play_sequence(self, idx):
       if idx < len(self.sequence):
           color_idx = self.sequence[idx]
           self._flash(color_idx)
           # schedule next flash
           self.after(700, self._play_sequence, idx+1)
       else:
           self.status.config(text="Your turn")


   def _flash(self, idx):
       _, color = self.buttons[idx]
       self.device.led_color(*color)
       self.device.beep(0.2)
       # turn off after short delay
       self.after(200, self.device.led_off)


   def _user_press(self, idx):
       if not self.sequence:
           return
       self._flash(idx)
       if idx == self.sequence[self.user_index]:
           self.user_index += 1
           if self.user_index == len(self.sequence):
               # correct full sequence
               self.status.config(text="Correct! Next round...")
               self.after(500, self._next_round)
       else:
           self.status.config(text="Wrong! Game Over")
           self.start_btn.config(state="enabled")
           self.sequence.clear()


# ─── Main ─────────────────────────────────────────────────────────────────────
if __name__ == '__main__':
   port = find_usb_port()
   if not port:
       print("No USB gateway detected.")
       sys.exit(1)


   device = Device(port)
   app = SimonSaysApp(device)
   app.protocol("WM_DELETE_WINDOW", lambda: (device.close(), app.destroy()))
   app.mainloop()
```

{% endcode %}
{% endtab %}

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

```cpp
#include <AcromeSMD.h>  // You need Acrome's Arduino SMD library


#define SMD_ID 0
#define LED_ID 5
#define BUZZER_ID 5


// Setup SMD and modules
SMDRed smd;
uint8_t sequence[100];
uint8_t userIndex = 0;
uint8_t currentLength = 0;
bool userTurn = false;




const uint8_t COLORS[3][3] = {
  {255, 0, 0},  // Red
  {0, 255, 0},  // Green
  {0, 0, 255}   // Blue
};


// Button pins (connect external buttons to these digital pins)
const int buttonPins[3] = {2, 3, 4};


void setup() {
  Serial.begin(115200);
  smd.begin();


  smd.attachModule(SMD_ID, LED_ID, RGB);
  smd.attachModule(SMD_ID, BUZZER_ID, BUZZER);


  for (int i = 0; i < 3; i++) {
    pinMode(buttonPins[i], INPUT_PULLUP);
  }


  // Hardware init blink + beep
  flashColor(0, 300);
  delay(1000);
  
  startNewGame();
}


void loop() {
  if (userTurn) {
    for (int i = 0; i < 3; i++) {
      if (digitalRead(buttonPins[i]) == LOW) {
        delay(200); // debounce
        
        flashColor(i, 200);
        if (i == sequence[userIndex]) {
          userIndex++;
          if (userIndex == currentLength) {
            Serial.println("Correct! Next round...");
            delay(500);
            nextRound();
          }
        } else {
          Serial.println("Wrong! Game Over.");
          delay(1000);
          startNewGame();
        }
      }
    }
  }
}


void startNewGame() {
  currentLength = 0;
  userIndex = 0;
  nextRound();
}


void nextRound() {
  if (currentLength < sizeof(sequence)) {
    sequence[currentLength] = random(0, 3);
    currentLength++;
    playSequence();
    userIndex = 0;
    userTurn = true;
  }
}


void playSequence() {
  userTurn = false;
  Serial.print("Round ");
  Serial.println(currentLength);
  delay(500);
  for (int i = 0; i < currentLength; i++) {
    flashColor(sequence[i], 200);
    delay(500);
  }
}


void flashColor(uint8_t colorIndex, uint16_t duration) {
  smd.setRGB(SMD_ID, LED_ID, COLORS[colorIndex][0], COLORS[colorIndex][1], COLORS[colorIndex][2]);
  smd.setBuzzer(SMD_ID, BUZZER_ID, duration);
  delay(duration);
  smd.setRGB(SMD_ID, LED_ID, 0, 0, 0);
}
```

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


# Robotics

Advanced Robotics & AI Solutions

The Robotics section is designed for advanced users interested in tackling complex robotics challenges and AI-driven automation. These projects focus on topics such as autonomous navigation, object detection, intelligent motion planning, and real-world robotics applications using SMD modules.

By working through these projects, users will gain experience in designing and implementing robotic systems that leverage modern automation techniques. This section is particularly beneficial for students, researchers, and professionals looking to explore cutting-edge robotics technologies and integrate them into sophisticated projects.


# Differential Robot Projects

The **Differential Robot Project** is a hands-on application of the **Acrome Motion Kit**, designed to introduce students, researchers, and robotics enthusiasts to **differential drive systems, motion control, and autonomous navigation**.

With this kit, users can build and program a **differential-drive mobile robot**, enabling real-time **motion planning, obstacle avoidance, and sensor integration**. It serves as an ideal platform for **robotics education, AI research, and industrial automation prototyping**.

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

## **What is a Differential Drive Robot?**

A **differential drive robot** is a type of wheeled robot that moves by controlling the speed of two independent motors. This movement mechanism allows for:

**Straight Motion** – Both wheels move at the same speed.\
**Turning** – One wheel moves faster than the other.\
**Rotation in Place** – The wheels rotate in opposite directions.

This simple yet powerful design is commonly used in **autonomous robots, self-driving vehicles, industrial AGVs (Automated Guided Vehicles), and AI-based navigation systems**.

## **Control & Programming Methods**

The **Differential Drive Robot** supports multiple control and programming methods, making it adaptable for users with different skill levels:

#### **1. Blockly UI (No-Code, Drag & Drop Programming)**

* Ideal for beginners and classroom learning.
* Allows users to **control motors, read sensor data, and implement logic** without coding.
* Example Blockly command: **Move Forward at 50% Speed**.

#### **2. Python API (Advanced Control)**

* Offers detailed control over **motor speed, sensor feedback, and real-time decision-making**.
* Supports **PID control** and adaptive movement strategies.
* Example Python script:

```python
set_motor_speed(left_motor=50, right_motor=50)  # Move forward
```

```python
distance = get_distance()
if distance < 15:
    stop_motors()  # Stop if an obstacle is detected
```

#### **3. Mobile App Control (Flutter-Based)**

* Enables **wireless remote control** through a smartphone or tablet.
* Uses **Bluetooth or Wi-Fi** for connectivity.

## **Real-World Applications of Differential Robots**

Differential drive robots are used in a variety of real-world applications, including:

**Autonomous Vehicles** – Found in **self-driving cars and delivery robots**.\
**Industrial Automation** – Used in **factories, warehouses, and AGVs**.\
**AI & Machine Learning** – Research in **reinforcement learning and path optimization**.\
**STEM Education & Competitions** – Helps students **develop robotics and programming skills**.

## Example Projects:

* [**Braitenberg Robot**](/smd-applications/robotics/braitenberg-robot)**:**\
  A reactive robot that simulates behavior based on sensory input, demonstrating simple bio-inspired logic.
* [**Line-Follower Robot**](/smd-applications/robotics/line-follower-robot)**:**\
  Uses infrared sensors to detect and follow lines autonomously, ideal for teaching basic PID control.
* [**Object Tracking Robot**](/ai/object-tracking-robot)**:**\
  Employs vision or distance sensors to follow or avoid dynamic targets.
* [**Teleoperation Robot**](/smd-applications/robotics/teleoperation-robot)**:**\
  Remotely controlled via mobile app or interface, perfect for exploring wireless control and safety limits.
* [**Obstacle Avoidance Robot**](/smd-applications/robotics/obstacle-avoidance-robot)**:**\
  Utilizes a pan-tilt ultrasonic sensor system to actively scan the environment and avoid obstacles in real time, offering a hands-on introduction to autonomous navigation and sensor fusion.




---

[Next Page](/llms-full.txt/1)

