# Why isn't my manual DSHOT600 programming of a HobbyWing ESC not responding to direction change?

I wrote a firmware for an STM32L4 board to talk to a HobbyWing XRotor Micro 60A running BLHeli_32.

I can drive each motor indiviudally just fine using DSHOT600 by bit-blasting the signals out of GPIO with correct timings (based on NOPs for an 80MHz core). It works fine: I set up the packets for each motor, and then send them sequentially to each GPIO in a loop; until I set the throttle to zero, then I stop sending any packets.

However, the motors are not spinning in the proper direction so I am trying to issue ESC commands 7 and 8 and 20 and 21. My strategy is to STOP sending throttle packets entirely. Then I send command 7 (or 8, or 20, or 21) to each prop 10 times with 100ms between each command, and then turn the props back on with a nonzero throttle.

Documentation is super thin on this. I've found several sites saying special commands 7,8 or 20,21 should reverse the props, as well as different # of times the commands must be sent, etc. But I don't see a reversal.

Suggestions?

I would recommend taking a look at the source code for Betaflight to get some hints, since the DSHOT commands should be the same. More specifically the code for enabling turtle mode (flip over after crash), which reverses the motor directions.

It looks like the code that activates turtle mode is:

dshotCommandWrite(ALL_MOTORS, getMotorCount(), DSHOT_CMD_SPIN_DIRECTION_REVERSED, DSHOT_CMD_TYPE_INLINE);


Where DSHOT_CMD_SPIN_DIRECTION_REVERSED is the value 21 in an enum.

typedef enum {
DSHOT_CMD_MOTOR_STOP = 0,
DSHOT_CMD_BEACON1,
DSHOT_CMD_BEACON2,
DSHOT_CMD_BEACON3,
DSHOT_CMD_BEACON4,
DSHOT_CMD_BEACON5,
DSHOT_CMD_ESC_INFO, // V2 includes settings
DSHOT_CMD_SPIN_DIRECTION_1,
DSHOT_CMD_SPIN_DIRECTION_2,
DSHOT_CMD_3D_MODE_OFF,
DSHOT_CMD_3D_MODE_ON,
DSHOT_CMD_SETTINGS_REQUEST, // Currently not implemented
DSHOT_CMD_SAVE_SETTINGS,
DSHOT_CMD_SPIN_DIRECTION_NORMAL = 20,
DSHOT_CMD_SPIN_DIRECTION_REVERSED = 21,
DSHOT_CMD_LED0_ON, // BLHeli32 only
DSHOT_CMD_LED1_ON, // BLHeli32 only
DSHOT_CMD_LED2_ON, // BLHeli32 only
DSHOT_CMD_LED3_ON, // BLHeli32 only
DSHOT_CMD_LED0_OFF, // BLHeli32 only
DSHOT_CMD_LED1_OFF, // BLHeli32 only
DSHOT_CMD_LED2_OFF, // BLHeli32 only
DSHOT_CMD_LED3_OFF, // BLHeli32 only
DSHOT_CMD_AUDIO_STREAM_MODE_ON_OFF = 30, // KISS audio Stream mode on/Off
DSHOT_CMD_SILENT_MODE_ON_OFF = 31, // KISS silent Mode on/Off
DSHOT_CMD_MAX = 47
} dshotCommands_e;


Note that DSHOT_CMD_SPIN_DIRECTION_NORMAL has the value 20, and seems to be the command used to set the motor direction to normal. There is also DSHOT_CMD_SPIN_DIRECTION_1 and DSHOT_CMD_SPIN_DIRECTION_2 with the values 7 and 8 respectively, but I can't find anywhere where they are used.

Examining the definition for dshotCommandWrite we find that a variable repeats is set to 10 with the current input and that delayAfterCommandUs is set to 1000.

I would assume that this means that you should send the command 21 to the motors 10 times with an interval of 1000 μs. So I would try doing as you did before but with a delay of 1000 μs (1 ms) between each repetition instead of 100 ms.