· 3 MIN READ

Levitation Is a Control Problem

Build log from the maglev platform. Why magnetic levitation is unstable, and how a Hall-effect sensor, some op-amps and an Arduino pretending to be a PWM chip keep a platform floating.

  • #hardware
  • #controls
  • #arduino
  • #build-log

There's one moment from the maglev project that I keep thinking about. The platform is floating, and then someone shuts the lab door a bit too hard. The platform wobbles, catches itself and settles again. That little recovery is what the whole project is really about.

Why levitation doesn't want to happen

Take an electromagnet, hang a permanent magnet under it, and try to keep it at a fixed gap. Earnshaw's theorem says you can't do that with static fields. The intuition is simpler than the theorem. Magnetic attraction gets stronger roughly with the inverse square of distance, so if the magnet moves a little closer, the pull increases and drags it even closer. If it moves a little farther away, the pull gets weaker and gravity wins.

So there is an equilibrium point, but it's like balancing a pencil on its tip, and any disturbance grows exponentially. For my setup the time constant is on the order of tens of milliseconds. Nobody can react that fast, and neither can a slow control loop, so it has to be done electronically.

The loop

The structure is the standard one:

  1. Sense. A Hall-effect sensor under the platform measures field strength. That maps to the air gap. The relationship isn't linear, but it always moves in the same direction.
  2. Decide. The difference from the setpoint turns into a correction. My first version was fully analog, with proportional control built from op-amps.
  3. Actuate. The correction changes the PWM duty cycle going into the electromagnet driver, which changes the average coil current.

The most interesting decision was the controller itself. The original circuit used a MIC502, a fixed-function PWM controller IC. It works, but tuning the loop means physically swapping resistors and capacitors. So I copied the MIC502's behaviour onto an Arduino. The input and the PWM output are the same, but now the gains are just numbers in the firmware.

// The core of it. Pretty small for something that fights gravity
int gap = analogRead(HALL_PIN);
int error = setpoint - gap;
int duty = constrain(BASE_DUTY + KP * error, 0, 255);
analogWrite(COIL_PIN, duty);

Replacing a chip with code felt like cheating at first. Then I realized that's pretty much what mechatronics is. You decide which parts of the loop should be hardware, which should be firmware, and which problems are better solved with a better mechanical design.

The mechanical side

I've spent about half my time on this project in SOLIDWORKS, not on circuits. A 1D controller can only correct disturbances along its one axis. If the solenoid axis isn't exactly vertical, every correction also pushes the platform slightly sideways. It slowly drifts out from under the magnet, and the controller can't do anything about it because it can't sense that direction at all.

That's why the electromagnet mounts went through several design iterations just to get the solenoid axis properly vertical. The main thing I took away from it is that when the controller seems broken, you should check the mechanics first.

What's next

Stable levitation works now. The actual goal of the project is linear motion, with a rail of coils passing the platform along from one to the next. That turns one control loop into a problem of coordinating lots of them, and it's what the next build log will be about.