I've been banging my head on this project for a while and need some guidance. It is a magnetic levitation device that is used in control theory class. I've never taken the class so have been trying to learn it through online courses and books. I think I get some of the basics but not enough to figure this out.

The way the system is supposed to work is that an electromagnet pulses its output to keep an object (permanent-magnet in my case) levitated.

Brief description of the system: There is an electromagnet that is being controlled by a PWM signal from an Arduino. The Arduino knows, or is supposed to know, what duty cycle to provide based on the the current through the electromagnet and the hall effect sensor.

As the object gets closer to the hall sensor the value of the hall sensor increases. The whammy here is that as the current, which is controlled by the PWM, through the electromagnet changes the hall sensor reacts to this as well. To get rid of this effect, we measure the current through the electromagnet convert it to a "hall value" and subtract it out to normalize the hall sensor reading. This in effect gives a pure reading of the object's distance relative to the hall sensor.

enter image description here enter image description here Schematic

Now my issues is how to characterize and tune the system.

One of the techniques to characterize the system is to provide an impulse or a step and measure the response of the system. I tried using a step response, which is essentially providing power to the electromagnet. Now the question is how do I measure the response. If I give full power to the electromagnet the permanent magnet shoots up and gets stuck. I have an overshoot situation. If I provide less power nothing really happens. I am stuck in a binary situation: the permanent magnet either doesn't move or shoots up and gets stuck.

How can I characterize this system with this limitation?

I've also tried just using a PID controller and doing some guessing for tuning it, but kept getting to that same issues.


  • \$\begingroup\$ If you're looking to find out the step response then isn't the shooting up and getting stuck the step response? \$\endgroup\$ Jan 31, 2018 at 22:25
  • 2
    \$\begingroup\$ This system isn't linear, you'll want to model the system from first principles, pic an operating point (nominal ball height), derive a linear approximation for that operating point, then produce a controller which can control that linear system. \$\endgroup\$
    – pgvoorhees
    Jan 31, 2018 at 22:29
  • \$\begingroup\$ @immibis you are correct but if it's getting stuck isn't it clipping some info? I guess this is where I am getting stuck. \$\endgroup\$
    – I Gr
    Feb 1, 2018 at 1:55
  • \$\begingroup\$ @pgyvoorhees I've actually done the model an analog system and done the linearization about a point. A lot of this is based on write ups I've seen of similar problems. I haven't figured out how to take that and implement it though. One issue is Z transform (digitizing) and also figuring out how sampling and PWM impact. \$\endgroup\$
    – I Gr
    Feb 1, 2018 at 1:57
  • \$\begingroup\$ @IGr How's your familiarity with state space modeling (that control theory part you mentioned) and eigen vectors/values? You will need ALL of the terms for PID here. D is definitely needed to yield a steady state response at an equilibrium position. I don't see any of your pencil and paper work on the equations, state space, or specific quantitative analysis of your situation here. Nothing. Just a block diagram. There's a huge vacant gap between these two. Also, PID will only work for a computable but narrow range of starting points. Too far or too close to start out will be a problem for PID. \$\endgroup\$
    – jonk
    Feb 1, 2018 at 5:01

1 Answer 1


There are a few issues with your implementation.

  • You need a flyback diode across that coil if you don't want an overheating transistor and massive interference. Your current schematic at least doesn't show one. I'd suggest using a schottky diode, as they are fast and have a low voltage drop.

enter image description here

  • If you are having trouble getting the magnet stable, keep in mind that it might have nothing to do with your PID gains and everything to do with the update rate of the control loop. When I did my magnetic levitatior, the bare minimum that I got to work was 200 Hz. Especially if you are using floating point math for the PID controller on an AVR, I bet you can't get stable levitation. Do everything with 8-bit and 16-bit integer math instead (known as fixed point), and you'll easily be able to reach cycle times below a millisecond.

  • Both the input and output of your PID controller are non-linearly related to what you want to control (you want to sense distance and control upwards force). Instead, the hall effect sensor output is proportional to the multiplicative inverse of distance squared, and the force exerted upon the magnet by the electromagnet is not only proportional to coil current, but also inversely proportional to distance squared.
    PID controllers don't like this nonlinearity. You should compensate for the nonlinearities in your control system, so that the controller operates in a linear space. For the input, calculate a linear distance from the hall effect sensor output and feed that to the controller instead of the raw value. For the output, apply less current for a given requested force when the magnet is nearer, so that the attraction is independent of distance.

There's also better way for eliminating the contribution of the electromagnet from the hall effect sensor output:

Sample the hall effect sensor output synchronously with your PWM output, so that the flux is measured only when the coil current has decayed to zero at the end of each PWM period. Much simpler hardware wise, the only drawback is that you need to program at a lower level, starting the analog-to-digital conversion each cycle in a timer interrupt. Don't low pass filter the ADC input if you do this though.

  • \$\begingroup\$ thanks for the info. For your first point I actually have the diode in my circuit; must have gotten lazy when copying from paper to computer. \$\endgroup\$
    – I Gr
    Feb 1, 2018 at 1:59
  • \$\begingroup\$ For your second point, I am using an interrupt to trigger the PID calculation. It was originally set to 2.5mS then I sped it up to about 0.25mS intervals. What I didn't consider is that my floating point calculation may not be completed in this time. I will try doing everything fixed point and get back to you. I am not sure I fully understand your third point. So convert the hall sensor reading into a distance, which should be linear; and reduce output current (PWM) with distance. \$\endgroup\$
    – I Gr
    Feb 1, 2018 at 2:08
  • \$\begingroup\$ @IGr I meant that you should scale the output current in proportion to distance squared to compensate for the nonlinear behaviour. For example, you might need 250 mA at 10 mm, 1 A at 20 mm, 2,25 A at 30 mm and 4 A at 40 mm to generate 0.1 N of force. \$\endgroup\$
    – jms
    Feb 1, 2018 at 2:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.