Arduino Powered Magnetic Levitator

Get all portions of this design! (zip)

This project was a simple introduction to magnetism and control systems. Ernshaw's Theorem states that any passive system of point charges can not remain in a stationary stable equilibrium with just electrostatic forces. We get around this limitation by providing active feedback to an electromagnet actively controlled with a proportional-integral-derivative (PID) controller built on either an Arduino or ATMega328.

A linear hall effect sensor, basically a sensor that reads the intensity and direction of local magnetic fields, is used to determine distance to the physical object being suspended. By adding a small passive rare-earth magnet to the object, the acceptable weight of items can be increased greatly, the components listed here can keep 22 grams stable even in an open environment with air currents and vibrations.

The Arduino is easily capable of updating the PID outputs multiple times a millisecond, but by keeping the update interval at a stable 1 millisecond we don't have to compensate for conditionals changing our cycle time or interrupts stealing valuable predictability. The Arudino also can output 32kHz PWM, with phase correct that gives us effectively 16kHz PWM. This unfortunately lies in the audible range, so additional optional filtering is done to keep the machine almost silent during steady state use. I had some heat dissipation issues earlier, so the electromagnet will automatically turn itself off when it doesn't detect a permanent magnet in range for 5 continuous seconds. Given that the duty cycle is substantially lower when an object is being suspended, even if very heavy, the device can stay in active mode indefinitely as long as there is an object in range.

Total power consumption is around 10 watts, and can be simply implemented using a bare ATMega328 to avoid the costs of permanently reserving a full Arduino board.

One future potential improvement is to convert the magnet system from a "puller" up top to a "pusher" model in the base. Due to the spherical nature of the magnetic fields, multiple electromagnets are required and I believe the software will have to anticipate and rapidly respond to the permanent magnet flipping over lest it be attracted straight into the base. The weight limits can be easily improved up to a point by simply using larger electromagnets and less sensitive hall effect sensors, but will eventually hit the square-cube law limits where increasing force becomes prohibitively expensive. It's also possible that magnetic saturation will become an issue. Anyone have some spare room-temperature super conductor to loan me?

Arduino Circuit Diagram

Component notes:

ATMega328 Circuit Diagram

Component notes:

Source Code For Both Configurations

Get the code! (ino File)

Provided under MIT 3 Clause license

Comes preconfigured for Uno/ATMega328. Other chips may require an update to the pin selection and timer. For reference, the ATMega328 uses Timer 2B for pin 10. An explanation of the #define options:

While the machine is running, parameters can be controlled via the Arduino Serial Monitor, even when using a bare ATMega328 provided the test points are connected. Capitol letters result in the value being raised, lower case makes them lower.


Proportional Term. This determines the gain of the system, in other words the difference between the sensor and the target value will be multiplied by this to find output. When freshly tuning with no known good values, set all three of the P, I, and D terms to 0 and slowly ramp this up until your object no longer falls straight away, instead get it bouncing up and down like a pogo stick for a few seconds before falling. Then move on to the derivative term.


Derivative Term. This determines the damping of the system. When high, this attempts to reduce the maximum error swing in the output, slowing down the up and down oscillations introduced by the proportional terms above and making the system more stable as a result and is responsible for settling. After an appropriate P is found, set D to about 20x P and then vary it until maximum stability is achieved. Then move on to I.


Integral Term. This is used to compensate for constant error in the machine as it remembers how far off the system has been over the last few seconds (or minutes depending on the max integral value). Choosing a good I will allow the setpoint to be reached easier, but too high and you'll overshoot and lose stability. After P & D are set, raise I from 0 and find a local island of stability. This term will be quite low. Once found, adjust P and D again to compensate for new issues introduced by other settings, then you're done!


Setpoint target value. This is the value the machine is working towards (lower numbers are closer together). To chose an appropriate set point, you can start with a value around 1/2 (512), then lower it with a magnet in close range. A good value is one which attracts the magnet when the PWM cycle is at 100%, but lets it fall when at 0%.


Display current tuning values.


This frame is suitable for cutting on a CO2 laser with Acrylic. It is assembled using acrylic glue, a form of solvent welding. The base plate looks like it's missing a front and back, that's because it's designed to be laser bent. After the form is cut rest the part above the bed so the flaps can swing free. Blow out the focus of the laser to 3 or 4x its designed focus depth, then do repeated passes of fast cuts. This will heat the acrylic enough that it becomes pliable and it will bend due to the force of gravity. If it doesn't bend on its own, add a little extra weight to pull it down.