FOC PART 4: More Hardware Debugging!!!

The Motor Science Rig.


When I left off last time, I had bestowed the ADCs with capacitor-based magic which caused them to function properly. The next step was to hook up the current sensors and forcefully request that they, too, function properly.

Wary of hardware problems, I collected some data before jumping straight to current-mode FOC. Through this data I was able to see hardware problems and correct them before they made FOC difficult. All the hardware must function properly before FOC can be attempted, otherwise it is likely that the FOC will work badly or not work at all.

I got pretty good at taking data from the motor controller and converting it to graphs using Python. I used PuTTY as a serial terminal, and copied the data into a numpy array in my python program. I used Sublime text as my text editor and ran the python program in the command prompt. Later, I further streamlined this process by wiring in a switch to turn on and off my printfs (blue switch in the above picture!!!).

First I took a plot of current on A phase (blue) vs electrical position (green). This data was taken with voltage mode commutation.

adc vs position 1, full duty cycle

Aaaaannnndddd something is wrong here. Instead of the current forming a nice sinusoid, a double peaked “butt” is present on the top of the cycle. What?

I decreased the modulation depth from 100% to 78%, which helped the issue:

adc vs position 3, 2.55f

Further decreased to 72%, which mostly solved the issue.

ADC1 vs ADC2 2.75

But, what is actually going on here?

It turns out that the Allegro current sensors I am using are only rated for a bandwith of 120kHz, and have a response time of about 4 microseconds. This is really, really slow. At above 75% duty cycle this rise time would eat into the time when the current was being sampled, therefore cutting off or even removing any current measured past that time. Below is a plot of the oscilloscope at about 85% duty cycle. The current is measured at the rise of the purple trace, and as you can see the current sensor has not had time to respond at this high duty cycle.


The best solution I could find at this point was just to limit the modulation depth to 70%. This was good enough for testing.

The next test was to move up a level in complexity and directly measure the d and q currents. Ideally, with my voltage mode commutation, the d would remain at a constant of zero current and the q would remain at a fixed value while the motor is rotated.

I did these next tests by first initializing the controller, then running 5 amps through the motor and slowly rotating it by hand for a couple electrical revolutions. Red is electrical position, blue is Iq, green is Id. I’ve scaled the axis so everything fits on one graph, so the numbers don’t really mean anything.

8 d,q vs position correncted offset

Again, something is wrong. I probably would not have caught this error had I just been looking at the numbers, but as you can see in this graph, Id and Iq both have a periodic oscillation. This effect was conserved over multiple tests.

10 d,q vs position correncted huh

I had a hunch that this effect may have been caused by periodically inaccurate current measurement on the A and B phases, leading to larger periodic inaccuracies in the calculated C phase current. I logged data from the A and B phases and calulated the C phase current in python. These three currents would ideally be three perfect sinusoids of equal magnitude, 120 degrees out of phase. In this plot, blue and green are measured A and B currents, and red is calculated C current.

11 the three currents

The calculated C current is clearly different, as it has a higher magnitude than it should. This is not correct, leading to problems with Id and Iq. The question was, what to do about this? I had already reduced the modulation depth to 70% and did not really want to go any further.
The version 3.1 controller board originally used high side shunts, which had not worked due to low common-mode voltage during testing. I had soldered in ACS758 current sensors in where the high side shunt resistors used to be, as I had them laying around. I put them in on the high side as I wanted to test whether allegros were fast enough to be used on the high or low side, as the planned permanent solution was to use the ACS722 current sensor as a low side shunt on the bottom of the board. Ideally the allegros would go straight on the phases, but with my board layout this would mean extending the board by 10mm to make space on the top side. These tests proved that the allegros were really not fast enough to be used as either a high or low side sensor at 20kHz switching frequency, so I got out the weller and moved the allegros to the phases.


After the mod. notice how the bottom two phase wires (A and B) go through the current sensors. Also, I installed a 150uf electrolytic (the black one) on the bus to damp a mysterious 40kHz oscillation. While it probably doesn’t actually have that much capacitance at 40kHz, the oscillation was removed. Harware bugs beware: you will be removed by force.

I repeated the earlier “log and calculate C current in python” test.

12 current sensors moved to phases

Looks a lot better!!! Some odd artifacts were still present at the tops and bottoms of the waves, so I reduced the deadtime from 8 to about 4 microseconds, which further improved results.

16 looks pretty sinusoidal

Yay, nice sinusoids!!
Next was to play a bit with the transforms. The Iq oscillation was gone but the Id oscillation persisted:

13 d,q vs position better

Turns out I had the current sensors inverted and the motor running backwards. With these problems fixed Id and Iq both look really great. Id isn’t perfect, but I believe this to be a measurement error. Its pretty small so I’m just going to ignore it for now.

17 im happy

Current-mode FOC, here we come!!!!