Odrive as BMW X-drive controller


Im trying to figure out if it is possible to use ODrive to control an actuator on/off, based on max set current.

I need to alter 4wheel drive on/off through a BMW X-drive transfer case, and it uses an actuator controlled clutch.

The actuator is a bldc motor, and no encoder.
I’ve searched through litterature from BMW, and I understand that they, based on current limits, check max/min stroke of the actuator at each power off cycle.

I’d like to do the same, but I’m not as advaced as BMW, so I don’t need to stop in the middle, I only need on/off based on an adjustable current setting.

The motor turns maximum 20-25turns from full off to full on.

Is this possible with ODrive?

1 Like

You may find some inspiration from this guy: https://www.youtube.com/watch?v=NeU2C2hAI6s
He’s controlling he Odrive from an arduino and has the arduino constantly querying current level and using the results to do a tactile feedback.

1 Like


So it is not possible to set it up, directly on the odrive itself?

It has been done by a user but I don’t remember who that was exactly… It’s not natively implemented.

Picture of the actuator motor.

Do you have hall sensor feedback? You will need it to use ODrive.
You can just drive a fixed velocity for a fixed time: if it hits an endstop it will drive into it with the current limit. You can then switch into position control if you want to hold it there (or a little away from it to not use too much current).
You will have some external logic board or PC connected? How will you send the actuation command?

Hi Oskar! Thanks for stepping by! :slight_smile:

I don’t have any feedback sensor, but I will look into possibilities to install one.

Actuation command will come from switches in the car, through an arduino, if needed (if I can’t trigger it directly at the Odrive board.

Another option is to run until “max set current” (record steps) on initialisation at first power up. Then switch to position mode in operation, for more precice control.

Yes, if I free up the axle, it will start spinning in reverse, and releases the tension of the clutch, so I need some holding power when stopped.

If I’m modifying the cover for the motor, I may be able to install an encoder like this, will it be compatible with odrive?

That one is too high of a voltage. Look for “open collector (NPN)” encoders

Like this one?

1 Like

That one should work well.

1 Like

Ah, good!
Looking forward to get the parts, and start figuring out things.
Now with the encoder, I can setup a calibration routine to find the max clamp force, and rely on the position for the rest of control.

Since the encoder is marked with ABZ pins, I assume it has the Index pin.
If so, I can store this in the controller, and make it return to this position each power up, and the start the position control from there?

Should be possible to do that. One thing to be aware of is you likely can’t have too much mechanical load on the rotor while the odrive is doing its index search. Before the index is found the odrive has to use an open loop vector rotation in order spin the motor. If there is too much of a load the rotor won’t stay locked to the field rotation. If this won’t work for you then you may need to look into using an absolute encoder. There is currently only beta support for running with an absolute encoder.

Hi folks!

Now that I see that there is a CAN-BUS protocol available, I think it would simplify my hardware bit, and put more work into the software.

As mention in earlier posts, I’d like to make the o-drive do startup routine, where it first goes slowly CCW, until it is blocked (by hardware) then run at “medium” speed until it reaches a set current of f.ex 10A, while counting the revolutions from a hall effect encoder (separate board, but same encoder chip as BMW uses, ENC2b from this site: http://techref.massmind.org/techref/io/sensor/pos/enc/ENC2.htm ), and store it as 100% lock.
When this is done, I want it to return to 50% of the revolutions and idle there.

Is this possible on the O-drive, or do I need a separate controller til take care of this startup routine?

After that, I will send position data to it over CAN-BUS, sent it to open fully (0%) or lock (100%).
The control logic I can setup in the cars ECU (MaxxECU), or in my multifunction screen (ECUMASTER ADU7).
Different conditions will be set by a rotary switch (2wd, 4wd AUTO, 4wd LOCK) and conditions will vary based on handbrake state, TPS pos. etc.

Today I 3d printed an adapter to hold the encoder board in place over the axle/magnet.

The fun has begun!

During the getting started guide, I get the ERROR_CPR_OUT_OF_RANGE error.

The motor I have does not have a datasheet, it’s a motor developed by BMW for their own use.

It has 8 permanent magnets (4 pole pairs), and 12 coils around the motor.

How can I determine the PPR?

CPR of my encoder is 4000, that is for sure, so I’m mistaking the motor setup to be incorrect.

I count 24 “notches” when doing a full round manual rotation, I guess because it’s 12 coils.


The seller must have shipped incorrect encoder, as it worked with 360cpr.

Now, with calibration stored, in closed loop control, it idles like this:

What to tune to avoid this?

That looks like cogging to me. You can try the anticogging, or you can increase the gains to compensate for the cogging torque.

360cpr sounds low. You’ll want to use an Arduino or similar to flash the correct firmware to that AS5047P to get the 4000cpr.

Cogging is when the permanent magnet force pull to the coil cores?

I tried some tuning, but ended up either some very small vibrations, or weak holding torque.

360CPR is way too low to get good controllability at low speeds with any motor, especially one that has a high cogging torque.

You might get better resolution using the SPI interface of your encoder instead of incremental (you also won’t have to do offset calibration or index search on startup)

To use SPI with this encoder, you need Wetmelon’s RazorsEdge branch

Thanks for enlightening me :slight_smile:

But for this application, 1deg resolution is plenty enough, and as soon as I apply some friction to the screw, maybe the cogging is not an issue.

I just don’t want to complicate things more than necessary. This is my first touch with ODrive, and will include CAN-BUS too, so I’m already fully booked on the learning curve :stuck_out_tongue: