<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Gearotons</title>
    <description>The latest articles on DEV Community by Gearotons (@gearotons).</description>
    <link>https://dev.to/gearotons</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4118249%2F92c493b1-768e-42fa-b4f2-2259619235fc.png</url>
      <title>DEV Community: Gearotons</title>
      <link>https://dev.to/gearotons</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/gearotons"/>
    <language>en</language>
    <item>
      <title>What is an integrated servomotor? (And when you actually want one)</title>
      <dc:creator>Gearotons</dc:creator>
      <pubDate>Wed, 09 Sep 2026 22:39:46 +0000</pubDate>
      <link>https://dev.to/gearotons/what-is-an-integrated-servomotor-and-when-you-actually-want-one-3hhi</link>
      <guid>https://dev.to/gearotons/what-is-an-integrated-servomotor-and-when-you-actually-want-one-3hhi</guid>
      <description>&lt;p&gt;If you've built anything with motors, you know the standard parts pile: a stepper or BLDC, a driver board, a controller to generate steps or commands, maybe an encoder if you care whether the motor actually went where you told it, and a loom of wires connecting all of it. An &lt;strong&gt;integrated servomotor&lt;/strong&gt; collapses that pile into one part: &lt;strong&gt;motor + driver + motion controller + encoder in a single housing&lt;/strong&gt;, speaking a single cable's worth of protocol to the outside world.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F02r16e3ptkgyqjrb7cx3.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F02r16e3ptkgyqjrb7cx3.webp" alt="Gearotons M17 family: four sizes of integrated NEMA-17 servomotor" width="800" height="392"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What's actually inside
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;The motor&lt;/strong&gt;: usually a stepper in the maker/light-industrial class (steppers give high torque at low speed without a gearbox).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;An encoder&lt;/strong&gt; on the rotor, so the unit knows its true shaft position at all times.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A driver&lt;/strong&gt;: the power electronics that energize the windings.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A motion controller&lt;/strong&gt;: a microcontroller running a feedback loop between encoder and driver, accepting high-level commands ("go to 90° over 2 s") instead of step pulses.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The feedback loop is the point: this is what makes it a *servo*motor. An open-loop stepper trusts that every step happened; under a snag or a too-fast move it silently loses position. A closed-loop integrated unit measures and corrects, continuously.&lt;/p&gt;

&lt;h2&gt;
  
  
  What it replaces
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;The classic stack&lt;/th&gt;
&lt;th&gt;The integrated unit&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Motor + driver + controller + encoder, 3 vendors&lt;/td&gt;
&lt;td&gt;one part, one datasheet&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;STEP/DIR wiring per axis + encoder cabling&lt;/td&gt;
&lt;td&gt;one bus cable, daisy-chained&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Tuning current/microstepping by hand&lt;/td&gt;
&lt;td&gt;tuned at the factory for its own motor&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;"Which combination of parts failed?"&lt;/td&gt;
&lt;td&gt;one thing to swap&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The wiring difference compounds with axis count: a 6-axis machine on STEP/DIR is dozens of conductors; on a multi-drop bus (RS-485 in the M17's case) it's one twisted pair visiting each motor. Each unit gets an address; the controller talks to all of them on one port.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ffgssfqz3pivbj6r2oc19.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ffgssfqz3pivbj6r2oc19.webp" alt="Wiring: computer, USB to RS-485 adapter, two daisy-chained M17 motors, 12–24 V supply" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The honest trade-offs
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Frame-size torque ceiling.&lt;/strong&gt; Integration doesn't create torque. A NEMA-17 integrated unit is still a NEMA-17 motor (~0.3–0.65 N·m holding). If the axis needs more, you gear it or go up a frame size; don't expect the electronics to save you.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Heat shares a body.&lt;/strong&gt; Driver and motor in one housing means one thermal budget (the M17 is 25–38 W by size, IP20, indoor use; we say so on the box).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;You're trusting the vendor's firmware.&lt;/strong&gt; With a closed product, a controller quirk is a support ticket. This is the strongest argument for &lt;strong&gt;open&lt;/strong&gt; integrated servos: if the firmware is on GitHub, the failure mode is "read the code," not "wait for the vendor."&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Unit price reads higher&lt;/strong&gt; than a bare stepper, until you price the driver, encoder, controller board, wiring, and your integration hours that the bare motor still needs.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What to look for when buying one
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Loop rate&lt;/strong&gt; (how fast it corrects; the M17 runs its PID at 32 kHz)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Encoder type and resolution&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The bus&lt;/strong&gt;: multi-drop (RS-485/CAN) beats point-to-point if you'll ever add axes&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Software&lt;/strong&gt;: real libraries with units ("degrees", "seconds"), not register tables&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Openness&lt;/strong&gt;: schematics + firmware + libraries published, or a black box?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;An AI/agent story&lt;/strong&gt;, the newest differentiator: can an LLM drive it through a documented API, with the motor protecting itself in firmware? (No motor vendor we've found ships this first-party except us: the M17 comes with an &lt;a href="https://github.com/Gearotons/servomotor-mcp" rel="noopener noreferrer"&gt;MCP server&lt;/a&gt;, so Claude can run it in plain English.)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Where the M17 sits
&lt;/h2&gt;

