RS485 Adapter
RS485 Adapter hardware 1.1
This is a 3-in-1 UART to RS485 converter. Can be used as a Raspberry Pi Hat, can connect to Arduino, and can connect to a computer via USB. It contains a CP2102N chip.
Other hardware versions: 1.2 — the version is printed on the board next to the QR code.
Start here
Let your coding agent write it
Almost everyone writes code with an AI agent now, and we think that is the future. So we made it the easy path: copy the prompt below into Claude Code, Codex, Cursor, Gemini CLI or whatever you use, then describe what you want to build. Your agent will know exactly where every command, unit, wiring detail and error code for this motor lives, so it looks them up instead of guessing. Happy vibe coding.
I am writing code to control a Gearotons RS485 Adapter (product code RS1, hardware version 1.1).
This is a 3-in-1 UART to RS485 converter. Can be used as a Raspberry Pi Hat, can connect to Arduino, and can connect to a computer via USB. It contains a CP2102N chip.
All of the official documentation is machine-readable. Read what you need from these before writing any code:
- https://9o.at/products/rs1/1.1.md
This product: what it is, the datasheet, the schematic, every firmware release and how to flash one.
- https://9o.at/docs/python.md
The complete Python API: every command with its arguments and units, wiring, working examples, and every error code with its causes and fixes.
- https://9o.at/docs/arduino.md
The same reference for the Arduino library.
- https://9o.at/llms.txt
An index of everything else, including the other Gearotons products.
Use only commands, units and error codes that appear in those documents. If something I ask for is not covered there, tell me instead of guessing.
Here is what I want to build:Nothing to install and no account: the documentation is plain Markdown at a stable address. Point an agent straight at it if you prefer — this product, Python, Arduino, everything. Want the agent to drive a real motor while it works? Add the MCP server →
Schematic
Open the PDF in a new tab ↗ · Download · Click the drawing, then scroll to zoom and drag to pan. Full screen for reading part numbers.
Loading the schematic viewer…
Firmware
No firmware files are published for this hardware version.
Get coding
Python
pip install servomotor#!/usr/bin/env python3
"""
Minimal trapezoid move: rotate 1 turn in 1 second.
Edit ALIAS below if needed. Uses rotations and seconds.
"""
import time, servomotor
from servomotor import communication
# Hard-coded settings for a minimal demo
ALIAS = 'X' # Device alias, change if needed
SERIAL_PORT = "/dev/tty.usbserial-110" # Serial device path; change if needed (e.g., "COM3" on
# Windows)
DISPLACEMENT_ROTATIONS = 1.0 # 1 rotation
DURATION_SECONDS = 1.0 # 1 second
DELAY_MARGIN = 0.10 # +10% wait margin because the motor's clock is not
# perfectly accurate
communication.serial_port = SERIAL_PORT # if you comment this out then the program
# should prompt you for the serial port or it will use
# the last used port from a file
servomotor.open_serial_port()
m = servomotor.M3(ALIAS, time_unit="seconds", position_unit="shaft_rotations", verbose=0)
m.enable_mosfets()
m.trapezoid_move(DISPLACEMENT_ROTATIONS, DURATION_SECONDS)
time.sleep(DURATION_SECONDS * (1.0 + DELAY_MARGIN))
m.disable_mosfets()
servomotor.close_serial_port()Arduino
Library Manager → search Servomotor → Install.
// Minimal Arduino example: Trapezoid move using built-in unit conversions
// Goal: spin the motor exactly 1 rotation in 1 second, then stop.
// Sequence:
// system reset -> enable MOSFETs -> trapezoidMove(1.0 rotations, 1.0 seconds)
// -> wait 1.1s -> disable MOSFETs.
//
// Notes:
// - This uses the library's unit conversion (no raw counts/timesteps).
// - Configure Serial1 pins for your board (ESP32 example pins below).
// - Motor is created AFTER Serial1.begin(...) so hardware UART pins are set first.
// - Every command is checked with getError(). No command method returns a success
// flag, and a motor that has latched a fatal error silently ignores everything
// afterwards, so an unchecked sketch just stops moving with no symptom at all.
// See "Checking for errors" in the API documentation.
#include <Servomotor.h>
#define ALIAS 'X' // Device alias
#define BAUD 230400 // RS485 UART baud rate
#define DISPLACEMENT_ROTATIONS 1.0f // 1 rotation
#define DURATION_SECONDS 1.0f // 1 second
#define TOLERANCE_PERCENT 10 // +10% wait margin because the motor's clock is not
// perfectly accurate
#define WAIT_MS ((unsigned long)(DURATION_SECONDS * 1000.0f * (100 + TOLERANCE_PERCENT) / 100))
#define POST_RESET_WAIT_MS 1500 // Keep the bus SILENT this long after a reset: the motor
// boots through a bootloader window, and any packet that
// arrives during it pins the motor in the bootloader.
// Example RS485 pins for ESP32 DevKit (change as needed for your board)
#if defined(ESP32)
#define RS485_TXD 4 // TX pin to RS485 transceiver
#define RS485_RXD 5 // RX pin from RS485 transceiver
#endif
// Returns true (and explains itself) if the previous command did not succeed.
// getError() is 0 on success, positive for a fatal error reported by the motor
// (look the number up in the Error Codes section of the documentation), and
// negative for a communication failure such as -1 = no reply within 1 second.
bool failed(Servomotor &motor, const char *what) {
int e = motor.getError();
if (e == 0) return false;
Serial.print("[FAIL] ");
Serial.print(what);
Serial.print(" -> getError() = ");
Serial.print(e);
Serial.println(e > 0 ? " (motor fatal error - see the Error Codes section)"
: " (communication failure - check wiring, alias and power)");
return true;
}
void setup() {
Serial.begin(115200); // Console serial for debugging
// On ESP32-S3, set Tools > USB CDC On Boot > Enabled or this
// output never reaches the USB serial monitor.
// Create the motor; serial port opens on first instantiation.
#if defined(ESP32)
Servomotor motor(ALIAS, Serial1, RS485_RXD, RS485_TXD);
#else
Servomotor motor(ALIAS, Serial1);
#endif
// Use units: rotations for position, seconds for time.
// These are host-side only - they send nothing to the motor.
motor.setPositionUnit(PositionUnit::SHAFT_ROTATIONS);
motor.setTimeUnit(TimeUnit::SECONDS);
// Start from a known-clean state: this also clears any fatal error left over
// from a previous run, which is the usual reason a motor "stops working".
motor.systemReset();
if (failed(motor, "systemReset")) return;
delay(POST_RESET_WAIT_MS);
motor.enableMosfets();
if (failed(motor, "enableMosfets")) return;
motor.trapezoidMove(DISPLACEMENT_ROTATIONS, DURATION_SECONDS);
if (failed(motor, "trapezoidMove")) return;
delay(WAIT_MS);
// A successful move command only means the move was accepted and queued. Faults
// such as a stall or a position-deviation trip happen later, while it executes,
// so check the motor's own status once the motion should be finished.
getStatusResponse status = motor.getStatus();
if (failed(motor, "getStatus")) return;
if (status.fatalErrorCode != 0) {
Serial.print("[FAIL] motor faulted during the move, error code ");
Serial.println(status.fatalErrorCode);
return;
}
motor.disableMosfets();
if (failed(motor, "disableMosfets")) return;
Serial.println("Move completed successfully.");
}
void loop() {
}Getting started · Full Arduino reference · Library on GitHub ↗
Or just ask Claude to move it
The MCP server exposes every command to Claude Desktop, Claude Code or any MCP client, finds your serial ports and the motors on the bus, and ships with a simulator.
uvx --from servomotor-mcp servomotor-mcpSomething missing or wrong on this page? We read every message. Send feedback ↗