Tonight I built a current-mode controller for brushed motors. Instead of going the traditional route using a microcontroller controlling PWM through a PI loop, I used only a comparator and an op amp. I had a hunch that this would work while being exceedingly simple. My hunch turned out to be correct, and I was able to run a motor in torque mode controlled with only an LF356 op amp and an LM311 comparator. The output from the comparator drives a low-side fet I had lying around. I can’t make too many solid claims about the performance of this setup, but it definitely does work.
The circuit uses an LF356 op amp to buffer and smooth the potentiometer input. The output voltage from this IC is compared against the output from an ACS756SCA-100B 100 amp bidirectional current sensor (overkill but all I had laying around) on an LM311 comparator. This comparison is done with approximately 5mv of hysteresis to stop noise and keep the switching “frequency” reasonable. The output of the comparator goes to the input of an old inverter board I had laying around. Here is the schematic.
This circuit seems to work well. An interesting number is the steady state pseudo-“switching frequency”, which for this hysteresis band is about 42kHz under steady state operation. Here is a video of operation. Notice that at stall the controller creates a lower duty cycle and that as the motor speeds up the duty cycle slowly increases to 100%. This is exactly what you would expect from a current mode motor controller, as the duty cycle increases to compensate for the increasing back-EMF of the motor.
Here is an oscilloscope capture of the controller running. Yellow is phase voltage, light blue is Allegro current sensor output, dark blue is LEM stick output. Notice how the LEM stick output shows that lovely inductor triangle wave.
I think that the weird jumps in the ACS756 current sensor output are a measurement error. Idk really but this signal is not picked up on the LEM. Possibly it is a grounding error.
I started out with just a comparator (no hysteresis) and I was oscilloscoping the output to determine comparator performance. I got crap loads of noise on this setup and determined hysteresis was necessary to not switch at a megahertz.
Moved to this.
The op amp is really just there as a buffer and a smoother. Seems to work guuuuuud!
More on comparators: A very good read.
What are some advantages of this setup over using a microcontroller running a PI loop and PWM?
- The current rise time is greatly reduced, since the controller is always applying full control effort. This could be useful for servo drives.
- Its an incredibly simple simple system- there is just not a lot going on here and therefore not a lot can get lost in abstractions because there really are no abstractions at all.
- There are just two friggin parts to the controller, thats gotta cost at least an order of magnitude less than an arduino.
- No tuning of controller gains!!!! You do have to set that hysteresis band, although this requires no knowledge of the characteristics of the motor.
- If one desires to run a position control loop on their motor, all current control is offloaded with this setup. Therefore one can run a very complex and slow position controller while still having a fast current “loop” with a setup like this.
- There is not really any set “switching frequency” That is ok but is kind of harder to think about.
- It is hard to apply small duty cycles. My hysteresis band allowed a minimum on time of about 8us, which is actually a long time. Given that PWM can achieve resolution on the order of 5.5 nanoseconds (for the STM32F446) this is substantially not as good. My inverter is definitely not good for 5.5 nanoseconds though.
- This lack of resolution can end up manifesting itself in slower switching and therefore a high current ripple and therefore higher losses.
Hysteresis control is very cool and I will probably visit it again in the future.
Next up: 3 phase version of this????? Could possibly work, or maybe a hybrid hysteresis-PWM controller. Stay tuned!