Support » Pololu Motoron Motor Controller User’s Guide »
9. Command reference
This section describes each of the commands supported by the Motoron Motor Controllers and how they are encoded as bytes on the I²C interface.
Each command begins with a byte called the command byte that has its most-significant bit set to 1. The command byte marks the start of the command and also indicates which command to execute. Some commands require additional bytes after the command byte, which are called data bytes and have their most-significant bits equal to 0. Unless you have disabled CRC for commands, the final byte of each command must be a CRC byte, which is calculated from the bytes came before it, as described in Section 11.
In the tables below that are labeled “Command encoding” and “Response encoding”, each cell of a table represents a single byte. CRC bytes are not shown in these tables, but each command requires a CRC byte at the end by default, and each response contains a CRC byte at the end by default. Numbers prefixed with “0x” are written in hexadecimal notation (base 16) and numbers prefixed with “0b” are written in binary notation. Numbers with these prefixes are written with their most significant digits first, just like regular decimal numbers.
The term “bit 0” refers to the least significant bit of a variable (the bit that contributes a value of 1 to the variable when it is set). Accordingly, the other bits of a variable are numbered in order from least significant to most significant.
For a reference implementation of the Motoron’s command protocol, see the Motoron Arduino library or the Motoron Python library.
List of commands
- Get firmware version
- Set protocol options
- Read EEPROM
- Write EEPROM
- Reinitialize
- Reset
- Get variables
- Set variable
- Coast now
- Clear motor fault
- Clear latched status flags
- Set latched status flags
- Set speed
- Set all speeds
- Set all speeds using buffers
- Set braking
- Reset command timeout
- Multi-device error check
- Multi-device write
Get firmware version
Arguments | None |
---|---|
Response | Product ID and firmware version |
Arduino library | void getFirmwareVersion(uint16_t * productId, uint16_t * firmwareVersion) |
Command encoding:
0x87 |
Response encoding:
product ID low byte | product ID high byte | minor FW version (BCD format) | major FW version (BCD format) |
Description:
This command generates a 4-byte response with identifying information about the firmware running on the device.
The first two bytes of the response are the low and high bytes of the product ID, respectively. The table below shows the correspondence between product IDs and Motoron models. (Models with the same product ID use the same firmware.)
Product ID | Models |
---|---|
0x00CC | M3S256, M3H256 |
0x00CD | M2S, M2H |
0x00CE | M2T256 |
0x00CF | M2U256 |
0x00D0 | M1T256 |
0x00D1 | M1U256 |
0x00D2 | M3S550, M3H550 |
0x00D3 | M2T550 |
0x00D4 | M2U550 |
0x00D5 | M1T550 |
0x00D6 | M1U550 |
The last two bytes of the response are the firmware minor and major version numbers in binary-coded decimal (BCD) format. For example, 0x02 0x01 corresponds to firmware version 1.02.
Set protocol options
Arguments | CRC for commands: true or false CRC for responses: true or false I²C general call: true or false |
---|---|
Response | None |
Arduino library | void setProtocolOptions(uint8_t options) void enableCrc() void disableCrc() void enableCrcForCommands() void disableCrcForCommands() void enableCrcForResponses() void disableCrcForResponses() void enabeI2cGeneralCall() void disableI2cGeneralCall() |
Command encoding:
0x8B | protocol options byte | inverted protocol options byte |
Description:
This command lets you change the Motoron’s protocol options. Each bit of the protocol options byte specifies whether to enable a particular feature.
- Bit 0: This bit should be 1 to enable CRC for commands and 0 to disable it. This feature is enabled by default and documented in Section 11.
- Bit 1: This bit should be 1 to enable CRC for responses and 0 to disable it. This feature is enabled by default and documented in Section 11.
- Bit 2: This bit should be 1 to enable the I²C general call address and 0 to disable it. This feature is enabled by default and documented in Section 6.
The other bits are reserved and should be set to 0. The effect of this command only lasts until the next time the Motoron loses power or its processor is reset, or it receives a Reinitialize command.
The second data byte should be equal to the protocol options byte but with the lower 7 bits all inverted. If it is some other value, the command fails and the Motoron reports a protocol error.
It is OK to provide a CRC byte at the end of this command even if CRC for commands has been disabled. For example, if you are not sure whether CRC for commands is enabled and you want to set the protocol options to 0x04 (disabling CRC but leaving the general call address enabled), send these four bytes: 0x8B 0x04 0x7B 0x43. The fourth byte is the CRC byte. If you are want to set the protocol options to 0x00 (disabling CRC and the general call address), send these four bytes: 0x8B 0x00 0x7F 0x42.
If you are using this command to enable or disable the I²C general call address, the command does not have an instant effect, so you might need to delay for 1 ms after sending the command.
Read EEPROM
Arguments | Offset: the address of the first byte to read, from 0 to 127 Length: the number of bytes to read, from 1 to 32 |
---|---|
Response | The requested bytes |
Arduino library | void readEeprom(uint8_t offset, uint8_t length, uint8_t * buffer) uint8_t readEepromDeviceNumber() |
Command encoding:
0x93 | offset | length |
Description:
This command reads the specified bytes from the Motoron’s EEPROM memory, which is a 128-byte non-volatile memory that is used to store settings that persist through power interruptions and resets. See the “Write EEPROM” command below for more information about the settings stored in EEPROM.
Write EEPROM
Arguments | Offset: a number between 0 and 127 Value: a byte value between 0 and 255 |
---|---|
Response | None |
Arduino library | void writeEeprom(uint8_t offset, uint8_t value) |
Command encoding:
0x95 | offset | lower 7 bits of value (0 to 127) | most significant bit of value (0 or 1) | first data byte (the offset) with lower 7 bits inverted | second data byte with lower 7 bits inverted | third data byte with lower 7 bits inverted |
Description:
This command writes a value to one byte in the Motoron’s EEPROM memory, which is a 128-byte non-volatile memory that is used to store settings that persist through power interruptions and resets.
This command only works while the JMP1 pin is shorted to GND. If the JMP1 pin is not shorted to GND when this command is received, the EEPROM will not be modified.
The first three data bytes after the command byte encode the offset and value. The last three data bytes are copies of the first three, but with the lower 7 bits inverted. If the third data byte is something other than 0 or 1, or the last three data bytes are incorrect, the Motoron reports a protocol error. The extra bytes in the command reduce the risk of accidental writes to the EEPROM.
This command takes about 5 ms to finish writing to the EEPROM. The Motoron’s microcontroller is stopped during this time, so it will not be able to respond to other commands or update its outputs. After running this command, we recommend waiting for at least 6 ms before you try to communicate with the Motoron.
Warning: Be careful not to write to the EEPROM in a fast loop. The EEPROM memory of the Motoron’s microcontroller is only rated for 100,000 erase/write cycles.
Although this command can write to any byte in EEPROM, we recommend that you only write to the parts of EEPROM documented in Section 10. The bytes at other offsets are either used internally by the Motoron or are reserved for use by new features in future firmware versions.
Reinitialize
Arguments | None |
---|---|
Response | None |
Arduino library | void reinitialize() |
Command encoding:
0x96 |
Description:
This command resets the Motoron’s variables to their default state.
- The protocol options are reset to their default values (meaning that CRC and the I²C general call address is enabled).
- The latched status flags are cleared and the Reset flag is set to 1.
- The UART faults variable is reset to 0.
- The command timeout is reset to 250 (1000 ms).
- The error response and error mask are reset to their default values.
- The motors will start decelerating down to a speed of zero—respecting the previously-set deceleration limits—and then coast. This process can be interrupted by subsequent motor control commands (Coast, Set speed, Set all speeds, Set all speeds using buffers).
- The target speed, target brake amount, buffered speed, acceleration limits, deceleration limits, starting speeds, direction change delays, for each motor are reset to 0.
- The PWM mode, current limit, and current sense settings for each motor are reset to their default values.
It is OK to provide a CRC byte at the end of this command even if CRC for commands has been disabled. For example, if you want to send the Reinitialize command and you are not sure whether CRC for commands is enabled, you can send the following two bytes: 0x96 0x74. The second byte is the CRC byte.
Reset
Arguments | None |
---|---|
Response | None |
Arduino library | void reset() |
Command encoding:
0x99 |
Description:
This command causes a full hardware reset, and is equivalent to briefly driving the Motoron’s RST pin low. The Motoron’s RST pin is briefly driven low by the Motoron itself as a result of this command.
After running this command, we recommend waiting for at least 5 ms before you try to communicate with the Motoron.
Get variables
Arguments | Motor: a motor number, or 0 for general variables Offset: the address of the first variable to fetch Length: the number of bytes to fetch, from 1 to 32 |
---|---|
Response | The requested bytes |
Arduino library | void getVariables(uint8_t motor, uint8_t offset, uint8_t length, uint8_t * buffer) Several functions with names starting with get |
Command encoding:
0x9A | motor | offset | length |
Description:
This command fetches a range of bytes from the Motoron’s variables, which are stored in the Motoron’s RAM and represent the current state of the Motoron.
To fetch variables specific to a particular motor, set the motor argument to the motor number (between 1 and the number of motors supported by the Motoron). To fetch general variables applicable to all motors, set the motor argument to 0. The Motoron reports a protocol error if this argument is invalid.
The offset argument specifies the location of the first byte you want to fetch. The length argument specifies how many bytes to read. Each variable, along with its offset and size, is documented in Section 8.
It is OK to read past the last variable. The Motoron will return zeros when you try to read from unimplemented areas of the variable space.
All multi-byte variables retrieved by this command are returned in little-endian format, meaning that the least-significant byte comes first.
Set variable
Arguments | Motor: a motor number, or 0 for general variables Offset: the address of the variable to set (only certain offsets allowed) Value: the new number to store in the variable (14-bit) |
---|---|
Response | None |
Arduino library | void setVariable(uint8_t motor, uint8_t offset, uint16_t value) Several functions with names starting with set |
Command encoding:
0x9C | motor | offset | lower 7 bits of the value | bits 7 through 13 of the value |
Description:
This command sets the value of the variable specified variable.
The motor and offset arguments specify which variable to set. These arguments are equivalent to the motor and offset arguments of the “Get variable” command. However, this command can only set certain variables, and the offset argument must point to the first byte of the variable. The Motoron will report a protocol error if the motor or offset arguments are invalid.
The value argument specifies the 14-bit number to set the variable to. The Motoron looks at all 14 bits of the value argument, even if the variable you are setting is 8-bit. If the value specified by those 14 bits is outside of the allowed range of values for the variable, the Motoron will change it to the closest allowed value before setting the variable.
Each variable, along with its offset, allowed range of values, and whether it can be set with this command, is documented in Section 8.
Here is some example C/C++ code that will generate the correct bytes, given integers motor
, offset
, and value
and an array called command
:
command[0] = 0x9C; // Set Variable command[1] = motor & 0x7F; command[2] = offset & 0x7F; command[3] = value & 0x7F; command[4] = (value >> 7) & 0x7F;
Coast now
Arguments | None |
---|---|
Response | None |
Arduino library | void coastNow() |
Command encoding:
0xA5 |
Description:
This command causes all of the motors to immediately start coasting. For each motor, it sets the target brake amount, target speed, and current speed to 0.
Clear motor fault
Arguments | Unconditional: true or false |
---|---|
Response | None |
Arduino library | void clearMotorFault(uint8_t flags = 0) void clearMotorFaultUnconditional() |
Command encoding:
0xA6 | Bit 0: unconditional |
Description for the Motoron M1T256, M1T256, M2T256, M2U256, M3S256, and M3H256:
If any of the motors on the Motoron are currently experiencing a fault (error), or the unconditional argument is true, this command attempts to recover from the faults. This command does not disrupt the operation of any motors that are operating normally. If you send this command while the “Current speed” variable of any motor is non-zero, it could cause the Motoron to recover from a fault and suddenly start driving the motor at that speed.
Description for the Motoron M1T550, M1T550, M2T550, M2U550, M3S550, M3H550, M2S and M2H:
These Motoron controllers do not have any latching faults, so this command does nothing.
Clear latched status flags
Arguments | Flags: 10-bit value |
---|---|
Response | None |
Arduino library | void clearLatchedStatusFlags(uint16_t flags) void clearResetFlag() |
Command encoding:
0xA9 | lower 7 bits of flags | upper 3 bits of flags |
Description:
For each bit in the flags argument that is 1, this command clears the corresponding bit in the “Status flags” variable, setting it to 0. The “Status flags” variable and all of its bits are documented in Section 8.
The Reset flag is particularly important to clear: it gets set to 1 after the Motoron powers on or experiences a reset, and it is considered to be an error by default, so it prevents the motors from running. Therefore, it is necessary to use this command to clear the Reset flag before you can get the motors running (or alternatively you can change the error mask).
We recommend that immediately after you clear the Reset flag, you should configure the Motoron’s motor settings and error response settings. That way, if the Motoron experiences an unexpected reset while your system is running, it will stop running its motors and it will not start them again until all the important settings have been configured.
The Reset flag is bit 9 in the “Status flags” variable. Therefore, to clear it, you would set the flags argument to 0x200. This would result in a command with the following three bytes (not including the CRC byte): 0xA9 0x00 0x04.
Set latched status flags
Arguments | Flags: 10-bit value |
---|---|
Response | None |
Arduino library | void setLatchedStatusFlags(uint16_t flags) |
Command encoding:
0xAC | lower 7 bits of flags | upper 3 bits of flags |
Description:
For each bit in the flags argument that is 1, this command sets the corresponding bit in the “Status flags” variable to 1. The “Status flags” variable and all of its bits are documented in Section 8.
Set speed
Arguments | Mode: normal, now, or buffered Motor: a motor number Speed: from −800 to 800 |
---|---|
Response | None |
Arduino library | void setSpeed(uint8_t motor, int16_t speed) void setSpeedNow(uint8_t motor, int16_t speed) void setBufferedSpeed(uint8_t motor, int16_t speed) |
Command encoding:
0xD1 for normal mode 0xD2 for now mode 0xD4 for buffered mode |
motor | lower 7 bits of speed | upper 7 bits of speed |
Description:
The motor argument should be between 1 and the number of motors that your Motoron supports. If it is invalid, the Motoron reports a protocol error.
The speed argument should be a speed between −800 and 800. If the specified speed is outside this range, the Motoron will change it to the closest valid speed between −800 and 800. See the documentation of the “Current speed” variable in Section 8 for more details about what the different speed values mean. The speed argument is encoded as a 14-bit two’s complement number.
The mode specifies when and how to apply the speed:
- Normal mode: The motor’s “Target speed” is changed. The “Current speed” will start moving towards the target speed, obeying acceleration and deceleration limits. The “Target brake amount” is also set to 800.
- Now mode: The motor’s “Target speed” and “Current speed” are changed, so the motor outputs will change immediately. The “Target brake amount” is also set to 800.
- Buffered mode: The motor’s “Buffered speed” is set. You can use the “Set all speeds using buffers” command to make it take effect.
Here is some example C/C++ code that will generate the correct bytes, given integers motor
and speed
:
command[0] = 0xD1; // Set Speed, normal mode command[1] = motor & 0x7F; command[2] = speed & 0x7F; command[3] = (speed >> 7) & 0x7F;
Set all speeds
Arguments | Mode: normal, now, or buffered Speed for each motor: from −800 to 800 |
---|---|
Response | None |
Arduino library | void setAllSpeeds(int16_t speed1, ...) void setAllSpeedsNow(int16_t speed1, ...) void setAllBufferedSpeeds(int16_t speed1, ...) |
Command encoding:
0xE1 for normal mode 0xE2 for now mode 0xE4 for buffered mode |
lower 7 bits of speed 1 | upper 7 bits of speed 1 | … |
Description:
This command is equivalent to the “Set speed” command, but it sets the speed of all the motors at the same time. This command takes one speed argument for each motor supported by the controller. Each speed argument is encoded as two bytes, using the same speed encoding as the “Set speed” command. The speeds are sent in order by motor number, starting with the speed for motor 1.
If CRC for commands is not enabled, it is OK to send extra speeds. They will be ignored since their most significant bit is 0.
If you send fewer speeds than the number of motors supported, the command will not be executed, and the Motoron will report a protocol error when you send the next command.
Set all speeds using buffers
Arguments | Mode: normal or now |
---|---|
Response | None |
Arduino library | void setAllSpeedsUsingBuffers() void setAllSpeedsNowUsingBuffers() |
Command encoding:
0xF0 for normal mode 0xF3 for now mode |
Description:
This command applies the buffered speeds that were previously set with “Set speed” or “Set all speeds” commands in buffered mode.
The mode specifies how to apply the speed:
- Normal mode: Each motor’s “Target speed” is set equal to its buffered speed. Each motor’s “Current speed” will start moving towards this value, obeying acceleration and deceleration limits.
- Now mode: Each motor’s “Target speed” and “Current speed” are set equal to its buffered speed, so the motor outputs will change immediately.
This command also sets each motor’s “Target brake amount” to 800.
This command does not change the buffered speeds.
Set braking
Arguments | Mode: normal or now Motor: a motor number Brake amount: from 0 to 800 |
---|---|
Response | None |
Arduino library | void setBraking(uint8_t motor, uint16_t amount) void setBrakingNow(uint8_t motor, uint16_t amount) |
Command encoding:
0xB1 for normal mode 0xB2 for now mode |
motor | lower 7 bits of brake amount | upper 7 bits of brake amount |
Description:
The motor argument should be between 1 and the number of motors that your Motoron supports. If it is invalid, the Motoron reports a protocol error.
The brake amount argument should be a number between 0 and 800. If it is larger than 800, the Motoron will change it to 800. This command sets the “Target brake amount” variable of the specified motor to the value of this argument. A value of 0 corresponds to full coasting, while a value of 800 corresponds to full braking. However, due to hardware limitations, the resulting brake amount might be different from what is specified. See the documentation of the “Target brake amount” variable in Section 8 for more details.
The mode argument specifies when and how to apply the specified brake amount:
- Normal mode: The motor’s “Target speed” is set to 0. The “Current speed” will start moving towards the target speed, obeying deceleration limits. When it reaches zero, the specified brake amount will be used.
- Now mode: The motor’s “Target speed” and “Current speed” are set to 0 so the desired brake amount will be applied immediately.
Here is some example C/C++ code that will generate the correct bytes, given integers motor
and amount
:
command[0] = 0xB1; // Set braking, normal mode command[1] = motor & 0x7F; command[2] = amount & 0x7F; command[3] = (amount >> 7) & 0x7F;
Reset command timeout
Arguments | None |
---|---|
Response | None |
Arduino library | void resetCommandTimeout() |
Command encoding:
0xF5 |
Description:
This command resets the command timeout, which means that if the command timeout feature is enabled, this command prevents the timeout from occurring for some time. (The command timeout is also reset by every other command documented here.) The command timeout feature is documented in Section 8.
Multi-device error check
Arguments | Starting device number: 7-bit or 14-bit number Device count: non-zero 7-bit or 14-bit number |
---|---|
Response | 0x00 if the “Error active” status flag is 1 0x3C otherwise |
Arduino library | void multiDeviceErrorCheckStart(uint16_t startingDeviceNumber, uint16_t deviceCount) |
Command encoding:
If 14-bit device numbers are not enabled (the default):
0xF9 | starting device number | device count |
If 14-bit device numbers are enabled:
0xF9 | lower 7 bits of starting device number | upper 7 bits of starting device number | lower 7 bits of device count | upper 7 bits of device count |
Description:
This special, advanced command allows you to quickly detect whether the “Error active” status flag (documented in Section 8) is set to 1 on any Motorons in a group of Motorons with consecutive device numbers. This command was added in firmware version 1.02, so it is not available on the Motoron M3S256, M3H256, M2S, and M2H. It is only intended to be used on Motorons with a UART serial interface.
If CRC for commands is enabled, a CRC byte must be sent after the device count. After the CRC byte, the Motoron expects to receive zero or more bytes with the value 0x3C, and it will transmit a response once the starting device number plus the number of 0x3C bytes received is equal to its own device number (or alternative device number). The response is a single byte: 0x00 if its “Error active” status flag is 1, or 0x3C otherwise. The Motoron’s response to this command never contains a CRC byte, even if CRC for responses is enabled. While the Motoron is waiting to receive the right number of 0x3C bytes, it ignores bytes with a value of 0xFF and 0xFE that it receives. If it receives a byte that is not 0x3C, 0xFF, or 0xFE, then it stops processing this command. Each Motoron will send at most one response per command, even if its device number and alternative device number are both in the specified range.
If you are using a half-duplex serial bus where each Motoron can receive the bytes transmitted by other Motorons, then you can just send this command once in order to check the error status of an entire group of Motorons with consecutive device numbers. After the optional CRC byte, the Motoron whose device number (or alternative device number) is equal to the starting device number will respond. If it responds with 0x00, then all the other Motorons will stop processing the command as a result. If it responds with 0x3C, then the Motoron whose device number (or alternative device number) is equal to the starting device number plus one will add its response. This process continues until all the addressed Motorons have responded or until one of has a problem and fails to send a 0x3C byte. The number of 0x3C bytes that the main controller receives in response is the number of Motorons that are not experiencing an error. If this number is equal to the device count, then you have confirmed that none of the addressed devices are experiencing an error. If the number is less, then you can add the starting device number to the number of 0x3C bytes received in order to get the device number of the first Motoron that might be experiencing errors or communication problems. Depending on how you want your system to behavior, you might use the Pololu protocol to query that specific motor controller for details about its error, or you might send commands to shut down the system.
It is also possible to use this command on a full-duplex serial bus. The main controller would send a series of 0x3C bytes to the Motorons in order to get all of them to respond to the command, and it might choose to abort this process if any Motoron fails to send a 0x3C byte.
Multi-device write
Arguments | Starting device number: 7-bit or 14-bit number Device count: non-zero 7-bit or 14-bit number Bytes per device: 0 to 15 Command byte: 7-bit number Payload data bytes for each device |
---|---|
Response | None |
Arduino library | void multiDeviceWrite(uint16_t startingDeviceNumber, uint16_t deviceCount, uint8_t bytesPerDevice, uint8_t commandByte, const uint8_t * data) |
Command encoding:
If 14-bit device numbers are not enabled (the default):
0xFA | starting device number | device count | bytes per device | lower 7 bits of command byte |
payload data bytes for each device |
If 14-bit device numbers are enabled:
0xFA | lower 7 bits of starting device number |
upper 7 bits of starting device number |
lower 7 bits of device count |
upper 7 bits of device count |
bytes per device | lower 7 bits of command byte |
payload data bytes for each device |
Description:
This special, advanced command allows you to efficiently send the same command to an entire group of Motorons with consecutive device numbers while specifying different data for each Motoron. This command was added in firmware version 1.02, so it is not available on the Motoron M3S256, M3H256, M2S, and M2H. It is mainly intended to be used for setting motor speeds on Motorons with a UART serial interface.
The Starting device number and Device count arguments define a range of consecutive device numbers that this command applies to.
The Bytes per device argument specifies how many data/payload bytes will be sent for each device. Normally you should set this argument to be equal to the number of bytes that the command you are using expects. For example, the “Set all speeds” command for a 2-channel Motoron expects 4 data bytes, so you would set this argument to 4. If this argument is more than the number of bytes the command takes, the extra bytes are ignored. If this argument is less than the number of bytes the command takes, then the unspecified bytes at the end of the command are assumed to be 0. (For example, using only 2 bytes per device with a “Set all speeds” command sets the speed of all motors other than Motor 1 to zero.) This argument can be zero.
The Command byte argument should have its most-significant bit be 0. In other words, it should be between 0 and 0x7F. The Motoron will add 0x80 to this argument (i.e. set its most significant bit) to determine the first byte of the command to execute. For example, the command byte of a “Set all speeds” command is 0xE1, and it is encoded in this command as 0x61, which is 0xE1 minus 0x80.
The length of the Payload data bytes should be exactly the product of the “Device count” and “Bytes per device” arguments. These bytes should each be between 0 and 127. The payloads are ordered by device number: the payload for the lowest device number goes first.
If CRC for commands is enabled, the Motoron expects a CRC byte after the last byte of payload data.
All Motorons receiving this command will check it for protocol and CRC errors, and they will not execute the command until after all of the payload bytes and the optional CRC byte have been received. The Motoron will never send a response to this command.
Treatment of unrecognized and invalid bytes
If the Motoron receives a byte with a most significant bit of 1 while it was expecting a data byte for a command, the command is canceled and the Motoron reports a protocol error. There are some exceptions to this while processing a Multi-device error check command.
If the Motoron receives a byte with a most significant bit of 1 that is not a recognized command byte, it will usually report a protocol error. However, bytes 0x80, 0xFE, and 0xFF are ignored, and 0xAA signals the start of a Pololu protocol command (Section 7).
If the Motoron receives a byte with a most significant bit of 0 while it is not expecting a data byte for a command, it ignores the byte.