&lt;p&gt;The M17 is our take on what this category should be: NEMA-17 integrated closed-loop servo, RS-485 daisy-chain, open hardware/firmware/software, Python and Arduino libraries, and a first-party MCP server for plain-English AI control, from $20. Where it &lt;em&gt;doesn't&lt;/em&gt; fit: axes needing more than ~0.65 N·m un-geared, wet/dusty environments (IP20), or more power than its 25–38 W (by size) rating.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://gearotons.com" rel="noopener noreferrer"&gt;See the M17 family&lt;/a&gt; · &lt;a href="https://github.com/Gearotons/servomotor-mcp/releases/download/v0.3.1/M17-claude-code-demo.mp4" rel="noopener noreferrer"&gt;Watch Claude Code drive one&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Written with the help of an AI and verified by a human. Hardware, firmware and software for the M17 are open source: &lt;a href="https://github.com/tomrodinger/servomotor" rel="noopener noreferrer"&gt;github.com/tomrodinger/servomotor&lt;/a&gt;. The MCP server: &lt;a href="https://github.com/Gearotons/servomotor-mcp" rel="noopener noreferrer"&gt;github.com/Gearotons/servomotor-mcp&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>hardware</category>
      <category>robotics</category>
      <category>motors</category>
      <category>opensource</category>
    </item>
    <item>
      <title>How to control a stepper motor from a Raspberry Pi (without babysitting STEP/DIR)</title>
      <dc:creator>Gearotons</dc:creator>
      <pubDate>Wed, 09 Sep 2026 22:35:03 +0000</pubDate>
      <link>https://dev.to/gearotons/how-to-control-a-stepper-motor-from-a-raspberry-pi-without-babysitting-stepdir-1n8g</link>
      <guid>https://dev.to/gearotons/how-to-control-a-stepper-motor-from-a-raspberry-pi-without-babysitting-stepdir-1n8g</guid>
      <description>&lt;p&gt;If you've tried to drive a stepper motor from a Raspberry Pi the traditional way, you know it's more fiddly than it should be. You wire a driver board (A4988, TMC2209) to the Pi's GPIO pins, generate STEP and DIR pulses with precise timing, fight the Pi's non-real-time scheduler for smooth motion, add an encoder if you care about lost steps, and write your own homing logic. It works, but it's a project in itself, before you've done anything &lt;em&gt;useful&lt;/em&gt; with the motion.&lt;/p&gt;

&lt;p&gt;There's a much simpler path: an &lt;strong&gt;integrated servomotor&lt;/strong&gt; that does the driving, the closed-loop control, and the motion planning &lt;em&gt;inside the motor&lt;/em&gt;, and talks to the Pi over a single serial bus. You send high-level commands ("go to 90 degrees") and read back the true position. Here's how to do it with the Gearotons &lt;a href="https://gearotons.com" rel="noopener noreferrer"&gt;M17&lt;/a&gt;, and how the same idea applies whatever integrated motor you use.&lt;/p&gt;

