I have been struggling with a college project, being so close but yet so far from making it work succesfully.

I have designed an electromagnet control system that has to control the position of an object levitating below it. It is an attractive levitating system, where the levitating object is below the electromagnet.

The object is a small ball with a permanent neodymium magnet attached to it, in order to sense its proximity by sensing the magnetic field produced by the permanent magnet. The sensor is a 49e Hall efect sensor whose output has been adapted to 0-5V. It is placed below the electromagnet (separated 1cm) and over the object. Forget the field generated by the electromagnet the regulator should be capable of controlling it despite its influence.

The regulator is programmed in Arduino, and consists of a regular on/off controller, depending if the object is above or below the set point (desired position.)

The Arduino output (0-5V) goes to the input of an analog circuit. It consists of a voltage-controlled current regulator.

analog circuit

The main problem here is that, after a few seconds levitating successfully, it begins to oscillate and then it falls.

I have a couple of theories about this:

  • The sensor is unstable and makes wrong measurements. (I have checked it and it seems to work.)
  • The transistor suffers a lot because of the heat (it has a heat sink, shouldn´t be that.)
  • The transistor is not capable os switching so fast.
  • The diode is not capable of discharging the magnet so fast.
  • \$\begingroup\$ You probably have slow feedback from hall. How offen do you read hall? \$\endgroup\$ Commented Oct 20, 2023 at 18:02
  • 1
    \$\begingroup\$ On/off control is likely not to be the best method either. \$\endgroup\$
    – Andy aka
    Commented Oct 20, 2023 at 18:06
  • 2
    \$\begingroup\$ it's a control system with feedback ... the correct term is oscillation, not vibration ... please do research using that term \$\endgroup\$
    – jsotola
    Commented Oct 20, 2023 at 18:08
  • \$\begingroup\$ Gravity is an acceleration, which is not a linear (first order) function. If you have had courses in feedback and control theory, review them. If not, then you must look into them. Hint: the solution requires either an integrator or differentiator network. \$\endgroup\$
    – AnalogKid
    Commented Oct 20, 2023 at 19:32
  • \$\begingroup\$ One could change R8 from 10k to 100 Ohm ... \$\endgroup\$
    – Antonio51
    Commented Oct 20, 2023 at 20:53

2 Answers 2


You have a high order control system there.

The current becomes force, which integrates to speed, which integrates to position. That's 180 degrees unavoidable phase shift due to the physics of the system, before you have begun to consider other implementation phase shifts like latency in the Hall sensor and the Arduino control program.

That means guarranteed oscillation, unless you design some phase lead for the system. You will need to do some analysis of the gain and phase response of the open loop system, and then design a phase lead that will give you some phase margin at the frequency where the closed loop gain crosses unity. Don't forget that the loop gain will vary as the vertical position of the target varies.

The bad news is that it's unlikely this can be hope'n'poked. The good news is that it can be designed graphically with a Bode plot, without resorting to nasty algebra. Further good news, you have started with a current controller. If you had driven the coil with voltage, you would have had yet another order to compensate, as voltage integrates to current. Yet more good news, you don't need any other equipment to make the Bode plot, the Arduino already drives the coil and reads the Hall - just program a data logger in there.

You can probably keep the on/off control, but it will need to on/off fast enough so that the mechanical response is relatively smooth. This means using fast PWM with the duty cycle controlled from your controller, rather than simply switching on or off when the target moves into or out of its correct position.

As you already have an Arduino in the loop, you will have the flexibility to play with the time constants in phase lead easily.

A word about the change in gain. If you only need to make the target stable at its correct position, you need only consider the gain at that position. If you want it to recover from a large deviation stably, then you need to make sure you have stability at all gains between the nominal and the disturbed positions.

  • \$\begingroup\$ Amazing.! I will try it, thanks! \$\endgroup\$
    – nolo
    Commented Oct 22, 2023 at 10:59

First stabilize your current sink, it is prone to high-frequency oscillations (much higher than you would observe from the object).

Reduce R8 to 100Ω and add a 10nF capacitor from pin 1 to pin 2 of the LM358.

Once that is done, assuming it still does not operate satisfactorily, I would look at reducing the gain while keeping relatively high bandwidth, for example by using a kHz PWM and few hundred Hz cutoff low-pass filter between the Arduino PWM output pin and the op-amp non-inverting input.


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.