Electronic – Controlling an Electromagnet using a microcontroller

control systemdacelectromagnetismpwm

My question stems from this one here: Controlling an electromagnet strengh with arduino

Background

I am working on the classic magnetic levitation control systems problem. I have a 10N electromagnet (150 mH, 40 ohms) that will be used to levitate a steel ball. I will be using an optical time of flight sensor to determine the balls position. I plan on going above and beyond the typical undergrad magnetic levitation problem by allowing the set point (ball height) to be changed on the fly, similar to this video.

I took non-linear control systems course in grad school so I am aware this is a difficult problem. We never went beyond the theory though, so I thought this would be a fun problem to extend my learning.

The Problem

The control system I derived expects that the input variable (the voltage applied to the electromagnet) is a continuously varying DC voltage. I've been looking at using a DAC, but they are relatively expensive and don't seem to be designed for power applications. PWM seems like the way to go, but I am struggling finding a way to model the PWM system; a square wave is not mathematically friendly.

The Question

What is the best solution for the problem: using something like a DAC or PWM? I need to create a fast-acting (< 1ms delay), accurate control signal.

If PWM is the best solution, how would I go about modeling it in a control system?

Best Answer

Rather than needing to model PWM effects on levitation you can run the PWM at much higher than critical rate then either

  • Filter to DC.
    This can drive an eg FET driver. OR

  • Send unfiltered PWM to FET and drive inductor with recirculation diode for when FET is off.
    This now becomes a buck converter. Changing PWM % changes inductor current.
    You can add a sense resistor and measure current.
    With due design the sense resistor can have one end grounded allowing ease of I measurement with microcontroller's ADC.

eg M1 is a P Channel high side MOSFET. If inductor supply is the same as microcontroller supply (which is not usually the case the gate can be driven at microcontroller voltage levels. If eg mc has 5V supply and inductor has say 12V supply a level-shifting driver is needed. Details on how this can be achieved can be discussed if this is the path taken. D1 allows current "recirculation" when MOSFET is off.
R1 allows current sensing.
Depending on inductor resistance it may be desirable to provide additional loss in the recirculating path to allow faster field decay to improve control response times. Or not.

schematic

simulate this circuit – Schematic created using CircuitLab

_______________________________

I see lots of people suggest using a TIP120 for driving a high current load from a uC. But it seems a FET is a much better choice since it allows faster switching and is less power hungry.

TIP120 is less bad than some - 5A 60V Darlington. Min current gain is 1000
BUT C-E saturation at 3A is 2V max @ Ib=12 mA,
and 4V at 5A at Ib = 20 mA.
At 3A that's equivalent to on resistance of R = V/I = 2/3 = 666 milliOhm or
at 5A = 4V / 5A = 800 milliOhm.
Heat = 6W and 20W. FETs with much much much lower Rdson are cheap and available.

Also 12 mA drive is liable to be near upper limit for some uCs and 20 mA worse.
FET drive needs are low at low speeds and if higher speeds needed a 2 transistor gate driver (NO other parts) can be used.

PWM with recirc diode as in other answer looks good.


An N Channel FET is equally good from a power switching point of view.
N Channel speed is no problem - required switching speeds will be well below what can be accomplished with typical devices.

The above P Channel method puts the "switch" high and allows the sense resistor to easily have one side grounded. This makes it simple to use an ADC to read V_Rsense in microcontrollers with ground referenced ADC's and keeps Rsense under Vdd_mc.

An N Channel switch on the "low" side slightly simplifies FET drive but makes Rsense voltage slightly harder to read as Rsense is then usually either floating or attached to V+_solenoid. Usually you then either use a current mirror to "reflect " Isensed to a ground reference point or use a differential amplifier to do the same.
Rsense is then usually at DC level of > Vdd_mc if Vinductor >> Vdd_mc as is often the case.