&lt;h2&gt;
  
  
  The two approaches, side by side
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Traditional (GPIO + driver):&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Wire STEP, DIR, ENABLE, microstep pins, motor coils, motor power.&lt;/li&gt;
&lt;li&gt;Generate step pulses in software (or with a HAT) at the right rate.&lt;/li&gt;
&lt;li&gt;No idea if the motor actually moved: open-loop, lost steps possible.&lt;/li&gt;
&lt;li&gt;Homing, acceleration curves, and multi-motor coordination are all on you.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Integrated servo over serial (the M17 way):&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;One USB-to-RS-485 adapter into the Pi; motor power from a 12–24 V supply.&lt;/li&gt;
&lt;li&gt;High-level commands over the serial bus: position, speed, homing.&lt;/li&gt;
&lt;li&gt;Closed-loop: the motor holds the commanded position and reports its real angle.&lt;/li&gt;
&lt;li&gt;Daisy-chain more motors on the &lt;em&gt;same two wires&lt;/em&gt;, each individually addressed.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The trade is cost per motor (an integrated servo costs more than a bare driver + motor) for a massive cut in integration effort and a big jump in reliability. For robot arms, plotters, lab automation, or anything you can't babysit, that trade is usually worth it.&lt;/p&gt;

&lt;h2&gt;
  
  
  What you need
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;A Raspberry Pi (any model with USB; Pi 4 / Pi 5 / Zero 2 W all fine).&lt;/li&gt;
&lt;li&gt;A Gearotons M17 servomotor.&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;USB-to-RS-485 adapter&lt;/strong&gt; (a $5–10 part; the M17 speaks RS-485 at 230400 baud).&lt;/li&gt;
&lt;li&gt;A 12–24 V DC power supply for the motor.&lt;/li&gt;
&lt;li&gt;Python 3.10+ on the Pi.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Wiring is refreshingly boring: USB adapter into the Pi, the adapter's A/B lines to the motor's RS-485 pins, motor power from your supply. No GPIO pin-counting.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ffgssfqz3pivbj6r2oc19.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ffgssfqz3pivbj6r2oc19.webp" alt="Wiring: computer, USB to RS-485 adapter, two daisy-chained M17 motors, 12–24 V supply" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Install the library
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;servomotor
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's the official Python library: it speaks the M17 protocol, handles the serial framing, and does &lt;strong&gt;automatic unit conversion&lt;/strong&gt; so you can work in degrees and seconds instead of encoder counts and timesteps.&lt;/p&gt;

&lt;h2&gt;
  
  
  Find your motor
&lt;/h2&gt;

&lt;p&gt;Each M17 has a factory-unique ID and a short &lt;strong&gt;alias&lt;/strong&gt; (a single byte, e.g. &lt;code&gt;X&lt;/code&gt;) so you can put many on one bus. First, see what's connected:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;servomotor&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;servomotor&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;communication&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;servomotor.device_detection&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;detect_devices_iteratively&lt;/span&gt;

