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!

1 Like

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.

1 Like

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!!

1 Like

With respect to your #1, I’d say that: yeah, he means you’d need to desolder the CAN IC (using a heat gun), then bridge the CAN H and L connections, such that when you hook up the CAN headers (schematic here: https://github.com/madcowswe/ODriveHardware/blob/master/v3/v3.5docs/schematic_v3.5.pdf), you are directly addressing the pins on the STM32 (which you enable using the function you previously experimented with). So…no, the I2C doesn’t work right out of the box - it requires some modification.

I’m not sure how to get it to work any further, as I haven’t played around with it yet or investigated it much myself. I’m going to play with it a bit right now, and spend more serious time looking into it tomorrow. I’m interested in perhaps using I2C to talk to multiple ODrives from a Mega, and am curious if that level of functionality exists and would work.

1 Like

As I understand, for I2C communication, it is needed to remove the CAN transceiver (UI – VP232 chip) from the board and connect CAN D line to CAN H and CAN R line to CAN L. Then we can use I2C communication with Arduino or any other board with connections;

Am I correct ? :thinking:

Hi!! This thread has been really helpful I need an i2c connection for a project I am working on but i have v3.6. I was hoping if you or anyone on this thread can help me out. Do I need to desolder the CAN H and CAN L connections on 3.6? I can’t find them. I think this board is slightly different and theres no schematic on github.

You have to desolder the CAN transceiver, yes. It’s basically identical to the 3.5

Might I suggest that you guys invest in a CAN transciever for your Arduino?
It would be a lot simpler. :stuck_out_tongue_winking_eye:

no kidding haha! however, it’s been a good learning experience. for the next ODrive project I pursue I’ll be looking into this for sure