Tuesday, December 3, 2013

An AVR Atmega based PID magnetic levitator



This is a magnetic levitator implemented using Atmega8 microcontroller.
Magnetic levitation is a method by which an object is suspended with no support other than magnetic fields.


To make a magnet levitate, an hall sensor is attached to a coil. The coil acts as an electromagnet, and the hall sensor measure the distance of the magnet from the coil.
The coil it is driven by PWM impulses, the closer the magnet is from the hall sensor, the bigger is the duty cycle and vice versa.
The coil works only if the magnet is in a certain range, out of this range no current flow through the coil, and the system is in is idle state.
The system has to mantain the equilibrium position of the magnet, the pull force of the coil has to be equal to the gravity force that pull the magnet to ground.

To stay on the budget, a small 12V 50N coil (ZYE1-P25/20) is used, with this coil the system can not lift heavy loads.
The hall sensor used it the Allegro A1302.
Because the heavy loads limitation, i've to put the hall sensor next to the coil, this solution produce a problem, the magnet can be pull even by the ferrite core of the coil, If it gets too close to the coil. To prevent this situation we have to emitting less current to the coil.
A bigger coil and a more sensible hall sensor can lift heavier load, and also the magnet can levitate far away from the coil.

An RGB led, next to the hall sensor, is powered on when the magnet is detected.




To adjust PWM intensity, a PID controller is used.
A proportional-integral-derivative controller (PID controller) is a generic control loop feedback mechanism (controller) that calculates an "error" value as the difference between a measured process variable and a desired setpoint. The controller attempts to minimize the error by adjusting the process control inputs.

The micro runs at 8Mhz, every 1ms the hall sensor it is checked, and the PWM for the coil is adjusted. The PWM period is 1953Hz.


The PID controller parameters, and other configuration options are stored in eeprom and can be edited by a software application connected through the UART connection. The software used for this functionality is avruartconfig.
All the configuration values could be changed through the UART connection for different coil / hall sensor / magnet hardware.


For an art fair next to my town, InverART 2013, a friend of mine, Paolo Crespi, build the sculptures you can see on the image above.



Code


Notes
  • read risk disclaimer
  • excuse my bad english

27 comments:

  1. Davide, awesome project! I am curious, where in relation to the coil the Hall-effect sensor is located and does it matter what direction it's facing?
    Cheers!

    ReplyDelete
    Replies
    1. a] hall sensor position, center of the coil, approx 4mm from it.
      b] sensor has no importance, but depends on the coil wiring (+ and -) and the magnet direction

      Delete
  2. Great job with the tutorial! But I am curious, wouldn't it be easier to use an arduino? I am not familiar with this Atmega.

    ReplyDelete
    Replies
    1. "easier" depends on your dev skils, if you are familiar with ardunio, it will be easir with arduinio. this one is writtn in "plain" avrgcc, and built on a 50cent ATmega8.

      Delete
  3. Very nice results. Just a small question:
    Your hall sensor measure both the distance to the magnet and the coil magnetic field due to the PWM. Do you cancel this factor in software ?

    ReplyDelete
    Replies
    1. no, this is not an issue, but this is the reason why sensor orientation have to depends on the coil wiring (+ and -) and of course the magnet direction.

      Delete
  4. This is really awesome, one question; the code says that PID is calculated every second, isn't it too big for PID calculations?

    ReplyDelete
    Replies
    1. it was my mistake in comments, sorry it's milliseconds :)
      so, it is calculated every 1 millisecond.

      Delete
  5. Very nice! How did you determine the PID parameters?

    ReplyDelete
    Replies
    1. Thank you.
      A rought estimation was done using the Ziegler–Nichols method, then i tune parameters experimenting by hand.
      Here the GUI software helps a lot, because i do not have to compile and upload the code to micro for every PID parameters change.

      Delete
    2. Thanks for the answer. I've a very similar project (even the same hall sensor). I tried the Cohen Coon method, but not successfully.
      The biggest problem I have is that when the force of the electromagnet changes, the sensor value also changes. Did you take that into account?

      Delete
    3. check the hall sensor and magnet orientation. The magnet influence are minimized if all parts is orientated in the right way. If not, the influence is too big, and system does not work.

      Delete
    4. So if I'm correct, you turned the hall sensor 90 degrees as to the electromagnet? How can you still detect the magnet that way?

      Delete
    5. i flip the hall (turned 180 degrees), and flip the magnet of course. and eventually invert the coil connection, if needed. Hall sensor must sense in the opposite way of the coil magn field.

      Delete
    6. But the hall sensor measures both ways, I got this from the datasheet: "These devices have a quiescent output voltage that is 50% of the supply voltage". So it gives an output voltage lower or higher depending on the fields direction.
      I still can't understand why your sensor doesn't detect the electromagnet?

      Delete
    7. I have explained badly, in theory you have two correct way of wiring.. in the wrong one magnetic field always grow by the magnet and by the coil.
      But if the coil has a ferrite core, this core may be magnetized more in one way, check this. Also keep the hall sensor at some distance from the ferrite core, or your core will attract the magnet.
      The rest of the magic is you PID alghorim and constants.

      Delete
  6. Massive thanks for the quick answers! I'm going to try to correct the sensor position.

    ReplyDelete
  7. hello david sir ,your link to avruartconfig is not working. can u please mail me (pankab37@gmail.com) the software or its link

    ReplyDelete
    Replies
    1. Hello, thank you for the feedback. Link is now corrected.
      Anyway you can find a compiled avruartconfig in the source file of this project, or look at the avruartconfig page here: http://davidegironi.blogspot.it/2013/03/avr-uartconfig-atmega-and-arduino.html

      Delete
  8. Is it OK if I dont use hall sensor?

    ReplyDelete
    Replies
    1. Hello. Yes, as long as you use any other sensor to measure the distance of the levitating object.

      Delete
  9. good job! Could you help me get the constants kp, ki, kd? I did it with the pid manual for atmega8 (ziegler-Nichols) and nothing, then try to modify the variables a bit to see if I could get it that way but nothing ... Help! (The k constants that start at the beginning are: kc = 2, kp = 1.3, ki = 13, kd = 0.0312)

    ReplyDelete
    Replies
    1. Hello, Ziegler-Nichols sould work, it it doesn't you could start by the value posted in my code, P=1.3, D=15.0, I=0.0015. My suggestion is to experiment a little with values, take a look to offset and theshould values too. As always, double check your wiring, and remember that magnet, hall sensor, coil orientation matters here. Check if all are oriented in the right verse.

      Delete
  10. This is great ! but doesn't the electromagnet interfere with the Hall effect sensor, because it also creates a magnetic field?

    ReplyDelete
    Replies
    1. Hello Bishoy, thank you. Nope, it does not. Indeed hall sensors is also used in brushless sensored motors.

      Delete
    2. Why it does not? despite the existence of a magnetic field from the electromagnet? Thank you.

      Delete
    3. I should say, it does in some way, it depends most on the hall sensor type and positioning, and the magnetic force applied. With the hardware I've used here, there's such a "small" amount of interference that it does not affact that much the positioning system, which is also stabilized by the PID controller.

      Delete