Filtering a digitalWrite OUTPUT to an electromagnet

So I have made an electromagnet levitation circuit using analogue components (comparator) and now I am trying to recreate using an arduino.

I have the circuit and code working just like the beginnings of my analogue circuit but I need to be able to filter my digitalWrite OUTPUT that turns my TIP122 transistor switch on and off.

When taking the first steps in the analogue levitation circuit (using IR sensors) I simply turned the electromagnet on and off when an IR beam was broken and this causes flutter, or oscillation of the object under levitation. To solve this a high pass filter of frequency 3.386Hz was used on the input to the TIP122 to turn it on and off 'smoothly' (470kohm and 100nF compensation network). On multisim this switching voltage is about 1.5V just for reference.

I have been looking for a digital equivalent and haven't been able to find/understand any solutions so far.

Could anyone help?

Just use PWM to drive the solenoid. The inductance of the coil tends to average out the PWM signal.

Post a circuit diagram -- you must have a flyback diode.

DrDaveyG:
When taking the first steps in the analogue levitation circuit (using IR sensors) I simply turned the electromagnet on and off when an IR beam was broken and this causes flutter, or oscillation of the object under levitation. To solve this a high pass filter of frequency 3.386Hz was used on the input to the TIP122 to turn it on and off 'smoothly' (470kohm and 100nF compensation network). On multisim this switching voltage is about 1.5V just for reference.

low pass filter surely?

You want to ramp the PWM up and down at a limited rate to emulate that in digital domain.

There is a circuit diagram of the analogue circuit that I have working perfectly with a 470kohm and 100nF compensation network (might be a low pass, not 100% sorry).

I thought that pin11 (a PWM) output might be okay but it wasnt.

I just think I need to smooth the PWM output so its not a pure ON or OFF to keep the object levitating. When I took a scope to the analogue circuit it seemed as if the EM was being turned ON and OFF through a sin-wave that damped the object under levitation.

Is there any way to filter the PWM output?

Or will I have to create some complex logic that calculates the velocity of the object under levitation and turns the PWM ON and OFF as a result. For example, if the sensor reading is going from 40 to 980 it is a negative velocity as the object is dropping and then if it went from 980 to 40 it would be a positive velocity as the object would be rising to block the sensor?

Thank you so much for your comments!!!

Is there any way to filter the PWM output?

No need to, if applied to an inductor.

turns the PWM ON and OFF

That is the wrong approach. PWM smoothly controls the average current through an inductor, and hence the average strength of the magnetic field, as you change the PWM duty cycle.

Most people use PID control to levitate objects using solenoids. Google will show you many examples.

So I have understood the PID explanations on google and it makes a lot of sense and I have learnt how they could be applied elsewhere in other applications so thanks for that!!!

Just one more question, I haven't got the equipment on me rn to test. Would I have to use a digitial PWM output to switch the transistor on? So use the Relay example of the library adapted to my use.

Or will I be able to use the analogue output to turn the transistor on? So then I will be able to use the adaptive tunings example?

Only reason is because the adaptive tunings example, with the aggressive or not so aggressive correction, based on the gap between input and set point values seems like it would, in theory, be a good fit for my levitation circuit, making more aggressive corrections if the object were to fall further for some reason and only small ones under normal operation.

I would quite like to use the tuning example but am afraid you are going to tell me I need a PWM output to switch the transistor. Do you think, with some thinking, I can use the tuning logic with the RelayOutput example?

Thanks again for any help. You are a legend!

edit... more than one question sorry

for example do think this combination would work?

#include <PID_v1.h>

#define IRbreak 0
#define EM 6

//Define Variables we’ll be connecting to
double Setpoint, Input, Output;

//Specify the links and initial tuning parameters
double aggKp=6, aggKi=2, aggKd=450;
double consKp=2, consKi=0.67, consKd=0.396;
PID myPID(&Input, &Output, &Setpoint, consKp, consKi, consKd, REVERSE);

int WindowSize = 5000;
unsigned long windowStartTime;

void setup()
{
windowStartTime = millis();

//initialize the variables we’re linked to
Setpoint = 950;

//tell the PID to range between 0 and the full window size
myPID.SetOutputLimits(0, WindowSize);

//turn the PID on
myPID.SetMode(AUTOMATIC);
}

void loop()
{
Input = analogRead(IRbreak);

double gap = abs(Setpoint-Input); //distance away from setpoint
if (gap < 50)
{ //we’re close to setpoint, use conservative tuning parameters
myPID.SetTunings(consKp, consKi, consKd);
}
else
{
//we’re far from setpoint, use aggressive tuning parameters
myPID.SetTunings(aggKp, aggKi, aggKd);
}

myPID.Compute();

/************************************************

  • turn the output pin on/off based on pid output
    ************************************************/
    if (millis() - windowStartTime > WindowSize)
    { //time to shift the Relay Window
    windowStartTime += WindowSize;
    }
    if (Output < millis() - windowStartTime) digitalWrite(EM, HIGH);
    else digitalWrite(EM, LOW);

}

Please use code tags when posting code, as described in "How to use this forum".

Use of PID absolutely requires careful choice of the constants Kd, Ki and Kp (which may be zero). Google "PID tuning" for tutorials on how to select them.

"analogWrite()" is a very badly named function that provides digital, PWM output on certain pins. There are plenty of tutorials describing the pins and use of the function.

A recommended circuit for PWM DC motor control, which will work fine for your solenoid, is posted below.

Have you considered looking at the Complementary Filter, there are versions with a high and low pass filter, for filtering in software?

Changing the K and Kp ratios change the band pass filtering ratio.

Complementary filter is only relevant to IMUs, not here. Perhaps you mean a digital filter?

DrDaveyG:
For example, if the sensor reading is going from 40 to 980 it is a negative velocity as the object is dropping and then if it went from 980 to 40 it would be a positive velocity as the object would be rising to block the sensor?

I see two major issues in this.

First a misunderstanding on how to read the sensor: it's apparently a break beam type of sensor, which can be on or off. These numbers tell me you're using an analogRead() call to read the state of the sensor. That doesn't make sense: it's much faster and more obvious for what's going on to use a digitalRead() call. After all the sensor has only two states: beam or no beam.

The second: you will continue having oscillations. The moment the beam is made, the object moves up, so you want it to go down. How much? You don't know as you don't know the speed or how much off the object is. So all you can do is switch off the magnet waiting for the object to come back down. Then the beam is made, the object moves down. Again you don't know how fast, or how much, just that it's too low now.

For working PID you need some kind of sensor that tells you how far away the levitating object actually is.

So if I created an array which calculated the velocity of the levitating object, using the sensor readings and their displacement worked out by how positive the readings are and how they negative they are do you think that would work?

No idea what you're trying to say, but if you stick to a single point you can never tell the speed or actual location of the object.

Velocity measurements won't help with a position PID controller.

As mentioned above, you need a sensor that can detect a deviation from the desired height. Many people use an LDR for that, with diffuse side illumination.