Sin/Cos encoder?

So I got this DJI motor that has an internal encoder that outputs one sin and one cos signal (phase shift with each other) they cross 7 times per motor spin. DJI has an asic to drive the motor in FOC and reads the encoder from 0-8000ish (they claim to be physical angle), I saw there is a pull on github about SPI encoder, so there might be a chance that if I can have a separate microcontroller to spit out data (angle)?

So right now I have the AMT10x encoder and it works beautifully but I want to use the internal encoder so it’s smaller and mechanically better.

1 Like

Oh cool, I didn’t know that was a thing. Do you have any more info on this that you can link to?

Are the signals in 0 to 3.3V level? If so you may be able to hook them up directly to the ODrive, and just add the decoding firmware. We have general-purpose ADC sampling implemented in this PR.

should look something like this, they have the encoder inside the motor and it’s hard to remove that to see exactly what they use. But I used scope and getting the waveform that pretty much sine and cosine (phase shift each other), the level might be 0-5v. so voltage divider i guess?

Yeah a divider and maybe a small filter cap close to the ODrive to keep noise out, making sure the RC time constant of the divider resistors and the cap is suitable.
Then just add a case statement here for analog SinCos input. You may need to also have it have some virtual CPR so the other parts of the code work correctly, say 8k or similar.

Did more testing. the encoder spits out sin and cos 90 degrees shift depends on the rotating direction. the voltage varies from 1 to 2v. Made an arduino code and it works pretty well to track the counts. gonna try to integrate with ODrive now.

1 Like

How often does encoder::update() gets called and where is it being called?
int16_t delta_enc_16 = (int16_t)hw_config_.timer->Instance->CNT - (int16_t)shadow_count_;
so the timer->CNT will get cleared somewhere? or the timer->CNT will keep all the encoder steps, what if it overflows?

And it seems like the fw4 branch doesn’t do the calibration at startup? I am using a mac and the odrivetool detects the odrv0 and disconnect very soon if it’s not being actively used.

All of the following pertains to the branch fw4. The closed loop control runs in a loop which is part of a function in axis.hpp called run_control_loop. This loop runs at about 10kHz right now and executes all control loops. It calls do_updates which is in axis.cpp, which in turn calls Encoder::update().

In the code timer->CNT will overflow and wrap around. This is why we have the shadow count and circular counts. The trick is that we compare to (int16_t)shadow_count_, so the subtraction will “unroll” the overflow and it works still when rolling around the overflow.

Yes fw4 is new and not released yet, sorry there is not much documentation. You must send odrv0.axis0.requested_state = 4, then = 7 then = 8. Have a look at axis.hpp to see the states.

It works! thanks for the help! One thing to know is the ADC reading on stm32 is convert to 0-3.3 float. but reads differently on the odrivetool.

@Steven_Sun Do you have a picture of the unit? Or maybe a link to where you go it?


motor i have is this one:

i don’t know the specific model of the encoder but it outputs sin/cos signal.

@Steven_Sun awesome, thank you!

Did you ever release any code for your sin/cos encoder interfacing?


Has somebody has used this type of encoder??? supports Sin/Cos encoders

Hi Guys…
Wanna ask about the M3508 P19…
Since you guys have already figured out the sin/cos encoder mystery,
can you guys share the pin out for the 7-pin?

I emailed DJI and they said it is “confidential” stuff and refuse to provide further information.

1 x Hall sensor (I guess?)
1 x Sin Cos encoder (Tested by your guys)

But which wire is which wire???



Sin /cos encoders are normally used on professional systems like cnc milling machines etc.
The allow for interpolation of the waveform .
They give much greater accuracy than the quadrature phase type and work very well at low speeds.

For Instance I have one that has a nominal 10 micron accuracy and with 5 x interpolation it gives 2 microns .
Its probably worth quite a lot of money.


@Wetmelon @madcowswe

How much work would it take to create encoder linearization logic? It seems that with a multipole ring/tape this is the only difference between current sin/cos support and industrial level product like @gasmeter mentioned .

IMHO there is much benefit to support sin/cos encoder with greater precision:

  • lower cost compared to ABZ/SPI encoders
  • potentially better response time and better precision since there is more compute resource on ODrive board than a low power SoC

The challenges seem to be signal strength (most sin/cos chips don’t output to 3.3V which is what it takes to get the full 12 bit of ODrive ADC?) and reliable calibration source.

Is it possible to extend the anti-cogging code to solve for both harmonics in cogging torque and harmonics in encoder nonlinearity?

sin/cos encoders have a wiper, so they are much noiser and far less reliable than the common magnetic/optical encoders.

If it is moving, then the delay between reading the sin and cos A/D converters becomes a problem

so I would expect them to be less accurate, and more timing sensitive than ABZ encoders

What is a wiper?

For reference I was looking at these chip level sin/cos encoders:

Most of them have an amp and a driver between the bridge circuit and the output pin. The delay should be <<10us.