3
\$\begingroup\$

I followed a Youtube video here and it has instructions at here. The concept is easy which is try to levitate a magnet and balance it using Hall-sensor by changing the PWM of the electromagnet to increase repulsion when the magnet is too close to the electromagnet so that the magnet always stays center. My model is slightly different than the author one that is I use 2 H-bridge driver. My hall sensors are working perfectly well as you can see from the readings I got when I place the magnet on the 4 corners. The code below is just to illustrate how to control the PWM of the electromagnet. I have tried to increase the duty cycle (100 %) when the the hall_effect sensor detect magnet is close to electromagent to repel it better. And then when it is in the middle somewhere, I lower the duty cycle both electromagnet to 70 % so that the magnet stays in middle but my trial was unsuccessful.

The voltage I measured on each electromagnet (100 % duty cycle) is 4 V and it has a resistance of 8 Ω which means it dissipate 2 W and I am not sure whether its enough because there is no datasheet for this.

Can anyone help to modify my code below so that I can test your code OR is there a better way to solve this:) ?. ie What other ways are there to improve the stability of the magnet levitation because my method does not keep the magnet balanced


Arduino uno code for reference

int hallSensorPin = A0;      int hallSensorPin_2 = A1;  
int state = 0;   int state_2 = 0;        

void setup() { 
  pinMode(hallSensorPin, INPUT);      
  pinMode(hallSensorPin_2, INPUT); 
  Serial.begin(9600);
}

void loop(){
  for(int x = 0; x < 1000000; x++) {
    state = analogRead(hallSensorPin);           //hall sensor1 (x-dir)
    state_2 = analogRead(hallSensorPin_2);   //hall sensor2 (y-dir)
    Serial.println( state);
    Serial.println( state_2);
    Serial.println("blank");

    analogWrite(9, 250); analogWrite(11, 250);
    analogWrite(5, 250); analogWrite(3, 250);      //250 is the maximum PWM (100% duty cycle)
    delay(1000);
  }
  delay(100000);
}

enter image description here

enter image description here

enter image description here

enter image description here

\$\endgroup\$
6
  • 3
    \$\begingroup\$ There's couple of problems. You don't say what help you need to modify your code, nor what modifications the code needs. \$\endgroup\$
    – Justme
    Commented Sep 10, 2022 at 16:29
  • \$\begingroup\$ @Justme, sorry, I mean what other ways in order to improve the stability of the magnet levitation because my method does not keep the magnet balanced :) \$\endgroup\$ Commented Sep 10, 2022 at 16:48
  • \$\begingroup\$ please delete your duplicate post at arduino.stackexchange.com/questions/90720/… \$\endgroup\$
    – jsotola
    Commented Sep 10, 2022 at 18:16
  • 1
    \$\begingroup\$ There appears to be no coupling in your code from measurement to control output, and the 1 second delay() call makes the control loop far too slow for this system (by my “seat of the pants” dynamics calculator) \$\endgroup\$
    – Bryan
    Commented Sep 10, 2022 at 19:43
  • 1
    \$\begingroup\$ September 10th: Edited to move question to bottom and tidy wording. Applications like this require increased incremental knowledge, usually gained by guided experiment - not single 'do this and it works' solutions. Such technical guidelines are not "opinions". Requirement is clear. Answer provides excellent guidelines for pratical investigation. \$\endgroup\$
    – Russell McMahon
    Commented Sep 11, 2022 at 9:40

1 Answer 1

3
\$\begingroup\$

This is not an answer, just a collection of thoughts. Programming a real time regulator loop with two dimensions is not a beginner's project, but if you are through it, you will have learned a lot.

You need a fast running software loop, that performs these tasks:

  1. Aquire the status quo, here the deviation in x and y from the desired position.
  2. Consider what has been in the cycle before and calculate the grow rate of the deviation. If the deviation was small before, it is just escalating, if it was larger before, the regulation is already successful.
  3. Calcutate the needed correction. In many cases a so called PID regulator is used.
  4. Send the correction to your actors, here the PWM values of the coils.
  5. Provide a precise timing until you start at 1 again.

In your code you have a delay of one second in the loop. This has no chance at all to react in time. A good implementation would prepare a hardware timer to set a software flag in fixed time periods. This flag indicates the start of the next loop.

A simpler approach could use e.g. delay(5) for a more or less stable first attempt. Updating your PWM much faster may produce garbage and the calculation of the deviation grow rate is vague. Being much slower, the imbalance may grow too fast to catch it easily. This is guesswork from my side, since I don't have the hardware.

Function calls like "Serial.print" inside the loop introduce more delay and make the regulator tardy. Keep those data as short as possible, use single characters or one number only, to deal with a special problem you just work on.

There are two regulators here, one for x and one for y. For simplicity you can consider them as independent for a start, but later on you might discover, that they aren't.
Use your code and modify the PWM values to find out how much power is just needed to lift the magnet if it is in the center and all 4 coils receive the same power. This will be your base power value for the regulator. If this is close to 255 you have no headroom for corrections and need a smaller magnet.

Declade two integer variables "x_corr" and "y_corr" and initialize them with zero. In the first test you can apply the following rule:

  • if the measured position of an axis is below the optimum add one to the corr variable, if it is above subtract one.
  • verify, that the corr value is below (255 - base), your control range. If not, revert the add or subtract because the correction already is at limit.
  • Do this for both axes
  • Set the PWM of one coil of an axis to base + corr, the other to base - corr. Do this for both axes.
  • Play with this code while holding the magnet between your fingers. Check if the direction of the regulator force is correct, if it at least tries to correct the position. You may discover, that you must change the sign in the PWM expression +corr and -corr if the regulator makes things worse than better.

The base value will later change the vertical force to raise or drop the magnet.

If this test produces the correct force directions, it is time to read about PID regulator implementations. I will give a short overview here.

  • The "P" stands for proportional. The P-value is the amount of deviation from the target value and will be multiplied with a configured P-factor to define the influence in the final correction value.
  • The "I" stands for integral. The I-value is the sum of all deviations and will be multiplied with the I-factor. The longer even a small deviation exists, the higher will be the influence of the I-value. Typically the I-value is limited to a useful range.
  • The "D" stands for differential and deals with the growth of the deviation. The D-value is the difference in deviation compared to the last cycle. Again there is a configured D-factor for the weighting of the D-value. The effect is, that the correction will be higher on escalation and lower if the deviation already is getting lower as a consequence of the last correction. This avoids overshoot.
  • The final calculation looks like this: corr = P x PFactor + I x IFactor + D x DFactor. The hard work is, to find the correct factors for a given mechanical system. This is, what the brain does while learning how to ride a bicycle. And if you change the regulator loop speed (e.g. being drunk) the regulator fails, ending in the ditch.
\$\endgroup\$
1
  • \$\begingroup\$ In control systems terminology, your PFactor, IFactor, and DFactor are typically called Kp, Ki, and Kd respectively. \$\endgroup\$
    – Hearth
    Commented Sep 11, 2022 at 13:11

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.