How to deal with Switching Noise?

I am finding the high pitched switching noise of the ODrive very unpleasant.

What I would like to do is have the ODrive automatically switch to IDLE when the motor reaches a halt, and switch back to CLOSED_LOOP_CONTROL only when it needs to. That way I won’t have to hear it whistling while it sits there; it’ll still happen when in motion, but at that point there are usually other noises that hide the sound.

Unfortunately I need the motor to respond to changes quickly - in the order of milliseconds.

So what I did was create my own thread in the firmware, that runs once every millisecond (with priority one less than the axis’ thread so it never gets in the way.)

In that thread I have this code:

    if (no_activity_needed){
        if (axis_->current_state_ != axis_->AXIS_STATE_IDLE) axis_->requested_state_ = axis_->AXIS_STATE_IDLE;
    } else {
        if (axis_->current_state_ != axis_->AXIS_STATE_CLOSED_LOOP_CONTROL) axis_->requested_state_ = axis_->AXIS_STATE_CLOSED_LOOP_CONTROL;

However, even though this code runs every ms, the axis’ state isn’t keeping up. There is a perceptible pause before the CLOSED_LOOP_CONTROL kicks in, and that’s more than enough to ruin the performance.

Does anyone know if there’s a faster way to set the state than the way I’m doing it?

Or, alternatively, can anyone tell me if there’s a reason it can’t go faster than that? That would suck but at least it would save me from sinking any more time into it.

In general, does anyone have any ideas on how to minimise that switching noise? I am assuming it comes from the DRV module and nothing can be done about it - I would love to find out I’m wrong about that!

I have done a bit more reading and apparently the noise I can hear is more likely to be the 8kHz current measurement than the DRV switching.

I’m assuming this measurement is tightly built into the control loop? I was wondering if I could somehow stop the readings while still in CLOSED_LOOP_CONTROL and just use the last measured values - until I detect motion from the encoder, at which point I’d start the readings again.

That would save us having to keep changing modes between CLOSED_LOOP_CONTROL and IDLE, which doesn’t seem to be happening fast enough.

On the other hand, I didn’t want to mess around too deep in the internals of the firmware, and this feels like playing with things I don’t understand.

Yes, unforutnately. The interrupt from the ADC tells the controller a current measurement has completed, which kicks off the entire control loop (it does nothing until the current is sensed).

ODrive v4 is going to probably be 24kHz current sampling, so it should get quieter.

Thanks for replying, @Wetmelon.

Maybe I’ll leave it for now then. I’m having other, SPI-related problems right now anyway.

Does ODrive v4 have any ETA, and if so, how far off is it?