# 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 10.

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.

#### Get firmware version

Arguments None Product ID and firmware version 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. The product ID 0x00CC corresponds to both the M3S256 and M3H256 (these models use the same firmware), and is encoded as 0xCC 0x00.

The last two bytes of the response are the firmware minor and major version numbers in binary-coded decimal (BCD) format. For example, 0x00 0x01 corresponds to firmware version 1.00.

#### Set protocol options

Arguments CRC for commands: true or falseCRC for responses: true or falseI²C general call: true or false None 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 10.
• 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 10.
• 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 7.

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.

Arguments Offset: the address of the first byte to read, from 0 to 127Length: the number of bytes to read, from 1 to 32 The requested bytes 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 127Value: a byte value between 0 and 255 None void writeEeprom(uint8_t offset, uint8_t value)void writeEepromDeviceNumber(uint8_t number)

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.

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.

The only setting currently stored in the EEPROM memory is the EEPROM device number, a number between 0 and 127 that is stored at offset 1. The Motoron uses this number as its I²C address if it detects that JMP1 is not shorted to GND when it starts up. The default EEPROM device number is 16.

Although this command can write to any byte in EEPROM, we recommend that you only write to the EEPROM device number (offset 1). The byte at offset 0 is used internally by the Motoron, and the bytes at other offsets are reserved for use by new features in future firmware versions.

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.

#### Reinitialize

Arguments None None void reinitialize()

Command encoding:

 0x96

Description:

This command resets most of 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 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, and direction change delays for each motor are reset to 0.

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 None 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 variablesOffset: the address of the first variable to fetchLength: the number of bytes to fetch, from 1 to 32 The requested bytes 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 variablesOffset: the address of the variable to set (only certain offsets allowed)Value: the new number to store in the variable (14-bit) None 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 None 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 None void clearMotorFault(uint8_t flags = 0)void clearMotorFaultUnconditional()

Command encoding:

 0xA6 Bit 0: unconditional

Description:

If any of the Motoron’s motors are currently experiencing a fault (error), or the unconditional argument is true, this command attempts to recover from the faults.

For the Motoron M3S256 and M3H256, 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.

#### Clear latched status flags

Arguments Flags: 10-bit value None 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 None 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 bufferedMotor: a motor numberSpeed: from −800 to 800 None 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 mode0xD2 for now mode0xD4 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 bufferedSpeed for each motor: from −800 to 800 None void setAllSpeeds(int16_t speed1, ...)void setAllSpeedsNow(int16_t speed1, ...)void setAllBufferedSpeeds(int16_t speed1, ...)

Command encoding:

 0xE1 for normal mode0xE2 for now mode0xE4 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 None void setAllSpeedsUsingBuffers()void setAllSpeedsNowUsingBuffers()

Command encoding:

 0xF0 for normal mode0xF3 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 nowMotor: a motor numberBrake amount: from 0 to 800 None void setBraking(uint8_t motor, uint16_t amount)void setBrakingNow(uint8_t motor, uint16_t amount)

Command encoding:

 0xB1 for normal mode0xB2 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 None 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.

#### 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 serial protocol error.

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 is a reserved command byte that should not be used during normal operation.

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.

(702) 262-6648
Same-day shipping, worldwide