&lt;span class="n"&gt;communication&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;serial_port&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/dev/ttyUSB0&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;   &lt;span class="c1"&gt;# your USB-RS485 adapter
&lt;/span&gt;&lt;span class="n"&gt;servomotor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;M3&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;alias_or_unique_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;         &lt;span class="c1"&gt;# 255 = broadcast
&lt;/span&gt;&lt;span class="n"&gt;servomotor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;open_serial_port&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;detect_devices_iteratively&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Found motor: unique_id=0x&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;unique_id&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;016&lt;/span&gt;&lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;, alias=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;alias&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;servomotor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;close_serial_port&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run it and you'll see each motor's unique ID and alias. (On a Pi the port is usually &lt;code&gt;/dev/ttyUSB0&lt;/code&gt;; on a Mac it's something like &lt;code&gt;/dev/cu.usbserial-XXXX&lt;/code&gt;.)&lt;/p&gt;

&lt;h2&gt;
  
  
  Move it, in six lines
&lt;/h2&gt;

&lt;p&gt;Here's a complete program that connects, enables the motor, moves to 90°, reads the position back, and returns to zero:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;servomotor&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;servomotor&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;communication&lt;/span&gt;

&lt;span class="n"&gt;communication&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;serial_port&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/dev/ttyUSB0&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="n"&gt;servomotor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;open_serial_port&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="c1"&gt;# Work in degrees and seconds; address the motor by its alias.
&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;servomotor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;M3&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;X&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;time_unit&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;seconds&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;position_unit&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;degrees&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;enable_mosfets&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;                 &lt;span class="c1"&gt;# energize the motor
&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;go_to_position&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;90&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;1.0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;          &lt;span class="c1"&gt;# absolute move to 90 deg, over 1 second
&lt;/span&gt;&lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;1.2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;position:&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get_position&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;   &lt;span class="c1"&gt;# -&amp;gt; ~90.0, measured by the encoder
&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;go_to_position&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;1.0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;           &lt;span class="c1"&gt;# back to zero
&lt;/span&gt;&lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;1.2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;disable_mosfets&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;                &lt;span class="c1"&gt;# release
&lt;/span&gt;
&lt;span class="n"&gt;servomotor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;close_serial_port&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it. No pulse timing, no DIR pins, no microstepping config. &lt;code&gt;go_to_position&lt;/code&gt; runs a smooth trapezoidal profile to the target; &lt;code&gt;get_position&lt;/code&gt; returns the &lt;em&gt;actual&lt;/em&gt; angle from the onboard encoder, not what you hoped happened. On our bench the read-back lands on the commanded angle to encoder resolution.&lt;/p&gt;

&lt;h2&gt;
  
  
  Smooth moves and relative jogs
&lt;/h2&gt;

&lt;p&gt;A couple more commands cover most real use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;trapezoid_move&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;45&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;    &lt;span class="c1"&gt;# relative: move +45 deg over 0.5 s (accel/decel)
&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;trapezoid_move&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;0.3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;   &lt;span class="c1"&gt;# nudge back 10 deg
&lt;/span&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get_status&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;        &lt;span class="c1"&gt;# health: [status_flags, fatal_error_code]
&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;homing&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;360&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;             &lt;span class="c1"&gt;# hard-stop homing: up to 360 deg of travel, 5 s max
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Because the motor is closed-loop, &lt;code&gt;get_status&lt;/code&gt; tells you if anything went wrong (it raises an error rather than silently losing steps), and &lt;code&gt;get_position&lt;/code&gt; always tells you the truth.&lt;/p&gt;

&lt;h2&gt;
  
  
  Driving several motors on one bus
&lt;/h2&gt;

&lt;p&gt;This is where serial-bus integrated motors shine on a Pi. Give each motor a different alias and address them independently, all on the same pair of wires:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;base&lt;/span&gt;     &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;servomotor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;M3&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;A&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;position_unit&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;degrees&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;time_unit&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;seconds&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;shoulder&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;servomotor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;M3&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;B&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;position_unit&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;degrees&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;time_unit&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;seconds&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;elbow&lt;/span&gt;    &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;servomotor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;M3&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;C&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;position_unit&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;degrees&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;time_unit&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;seconds&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;base&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;shoulder&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;elbow&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;enable_mosfets&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="n"&gt;base&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;go_to_position&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;1.0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;shoulder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;go_to_position&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;1.0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;elbow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;go_to_position&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;45&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;1.0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A three-axis arm on a single Pi, three lines of motion code, one cable. Wiring a GPIO driver per axis would be a far bigger build.&lt;/p&gt;

&lt;h2&gt;
  
  
  From here
&lt;/h2&gt;

&lt;p&gt;Once you can move a motor in a few lines of Python from a Pi, a lot opens up: a pen plotter, a camera slider, a small robot arm, a lab fixture. And because the M17's command interface is clean and well-documented, you can go one step further and let an &lt;strong&gt;AI assistant&lt;/strong&gt; issue those commands. We have an open &lt;a href="https://github.com/Gearotons/servomotor-mcp" rel="noopener noreferrer"&gt;MCP server&lt;/a&gt; that does exactly that, so you can drive the hardware from plain language; here is &lt;a href="https://github.com/Gearotons/servomotor-mcp/releases/download/v0.3.1/M17-claude-code-demo.mp4" rel="noopener noreferrer"&gt;Claude Code doing it on a real M17&lt;/a&gt; (50 s).&lt;/p&gt;

&lt;p&gt;The headline: controlling a stepper from a Raspberry Pi &lt;em&gt;used&lt;/em&gt; to mean GPIO timing and lost-step anxiety. With an integrated closed-loop servo over serial, it's a &lt;code&gt;pip install&lt;/code&gt; and six lines.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Written with the help of an AI and verified by a human. Hardware, firmware and software for the M17 are open source: &lt;a href="https://github.com/tomrodinger/servomotor" rel="noopener noreferrer"&gt;github.com/tomrodinger/servomotor&lt;/a&gt;. The MCP server: &lt;a href="https://github.com/Gearotons/servomotor-mcp" rel="noopener noreferrer"&gt;github.com/Gearotons/servomotor-mcp&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>raspberrypi</category>
      <category>python</category>
      <category>robotics</category>
      <category>hardware</category>
    </item>
    <item>
      <title>M17 vs Dynamixel: an honest comparison (and an open-source alternative)</title>
      <dc:creator>Gearotons</dc:creator>
      <pubDate>Wed, 09 Sep 2026 22:32:28 +0000</pubDate>
      <link>https://dev.to/gearotons/m17-vs-dynamixel-an-honest-comparison-and-an-open-source-alternative-1cip</link>
      <guid>https://dev.to/gearotons/m17-vs-dynamixel-an-honest-comparison-and-an-open-source-alternative-1cip</guid>
      <description>&lt;p&gt;If you're building a robot arm or a research platform, &lt;strong&gt;Dynamixel&lt;/strong&gt; is probably the first smart servo you looked at, and for good reason. ROBOTIS has spent over a decade building one of the best motor ecosystems in robotics. So let's be upfront: this isn't a hit piece. It's an honest look at where Dynamixel is the right call, and where an open-source, NEMA-17 integrated servo like the Gearotons &lt;a href="https://gearotons.com" rel="noopener noreferrer"&gt;M17&lt;/a&gt; is the better fit.&lt;/p&gt;

&lt;p&gt;They're not actually the same kind of motor, and that's the whole point.&lt;/p&gt;

&lt;h2&gt;
  
  
  What each one &lt;em&gt;is&lt;/em&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Dynamixel&lt;/strong&gt; (e.g. XL330-M288-T, XL430-W250-T) is a &lt;strong&gt;smart gearmotor servo&lt;/strong&gt;: a small DC motor with a gearbox, an encoder, and a controller in a compact plastic housing, talking a TTL serial protocol. The XL330 is tiny and runs on 5 V; the XL430 is a bit bigger on 11.1 V. They daisy-chain, do position/velocity/current control, and have an SDK that's the envy of the industry.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The M17&lt;/strong&gt; is an &lt;strong&gt;integrated NEMA-17 stepper servomotor&lt;/strong&gt;: a standard NEMA-17 stepper with a closed-loop driver, motion controller, and magnetic encoder built into one unit, talking RS-485. No gearbox: a stepper holds position directly, with no gear backlash, and you get the high holding torque and fine positioning steppers are known for.&lt;/p&gt;

&lt;p&gt;That difference (geared DC servo vs. integrated closed-loop stepper, TTL vs. RS-485, proprietary vs. open) drives everything below.&lt;/p&gt;

&lt;h2&gt;
  
  
  Side by side
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Gearotons M17&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Dynamixel XL330 / XL430&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Type&lt;/td&gt;
&lt;td&gt;Integrated closed-loop &lt;strong&gt;stepper&lt;/strong&gt; (NEMA-17)&lt;/td&gt;
&lt;td&gt;Smart &lt;strong&gt;gearmotor&lt;/strong&gt; servo&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Open source&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Hardware + firmware + software&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Proprietary HW/FW (open SDK + protocol docs)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Mounting&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Standard NEMA-17&lt;/strong&gt; (any bracket, GT2 pulley, coupling)&lt;/td&gt;
&lt;td&gt;Proprietary horn/frame (FR-series brackets)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Bus&lt;/td&gt;
&lt;td&gt;RS-485, 230400 baud, daisy-chain&lt;/td&gt;
&lt;td&gt;TTL, daisy-chain&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Encoder / control&lt;/td&gt;
&lt;td&gt;32 kHz closed loop, magnetic encoder&lt;/td&gt;
&lt;td&gt;Contactless absolute encoder&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Libraries&lt;/td&gt;
&lt;td&gt;Python + Arduino, auto unit conversion&lt;/td&gt;
&lt;td&gt;DYNAMIXEL SDK (C/C++/Python/ROS/Arduino), best-in-class&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ecosystem&lt;/td&gt;
&lt;td&gt;Young, growing&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Huge&lt;/strong&gt;: ROS/MoveIt, years of research use&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AI-native&lt;/td&gt;
&lt;td&gt;First-party &lt;strong&gt;MCP server&lt;/strong&gt; (drive from an LLM)&lt;/td&gt;
&lt;td&gt;None first-party&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Price (verified 2026-06/09)&lt;/td&gt;
&lt;td&gt;$20–35 (4 sizes; US $23–40 with import duty included)&lt;/td&gt;
&lt;td&gt;XL330 &lt;strong&gt;$27.49&lt;/strong&gt;, XL430 &lt;strong&gt;$27.50&lt;/strong&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Voltage&lt;/td&gt;
&lt;td&gt;12–24 V&lt;/td&gt;
&lt;td&gt;5 V (XL330) / 11.1 V (XL430)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Where Dynamixel genuinely wins
&lt;/h2&gt;

&lt;p&gt;Be clear-eyed about this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The software ecosystem.&lt;/strong&gt; The DYNAMIXEL SDK and its ROS/MoveIt integration are mature, documented, and battle-tested across thousands of research projects. If you're doing ROS-based manipulation research, Dynamixel is a paved road.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Compactness.&lt;/strong&gt; The XL330 is &lt;em&gt;tiny&lt;/em&gt; and light. For a small desktop arm or a humanoid hand where grams and millimeters matter, a NEMA-17 is simply bigger.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Proven track record.&lt;/strong&gt; It's been the default smart servo in education and research for years. That maturity has real value: you're unlikely to hit a surprise.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Velocity and current modes.&lt;/strong&gt; Dynamixel exposes both out of the box. The M17 has velocity moves in its command set, but no current-control mode.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If those are your priorities, buy Dynamixel. We mean that.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where the M17 wins
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;It's open-source, top to bottom.&lt;/strong&gt; Hardware, firmware, and libraries are all public. You can inspect it, modify it, fix it, and keep it running for years without depending on one vendor's roadmap. For a lot of people that's not a nice-to-have; it's the requirement.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Standard NEMA-17 mounting.&lt;/strong&gt; The M17 drops into the entire maker/CNC/3D-printer hardware universe: standard brackets, GT2 pulleys, 5 mm shaft couplers, the lot. No proprietary horns. If you're building anything in that world, this matters enormously.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;RS-485, not TTL.&lt;/strong&gt; RS-485 is the industrial-grade differential bus: better noise immunity and longer cable runs, which you feel the moment your robot is bigger than a desktop toy.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AI-native control.&lt;/strong&gt; The M17 ships with a first-party &lt;strong&gt;MCP server&lt;/strong&gt;, so an AI assistant can drive it from natural language. No motor vendor, Dynamixel included, offers that today. Here is &lt;a href="https://github.com/Gearotons/servomotor-mcp/releases/download/v0.3.1/M17-claude-code-demo.mp4" rel="noopener noreferrer"&gt;Claude Code driving a real M17&lt;/a&gt; (50 s).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Stepper characteristics.&lt;/strong&gt; High holding torque, precise open-frame positioning, no gearbox backlash. For pen plotters, CNC-style motion, camera rigs, and lab fixtures, a NEMA-17 stepper servo is often a more natural fit than a geared hobby servo.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  On price (the honest version)
&lt;/h2&gt;

&lt;p&gt;You'll notice the XL330, at ~$27, sits right in the M17's price range. That's a fair point, and a reminder to compare like with like. The XL330 is a tiny 5 V geared servo; the M17 is a full NEMA-17 integrated stepper servo with several times the physical size and a different torque/positioning profile. The more apples-to-apples comparison for "integrated closed-loop NEMA-17 over a serial bus" is the proprietary industrial options (StepperOnline's iCL/ESS at $62–84), and against &lt;em&gt;those&lt;/em&gt;, the M17 is dramatically cheaper &lt;em&gt;and&lt;/em&gt; open. (Separate post coming.)&lt;/p&gt;

