I2C communication Arduino <-> ODrive


Hello guys,

I am a new oDrive (v3.5, 48V) user, and really happy with how it works and how well communication goes with the native protocol and the ASCII protocol.

I’ve found this Arduino I2C library, but can not wrap my head around how to implement it, so until now I haven’t tried if it works from scratch because I do not know what it will be doing.

Via the oDrive Tool, I have activated I2C with

enable_i2c_instead_of_can = True

but still get back a

  addr = 0 (int)
  addr_match_cnt = 0 (int)
  rx_cnt = 0 (int)
  error_cnt = 0 (int)

I also tried to change the address manually by typing

In [12]: odrv0.system_stats.i2c.addr = 104

which is not a valid command.

Would appreciate any advice to get I2C running, so I can try out the commands specified in the Arduino library.
Unfortunately I am not familiar with STM32 programming.

Thank you very much!


Just a guess, but did you try rebooting your ODrive? Found this here: https://github.com/madcowswe/ODrive/blob/3113aedf081cf40e942d25d3b0b36c8806f11f23/Firmware/communication/communication.cpp#L157.

Maybe try “odrv0.reboot()”. Otherwise, reach out to those on the “Support” channel on the discord chat (here: https://discordapp.com/channels/369667319280173067/369678934985408524).


Makes sense! :slightly_smiling_face: Now it works. Thank you very much.


Ok now I will come up with some new questions.

  1. In the Discourse #support chat, Oskar mentioned that one has to ‘desolder the can tranciever and make two bridge connections’, and I understand that this is for I2C. Right?
    So it is impossible to use I2C out of the box? Or am I getting something wrong?

  2. I’ve tried using the I2C. The odrivetool I2C stats are

    addr = 111 (int)
    addr_match_cnt = 0 (int)
    rx_cnt = 0 (int)
    error_cnt = 0 (int)

and when using the available Arduino I2C library and the example, so I guess I have to put

byte odrive_num = 7;

because 111 (dec) = 1101111 (bin) = 1101xxx + 111 (bin) where 1101000 is defined in Arduino/ArduinoI2C/odrive.c

static constexpr const uint8_t i2c_addr = (0xD << 3); // write: 1101xxx0, read: 1101xxx1

Anyway I also tried with address odrive_num = 6, leaving out the read bit (LSB = 0).

Whatever address I put, I get the following result: Oscilloscope shows exactly the same signal (the 100 kHz clock signal) on both lines, exactly the same amplitude and phase.
Ia am using a Mega2560, with connections


Connected to another Arduino, my Mega2560 talks proper I2C :slight_smile:

I tried also to switch the odrive on-board switch to CAN NO R, which just gave worse results (no clk at all).

The reason why I want to use I2C is a position update rate higher than 200 Hz for two motors, which I achieved with 1,000,000 Bd/s UART via ASCII protocol.

A hint where to work on or where I missed something would be awesome!!