How to use UART on Odrive

Dear All,
I am having issues with controlling the Odrvie Pro via UART. I can set up and control the motor via USB when I am using Python with the odrivetools.

I want to control Odrive via UART from the STM32 board. I activated USART on STM32 and connected the boards as follows:

  • STM32 RX (PA10) ← UART TX G13
  • STM32 TX (PA9) → UART RX G12
  • STM_GND - ISO GND
  • STM_3.3V - ISO VDD

I set up the Odrive according to the instruction located here: [Odrive - UART Configuration] (UART Interface — ODrive Pro Documentation 0.6.4 documentation); thus:

odrv0.config.enable_uart_a = True
odrv0.config.gpio12_mode = GpioMode.UART_A
odrv0.config.gpio13_mode = GpioMode.UART_A
odrv0.save_configuration()  

I developed a simple code for the STM32 to send velocity commands:

  char buf_uart2[40] = {'0'};
  while (1)
  {
	  sprintf(buf_uart2, "v 0 2\n");
	  HAL_UART_Transmit(&huart1, (uint8_t*)buf_uart2, sizeof(buf_uart2), HAL_MAX_DELAY);
	  HAL_Delay(500);
  }

I tried to activate the closed loop mode in the velocity loop via Python. Is it okay to expect that both interfaces will work at the same time?

odrv0.axis0.requested_state = 8#closed loop control
odrv0.axis0.controller.config.control_mode = 2#velocity mode

It does not work, and I do not know why. I connected USB (PC with Python) and UART at the same time. Is it allowed? Any help will be appreciated.

Do you have a scope? Do you know if you are getting a response?

Also, did you reassign the GPIO0 and GPIO1 to a standard IO pin? There is an example in the odrive docs.

Also, you could try some form of UART sniffer program on your PC to listen to the Tx and Rx lines.

Lastly, is your baud rate 115200?

I think both interfaces can work concurrently. Should be easy enough to try, but it works on my Odrive 3.6.

I am also looking for an answer on this. I am trying to control via esp32 following the YouTube video https://www.youtube.com/watch?v=OGZaya6PvBY I also followed the getting started document. I don’t see anything referencing reassigning gpio0 and gpio1. I am trying to use the Arduino library here. https://github.com/kylebme/ODriveArduino/blob/master/examples/ODriveArduinoTest/ODriveArduinoTest.ino

I used two UARTs from my microcontroller, dedicating one port for each Odrive Pro.

@loren can you provide some details on hookup and settings? thank you

What do you need?

I just declared them as Serial1 and Serial2, bypassing the Arduino-Odrive library.

Serial1.begin(115200); // Odrive Pro 0
Serial2.begin(115200); // Odrive Pro 1

Serial1 << "w axis0.controller.input_pos " << Pitch_Pos << “\n”;
Serial2 << "w axis0.controller.input_pos " << Roll_Pos << “\n”;

It’s ASCII format.

thank you, I switched from uno to mega and used hardware serial instead of software serial and got it talking.

1 Like

Excellent!

@Loren
Just to make sure, that way you didn’t need to import any library ? simply concatenate the command with a “w” at the begining and everything works just fine ?

Just to make sure,

in that message, there’s no “=” sign ? and what does the << sign means/do ?

Thanks

You probably do not need that library, but no harm in including it.

The serial port out to the Odrive on my code looks like this:

Serial1 << "w axis0.controller.input_pos " << Pitch_Pos << “\n”;

The << symbol is a C program stream direction construct. It essentially directs what is to the right of the symbol to the object that is on the left.

The “w” is part of the Odrive language syntax. More examples and details of the ASCII syntax are found in the Getting Started section of Odrive documentation.

@Loren Finally, do you know how to clear the errors via UART ?
I tried with the following :

odrive_serial << "w odrv0.clear_errors()" << "\n";

or

odrive_serial << "w odrv0.clear_errors" << "\n";

But it doesn’t work. I didn’t find any command in the list of UART commands.
Also, I know that my connection is good, because I can control my motor in torque mode and I don’t get the watchdog timeout error, hence I know the controller constantly receives a command.

odrive_serial << "c " << 0 << " " << 5.0f << "\n";

thanks