&lt;p&gt;So the M17 isn't trying to win on price against a $27 hobby servo. It's offering a different, standard-mount, open, AI-native motor at a price that's still accessible.&lt;/p&gt;

&lt;h2&gt;
  
  
  Which should you choose?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Choose Dynamixel if:&lt;/strong&gt; you're doing ROS/MoveIt research, you need the most mature SDK and community, you're building something small and weight-sensitive, and proprietary hardware is fine for your project.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Choose the M17 if:&lt;/strong&gt; you want open-source you can own and modify; you're building on standard NEMA-17 hardware (printers, CNC, plotters, larger arms); you want RS-485 robustness; you want to drive motors from an AI assistant; or you simply prefer a closed-loop stepper's positioning characteristics. And if you've been put off by proprietary lock-in or by the price of integrated industrial RS-485 servos, the M17 is built specifically for you.&lt;/p&gt;

&lt;p&gt;Different tools for different jobs. We're glad Dynamixel exists: it raised the bar for what a smart servo should be. The M17 takes that bar and makes it open, standard-mount, and AI-ready.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Written with the help of an AI and verified by a human. Hardware, firmware and software for the M17 are open source: &lt;a href="https://github.com/tomrodinger/servomotor" rel="noopener noreferrer"&gt;github.com/tomrodinger/servomotor&lt;/a&gt;. The MCP server: &lt;a href="https://github.com/Gearotons/servomotor-mcp" rel="noopener noreferrer"&gt;github.com/Gearotons/servomotor-mcp&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>robotics</category>
      <category>hardware</category>
      <category>opensource</category>
      <category>servo</category>
    </item>
    <item>
      <title>What makes a motor "AI-friendly"?</title>
      <dc:creator>Gearotons</dc:creator>
      <pubDate>Wed, 09 Sep 2026 22:29:34 +0000</pubDate>
      <link>https://dev.to/gearotons/what-makes-a-motor-ai-friendly-2hh6</link>
      <guid>https://dev.to/gearotons/what-makes-a-motor-ai-friendly-2hh6</guid>
      <description>&lt;p&gt;"AI-friendly" is well on its way to becoming a meaningless sticker, slapped on anything with a microcontroller and a press release. So let me be precise about what it actually means for a piece of motion hardware, because it turns out to be the &lt;em&gt;opposite&lt;/em&gt; of a marketing gimmick: it's a set of boring engineering properties that happen to matter enormously the moment an LLM is in the control loop.&lt;/p&gt;

