# M3 Servomotor — hardware version 1.2

> This product is a Servomotor with 4-in-1 integrated motor + motor driver + motion controller + encoder in a NEMA 17 form factor

Canonical page: https://9o.at/products/m3/1.2
Product code: M3. Hardware version: 1.2.

## Documents
- Datasheet (English): https://cdn.jsdelivr.net/gh/tomrodinger/servomotor@main/servomotor_datasheets/servomotor_datasheet_v1.1_Dec_5_2024.pdf
- Schematic (PDF): https://raw.githubusercontent.com/tomrodinger/servomotor/main/PCB/Servomotor3/1.2/schematic/1.2-index-schTop.pdf
- Hardware design files on GitHub: https://github.com/tomrodinger/servomotor/tree/main/PCB/Servomotor3/1.2
- Tutorial: https://tutorial.gearotons.com/
- Python API reference (Markdown): https://9o.at/docs/python.md
- Arduino API reference (Markdown): https://9o.at/docs/arduino.md
- MCP server (drive the motor from an AI assistant): https://github.com/Gearotons/servomotor-mcp
- Store: https://gearotons.com/store

## Firmware
Newest first. Update with the browser tool at https://motor-maintenance.gearotons.com/ (Chromium browsers) or the Python tools in the repository.

| Version | Compatibility | Date | SHA-256 | File |
|---|---|---|---|---|
| 0.11.0.1 | 3 | 2025-06-25 | 4efa761edb1f6337da95eed12d4ba78fd727c98d0487c39e6eddbb9f083282f6 | https://cdn.jsdelivr.net/gh/tomrodinger/servomotor@main/firmware/firmware_releases/servomotor_M3_fw0.11.0.1_scc3_hw1.2.firmware |
| 0.11.0.0 | 3 | 2025-06-13 | a554053fcbb8b90fb4a97d31fe822cf7d2ae486428934f4c78e1d515d75dbd3b | https://cdn.jsdelivr.net/gh/tomrodinger/servomotor@main/firmware/firmware_releases/servomotor_M3_fw0.11.0.0_scc3_hw1.2.firmware |

### Updating from the command line

Once per computer, run these two commands separately:

```sh
pip3 install --upgrade servomotor
```

```sh
servomotor_command -P
```

The second shows a numbered list of serial ports; type the number of the USB-to-RS-485 adapter and press Enter. The choice is saved, so no later command needs `-p`, and nothing is sent to the motor. Run it on its own: it reads its answer from the terminal, so inside a pasted block it would take the next pasted line as its answer. For scripts, pass `-p <PORT>` or set `SERVOMOTOR_PORT` instead; either overrides the saved choice.

Then, for each upgrade:

```sh
# Download the firmware file into the current folder.
curl -LO https://cdn.jsdelivr.net/gh/tomrodinger/servomotor@main/firmware/firmware_releases/servomotor_M3_fw0.11.0.1_scc3_hw1.2.firmware
# Update every motor on the bus that this file is for. Motors of another
# model or compatibility code ignore it and keep their firmware.
upgrade_firmware servomotor_M3_fw0.11.0.1_scc3_hw1.2.firmware
# Check the result: the Firmware Version column should show the new version
# for every motor. The upgrade itself cannot tell you whether it worked.
show_device_information_for_all_devices
```

This updates every motor on the bus that the file is for; motors of another model or firmware compatibility code ignore it and keep their firmware. No motor answers during a broadcast transfer, so upgrade_firmware reports every page as written whether or not it was: the final `show_device_information_for_all_devices` is the real check, and its Firmware Version column should show the new version for every motor. If it stops with "Communication error" instead of printing its table, a motor is probably still in its bootloader (its green LED blinks fast); run the upgrade again. To update only one motor, use the browser maintenance tool at https://motor-maintenance.gearotons.com/ — press Firmware on that motor's row; it flashes only that motor, leaves the rest of the bus alone and reads the version back — or add `-a <ALIAS>` to the upgrade command. The command-line tool reboots the whole bus into its bootloader during the transfer, even with -a. An interrupted upgrade cannot brick a motor, and the alias and calibration survive.
