Motor Controller: Board 5!!!

When we left off last time, I’d dealt with a bunch of issues with misused current sensors. Here is a photo of the lovely Motor Science Rig in all its glory, taken with Bayley’s ViewCamera.

DSC00755

With the current sensors installed properly, it was time to move from voltage-mode FOC to current-mode FOC. I had some minor issues doing this, but once I got all the variables correctly assigned and the correct signs on Ben’s transforms, it just fired right up. With current-mode control running, I wrote a bang-bang position controller, and then a PID controller. Here is a video describing recent events.

I tested out the AS5047, a magnetic position sensor which I will be using on future motor control experiments. I mounted the sensor to using an XYZ micrometer stage to center it precisely on the motor. Performance was satisfactory and I was able to do a bit of testing on how critical the centering of the chip was and how close it needed to be to the magnet. I determined the sensor will output garbage when placed greater than 3mm from the magnet.

IMG_4278

A huge milestone has been reached, servo control is running, and it seems to even work. With that running I began work on a new PCB. This will be board 5, hopefully this one works…!

I discussed options for current sensors with Ben and Bayley and the ultimate decision was low side shunts. I selected INA181A1 bidirectional current sensors, planning to use them on the low side (although they are high-side capable up to 26v). I sampled these from TI and as usual they arrived very quickly. Concurrently, I designed this board:

board

I also did some calculations on how much power the board would be able to take, based on the stats from the IRSM005 fets. The datasheet lists these specifications:

stats

I estimated that by heatsinking the top of the fets (which are unfortunately plastic) I could probably get a thermal resistance of 10 degrees C per watt, as a conservative measurement. I decided a maximum desired board temperature of 125 F, leaving 2.5 W of power dissipation. However by this math I’ve got a maximum current of only 22 continuous amps, which is pretty bad. I am hoping that I can heatsink the copper on the board as well, and hopefully this will further improve performance. It also really hammers home that amps make heat but in terms of controller heating, voltage does nothing. For CNC applications, Ideally I would use a motor that was wound so that at my maximum desired rapid speed, the backEMF of the motor is very close to my supply voltage. I may try and change the NTM propdrive motors from delta to wye to increase the torque, basically for free as I am operating them in a very low speed regime.

To go with the new board I designed up a little servo module. This module will hopefully replace the Motor Science Rig as my primary experimentation platform. It also may be what I mount to my CNC. I did a lot of the design around the PCB. I also made up a little AS5047 breakout, which factored into the design.

1lotadesign

FAST FORWARD TWO WEEKS! One week of PCB delivery time, and one week of me actually having a life and doing stuff other than motors.

The board arrived and I populated it. I attached it to a test 3d printed version of the motor module back plate. Everything fit quite nicely!

IMG_4332

The board itself.

IMG_4333

Motor power and Logic power wires attached. LED works too!

IMG_4340

A couple minor code tweaks (changed the current sensor ordering and the encoder offset) and the motor spun, for now in voltage mode.

IMG_4341

The way I found the theta offset on this board was new. I drove the motor forward and backwards in voltage mode at 0.5 Hz and tuned the theta offset until the current draw was the same in both directions.

Next up was switching from voltage mode to current mode. In order for this to work, I needed to enable the current sensors. In this revision of the board I had switched from high side shunts to low-side shunts. This meant I had to invert the center-aligned PWM such that the low side is on when the main interrupt fires and the ADCs read the current sensors. Easy, right….?

Nope. Many pages of datasheet later, no luck. The 6 PWM outputs are controlled by the TIM1 timer, which it turns out is exceedingly complex (especially to someone who is new to this stuff). My first strategy was to simply un-comment some code which Ben had left in his Dyno controller code, marked with the comment”Interupt when low side is on”:

TIM1->CCER |= ~TIM_CCER_CC1NP;

This caused the current sensors to sort of work, but with some odd behavior. The controller also started to draw a lot of current. It turned out that I had inverted the outputs of the 6 PWM channels, which caused the dead-time to become undead. In this oscilloscope screen grab I scoped the gate drive inputs to one of the fets. Yellow is high side and blue is low side. As you can see, the dead time has become undead.

DS1Z_QucikPrint1

This undead time caused massive shoot-through and generally messed things up. I asked Ben for help and he suggested look at the datasheet, and I asked Bayley and he said look harder.

Another shot of the oscilloscope. Blue is high side, yellow is my current sensor output, the dark blue spike is when the ADCs are sampled. As you can see, the output of the current sensors is zero when they are read 🙁

IMG_4409

After two days of looking at the register maps, I began to understand that the TIM1 timer consists of a hierarchy:
1. The main timer, which counts up and down subject to a prescaler.
2. The OCxREF signals, of which there are four on TIM1.
3. The OCx and OCxN outputs, which control the pins.
The dead time is generated by simply delaying a rising transition between the OCxREF and the OCx or OCxN levels. At first, I had simply inverted the polarity of the OCx and OCxN signals after the deadtime was generated leading to undead time. The fix was to instead invert the OCxREF signal, therefore keeping the polarity of the dead-time intact. It also turns out that there is an OC REF signal for each channel, which caused some confusion when I inverted just the channel 1 reference (OC1REF). All three needed inversion, and then it even worked!

Motorin like a happy camper.

IMG_4373

Tune in next time for the great position control saga!