Controlling ODrive from ESP32 via UART

Hi,

I want to try the example found here: Controlling ODrive from an Arduino via UART — ODrive Documentation 0.6.9 documentation
But I want to do it by using an ESP32 instead of an Arduino Uno (I already tried with an Arduino Uno and it works). For UART, I connected pins 16 and 17 of the ESP32 to my ODrive S1 and I am using Serial1 with baudrate of 115200 in the code. I have changed the baudrate accordingly in odrivetool too. In the Arduino IDE, I am able to verify the code (after removing the include of the SoftwareSerial) and upload it, but nothing happens afterwards. Do I have to change maybe other parameters in the odrivetool than the ones mentioned in the uart guide ?

I believe pins 16/17 are Serial2

I already tried Serial2 too, but it doesn’t work.

Do you have a logic analyzer or oscilloscope you can use to see if the ESP32 is actually sending? Can you post your code?

After putting the scope of the oscilloscope on the Tx, I get this:


And after putting the scope on the Rx, I get something very noisy but after pressing on “stop” on the oscilloscope, I have this:

This is the code that I am using on the Arduino IDE:

#include <ODriveUART.h>

// Documentation for this example can be found here:
// Controlling ODrive from an Arduino via UART — ODrive Documentation 0.6.9 documentation

////////////////////////////////
// Set up serial pins to the ODrive
////////////////////////////////

// Below are some sample configurations.
// You can comment out the default one and uncomment the one you wish to use.
// You can of course use something different if you like
// Don’t forget to also connect ODrive ISOVDD and ISOGND to Arduino 3.3V/5V and GND.

// Arduino without spare serial ports (such as Arduino UNO) have to use software serial.
// Note that this is implemented poorly and can lead to wrong data sent or read.
// pin 8: RX - connect to ODrive TX
// pin 9: TX - connect to ODrive RX
// SoftwareSerial odrive_serial(8, 9);
// int baudrate = 19200; // Must match what you configure on the ODrive (see docs for details)

// Teensy 3 and 4 (all versions) - Serial1
// pin 0: RX - connect to ODrive TX
// pin 1: TX - connect to ODrive RX
// See Teensyduino: Using the UART (real serial) with Teensy on the Arduino IDE for other options on Teensy
HardwareSerial& odrive_serial = Serial2;
int baudrate = 115200; // Must match what you configure on the ODrive (see docs for details)

// Arduino Mega or Due - Serial1
// pin 19: RX - connect to ODrive TX
// pin 18: TX - connect to ODrive RX
// See Serial - Arduino Reference for other options
// HardwareSerial& odrive_serial = Serial1;
// int baudrate = 115200; // Must match what you configure on the ODrive (see docs for details)

ODriveUART odrive(odrive_serial);

void setup() {
odrive_serial.begin(baudrate);

Serial.begin(115200); // Serial to PC

delay(10);

Serial.println(“Waiting for ODrive…”);
while (odrive.getState() == AXIS_STATE_UNDEFINED) {
delay(100);
}

Serial.println(“found ODrive”);

Serial.print("DC voltage: ");
Serial.println(odrive.getParameterAsFloat(“vbus_voltage”));

Serial.println(“Enabling closed loop control…”);
while (odrive.getState() != AXIS_STATE_CLOSED_LOOP_CONTROL) {
odrive.clearErrors();
odrive.setState(AXIS_STATE_CLOSED_LOOP_CONTROL);
delay(10);
}

Serial.println(“ODrive running!”);
}

void loop() {
float SINE_PERIOD = 2.0f; // Period of the position command sine wave in seconds

float t = 0.001 * millis();

float phase = t * (TWO_PI / SINE_PERIOD);

odrive.setPosition(
sin(phase), // position
cos(phase) * (TWO_PI / SINE_PERIOD) // velocity feedforward (optional)
);

ODriveFeedback feedback = odrive.getFeedback();
Serial.print(“pos:”);
Serial.print(feedback.pos);
Serial.print(", ");
Serial.print(“vel:”);
Serial.print(feedback.vel);
Serial.println();
}

I also measured the signals on the Tx and Rx when using the Arduino UNO with the example to compare with something that works and I get the following results:

Tx Arduino UNO:


Rx Arduino UNO:

I measured again the same signals but with using the ESP32 and I get different results than the ones I sent in my previous post. Actually, I am getting very unstable signals this time:

Rx ESP32:


Tx ESP32:

Could the cause of this problem be that the 3.3V of the ESP32 is not enough compared to the 5V of the Arduino UNO? Or is there something hardware specific to the ESP32 that causes this?

Just checking - how are you wiring to the ODrive? How is ISO_VDD and ISO_GND being connected? Can you sketch a wiring diagram?


On the left is the stuff coming from the ESP32 and on the right are the connections to the ODrive IO J11 of the ODrive S1. I have done the measures of my previous post on the TX and RX with and without the 2 resistances, but I get similar unstable signals in both cases.

Why do you have 6kohm on the GPIO17/GPIO16? What’s the point of those?

Someone else set it up and told me the resistors were there to protect the ODrive from a ground loop. He said he followed the guidelines of your website about this problem. I wasn’t sure why the resistors were there initially either so I measured the TX and RX on the oscilloscope after removing those resistors and I still get unstable signals.

Hm, yeah ground loops shouldn’t be an issue if properly wired.

Can you confirm that the ISO_VDD to ISO_GND is actually getting the 3v3 power? I’m wondering if it’s miswired, or if there’s an issue with the ESP32.