InlineCurrentSense question


I’m trying to use the InlineCurrentSense class with my drv8305, which has low-side current sense.

From the docs, SimpleFOC does not support that yet, I’d like to add support. Any hints appreciated. @Antun_Skuric?

Just read this:

So I understand I will need very timely ADC reads. I think that means DMA ADC setup… moving there, then

The main issue at the moment is very hardware specific synchronisation procedure of the PWM generation and ADC triggering. Therefore it is possible that this implantation will be done one MCU architecture at the time.

Its needed to sync the PWM and ADC, read the current at the specially moment when the FET is on.

I made good progress today, adding dma-adc to my samd21 setup. The thing is, as Antun puts it, it’s rather hard to interpret, at least without a proper diagnostic/plotting setup, which I plan to build also. I will unfortunately need to move away from the commander/Arduino constraints momentarily to achieve something, but I hope to move claw back to an MCU agnostic after

Found some time again. turns out the adc readings I had were completely off. it is now fixed. I use drv8305’s vcc as AREF and I now get (3.3/2) 1.65V-centered readings from each drv8305 input sense pins.
These are 1.65-centered since they measure negative and positive currents. All measure via DMA/async readings. Tomorrow, if I find the time, I’ll plunge into theory as to how to use it. any help appreciated.

Hey @malem,

yep so DMA + ADC is the way to go. Or at least Timer interrupt based ADC conversion synchronized to the PWM output.

I am working on it at the moment also. We are interested to have a stable general solution to it so it will take some time and it will most likely be very incremental. :smiley:

Its so cool to see how fast are you progressing!
I’d be very happy to see your code also, it could help us to jumpstart the support.

Once you scale your ADC voltages to the current values using the resistor value and the amp gains that will be more or less it. The current control software is already implemented. You can extend the CurrentSense class and provide it to the motor once you’ve implemented the init() and getPhaseCurrents(). You can use the InlineCurrentSense as a template. I’m writing the LowsideCurrentSense class now and it should be available soon in the dev branch.

Yes, let me tidy-up things a bit and I’ll post a link. Do you think the voltage to amps formula will be common to all drivers or driver hardware specifc? I haven’t dived into that yet. Can’t wait to see and try LowsideCurrentSense.

Here is the file

Not quite sure about the API yet. I’m a big fan of letting the API settle as we use it for real. I’m waiting for your LosideCurrentSense. I have one right now but it’s an empty cut&pasted shell

(Oh, and this class assumes you fixed samd’s variant.cpp for the ADC pins you use. I plan to submit a patch to Arduino for this samd21 variant.cpp problem, @runger hit this problem too )

Should we create a new thread <<<LowSideCurrentSense>>> for that topic? I am very interested in testing it as I am currently making a design decision. I have TI’s DRV8323RS fully assembled but it’s been sitting and waiting for it.

Hi Antun, first of all I want to thank you for your incredible work.
I am using the MP6540H by MPS - it’s a BLDC driver with low side current sense amplifiers. I also use the nucleo L432KC which has a 12 bit ADC. therefor in the setup i use:

I have calculated the current on each of the analog pins to be:
float curr1 = ((((float(float(analogRead(A0))/4095))*3.3)*2)-3)*1.84;
float curr2 = ((((float(float(analogRead(A1))/4095))*3.3)*2)-3)*1.84;

where 4095 is the full scale reading and 3.3 is the Vref
I noticed InlineCurrentSense.cpp the lines where you calculate the phase currents:
current.a = (_readADCVoltage(pinA) - offset_ia)*gain_a;// amps
current.b = (_readADCVoltage(pinB) - offset_ib)*gain_b;// amps
current.c = (!_isset(pinC)) ? 0 : (_readADCVoltage(pinC) - offset_ic)*gain_c; // amps

It seems like the current calculated is in Amps. Because:
float _readADCVoltage(const int pinA){
uint32_t raw_adc = analogRead(pinA);
return raw_adc * _ADC_CONV;

So theoratically, I can just substitute these lines:
current.a = my calculation above;
current.b = my calculation above;


Yep exactly!
The code does exactly that. :smiley:

Reads the voltage, removes the offset ( just not the static offset but the one calculated in the init function) and then scales it to get the current from the voltage.

Thanks Antun, but what about the gain sign (-1 or not) and the driver align function? Because now the gain is "0"m I don’t use it…