&lt;p&gt;Here's the thesis: &lt;strong&gt;a motor is AI-friendly to exactly the degree that it is human-friendly, because the things that make hardware easy for a person to program are the same things that make it reliable for a model to operate as a tool.&lt;/strong&gt; Good docs for people turn out to be good docs for machines.&lt;/p&gt;

&lt;h2&gt;
  
  
  What an LLM actually needs from hardware
&lt;/h2&gt;

&lt;p&gt;When you wire a language model to a physical device, via tool-calling, an &lt;a href="https://modelcontextprotocol.io" rel="noopener noreferrer"&gt;MCP&lt;/a&gt; server, or an agent loop, the model isn't running a real-time control loop. It's doing something more like what a careful human operator does: deciding &lt;em&gt;what&lt;/em&gt; should happen ("move axis 2 to 90 degrees, slowly"), calling a function, and reading back the result to decide what's next. For that to work reliably, the hardware interface has to provide four things:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Intent-level commands, not timing.&lt;/strong&gt; A model should say &lt;code&gt;go_to_position(90°)&lt;/code&gt; or &lt;code&gt;homing()&lt;/code&gt;, not bit-bang STEP/DIR pulses with microsecond timing. Low-level protocols are fine for an FPGA and miserable for an LLM (and for a human writing a quick script). The command surface should be the &lt;em&gt;intentions&lt;/em&gt; you actually have.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Clear, complete, structured documentation.&lt;/strong&gt; A model reads your docs (or your tool schemas) and acts on them literally. Ambiguity, missing parameters, and "see the forum post" gaps that a human muddles through become hard failures for a model. The discipline that makes a datasheet pleasant for a person (every command defined, units explicit, ranges stated) is exactly what lets a model call the interface without guessing.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Real, readable feedback.&lt;/strong&gt; The model has to be able to &lt;em&gt;ask&lt;/em&gt; what happened: where is the shaft now? Did the move finish? Is there an error? A motor that silently drifts (see: open-loop step loss) is poison for an agent, because the model can't recover from a failure it can't observe. Closed-loop position feedback isn't just a precision feature here; it's what makes the loop &lt;em&gt;honest&lt;/em&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Safety in the hardware, not the model's good behavior.&lt;/strong&gt; Models hallucinate. An agent will occasionally emit a wrong tool call. You don't want the only thing standing between a bad command and a damaged mechanism to be a prompt that says "please don't break things." The protection that matters belongs in the motor itself. On the M17, the firmware enforces over-current, over-voltage, and over-temperature limits that hold no matter what command arrives. Safety belongs in the hardware, not in the model's goodwill.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Notice that none of these are AI features. They're just good interface design. The "AI-friendly" claim is really a claim that you did the unglamorous work well.&lt;/p&gt;

&lt;h2&gt;
  
  
  Automatic unit conversion is an underrated example
&lt;/h2&gt;

&lt;p&gt;Here's a concrete one. Ask a model to "turn the motor a quarter turn" and it'll happily reason in degrees or rotations. Internally, the motor thinks in encoder counts and timesteps. If your library makes the &lt;em&gt;caller&lt;/em&gt; do that conversion, every integration, human or model, becomes a source of off-by-a-factor bugs. If the library accepts degrees and seconds and converts for you, the model (and the human) can operate at the level they actually think at. Small thing; huge reliability difference across thousands of tool calls.&lt;/p&gt;

&lt;h2&gt;
  
  
  The MCP server is where it gets real
&lt;/h2&gt;

&lt;p&gt;The cleanest way to make a motor drivable by AI today is to expose it as a set of &lt;strong&gt;MCP tools&lt;/strong&gt;: a well-described API that any MCP-capable client (Claude Desktop, an agent, your own loop) can call. A good tool surface for a motor leads with intent-level tools: discovery (&lt;code&gt;list_serial_ports&lt;/code&gt;, &lt;code&gt;connect&lt;/code&gt;, &lt;code&gt;list_motors&lt;/code&gt;), &lt;code&gt;move_to&lt;/code&gt;, &lt;code&gt;move_relative&lt;/code&gt;, &lt;code&gt;get_motor_status&lt;/code&gt;, &lt;code&gt;stop&lt;/code&gt;, and a &lt;code&gt;run_sequence&lt;/code&gt; for choreographed motion, with the full firmware command set exposed underneath (one generated tool per command), so nothing the motor can do is out of the model's reach. Each tool's description states &lt;em&gt;when&lt;/em&gt; to call it, not just what it does, because models, like junior operators, do better with explicit triggers.&lt;/p&gt;

&lt;p&gt;Crucially, the MCP server stays a &lt;em&gt;thin control layer&lt;/em&gt;: it forwards intent-level commands straight to the motor, so the model has the motor's full range and speed to work with. The safety that matters lives one layer down, in the motor's own firmware: over-current, over-voltage, and over-temperature protection that holds regardless of what the model asks for. The model drives; the hardware protects itself.&lt;/p&gt;

&lt;p&gt;We've built exactly this for the M17 (&lt;a href="https://github.com/Gearotons/servomotor-mcp" rel="noopener noreferrer"&gt;servomotor-mcp&lt;/a&gt;; &lt;code&gt;uvx --from servomotor-mcp servomotor-mcp&lt;/code&gt; runs it with a simulated motor), and the behavior holds up on real hardware. Here is a real session, replayed from the log, with the bench motor filmed alongside: &lt;a href="https://github.com/Gearotons/servomotor-mcp/releases/download/v0.3.1/M17-claude-code-demo.mp4" rel="noopener noreferrer"&gt;50-second video&lt;/a&gt;. In it, an LLM issues plain-language instructions, the motor moves closed-loop to the commanded angle, and the motor's firmware self-protects if a command would push it past its electrical or thermal limits. No vendor lock-in: the server is MIT-licensed and speaks plain MCP, so any MCP client can drive it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F5amczz251oh4nhhm46ux.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F5amczz251oh4nhhm46ux.gif" alt="Claude Code driving a real M17 over MCP: the session, replayed" width="600" height="338"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why this is a category, not a feature
&lt;/h2&gt;

&lt;p&gt;No motor manufacturer markets this today. The bridges that exist are third-party software bolted onto generic servos. That's a tell: "AI-friendly" hasn't been treated as a &lt;em&gt;hardware&lt;/em&gt; design goal, as something you build the command surface, the docs, the feedback, and the safety model &lt;em&gt;around&lt;/em&gt; from the start.&lt;/p&gt;

&lt;p&gt;We think that's where motion control is heading. Not because AI is magic, but because the properties that make a motor good for an agent (high-level commands, honest feedback, complete docs, hardware protection you can trust) are the same properties that have always made hardware good to work with. "AI-friendly" is just a forcing function for doing the basics right.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Written with the help of an AI and verified by a human. Hardware, firmware and software for the M17 are open source: &lt;a href="https://github.com/tomrodinger/servomotor" rel="noopener noreferrer"&gt;github.com/tomrodinger/servomotor&lt;/a&gt;. The MCP server: &lt;a href="https://github.com/Gearotons/servomotor-mcp" rel="noopener noreferrer"&gt;github.com/Gearotons/servomotor-mcp&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>mcp</category>
      <category>ai</category>
      <category>robotics</category>
      <category>hardware</category>
    </item>
  </channel>
</rss>
