Electronic – arduino – Reduce noise from a Hall effect sensor

arduinocoilhall-effectmosfetnoise

I am currently working on a magnetic levitation project using a Hall effect sensor for distance measurement. I drive the coil using two 12 V car batteries in series to form a 24 V DC source, a MOSFET and a 3900 Hz PWM signal from my Arduino.

Here is my circuit:

Enter image description here

I have to map the field strength (-512 to 511) created by the coil to the input signal (0 to 255). I expected this to be a linear relation, but my readings were quite noisy:

Enter image description here

I reduced it a lot by adding a bypass capacitor to the Hall effect sensor output (C1):

Enter image description here

However, I don't think it's clean enough to get a stable magnetic levitation.

My questions are:

  1. Why does the signal behave like that? Is it measurement noise, or is it the field generated by the coil messy?

  2. How can I improve this?

Here is the code I use for the measuments:

int field[256];
int val;

void setup() {

    setPwmFrequency(MAGNET_PIN,8); //Sets the PWM frequency to 3900 Hz
    Serial.begin(9600);
    Serial.print('[');

    for (int i = 0; i < 256; i++){
        analogWrite(MAGNET_PIN, i);
        delay(50);
        val = analogRead(SENSOR_PIN)-512;
        field[i] = val;
        Serial.print(val);
        Serial.print(", ");
    }
    analogWrite(MAGNET_PIN, 0);
    Serial.println(']');
}

void loop() {

}

Here are some pictures of my setup, as requested:

enter image description here

enter image description here

enter image description here

Here is a picture of the signal after adding a 240 Ohm resistor to the LED:

enter image description here

Later today i encountered a new problem. The output now looks like this:

enter image description here

I am a bit confused, because I have not really made any changes. Could it be that my batteries are running low?

Best Answer

There are several problems, some of which are mentioned in other answers. I'll reiterate them for completeness's sake:

  1. The Arduino's output is loaded with the mosfet's gate capacitance. That can be several nF. Given that Arduino's outputs switch in ~10ns, so you're creating large current spikes with that load. The path of those spikes is not controlled and pollutes the rest of your circuit.

  2. The gate input is clamped to the LED's forward voltage. The mosfet might not be fully turned on.

  3. The output pin's driver is likely driving its full output current into the LED. Since that current is very likely to share lots of circuitry with the analog reference signal, you're corrupting your ADC reference voltage.

  4. The car battery can push hundreds of amperes through your circuit. With no fuse, you will burn your lab/house down.

  5. The inductor will likely need a snubber for EMI minimization.

  6. You have no slew rate control for mosfet turn-on/turn-off. You're likely switching the mosfet way too fast. You need to trade off some heat dissipation for improved electromagnetic compatibility.

  7. The fast switching PWM current path needs to be kept as short as possible: you need to isolate the inductor-switch loop from the battery and the rest of the circuit.

  8. There may be capacitive coupling between the inductor and the Hall sensor.

Below is an attempt at addressing all of the shortcomings.

Let's say that we want to keep the mosfet switching times roughly at 2% of the PWM period. The mosfet should switch in approximately 2.5us. The low-pass filter formed by the gate drive resistance and the gate capacitance should have a time constant of, say, half that value. Thus, assuming a 1nF gate capacitance, we need an equivalent 200 Ohm series resistor in the gate drive circuit.

Ensure that the fast-switching current loop, drawn in thick line, is kept as short as possible. The decoupling C1 needs to be a low-ESR electrolytic. The snubber C2/R3 can be designed following this procedure. The buffer U2 can be 74HC1G125 or similar. It needs to have its power supply decoupled with a 47nF capacitor, and have its output enabled (OE# input driven low). U2 needs to be close to M1. To ensure fastest turn-off, the D2/D3 is a pair of back-to-back 27V Zeners. F1 should be sized to accommodate the power consumption of L1. The GND of U2 needs to be tied to the star point at M1's drain. Ideally you'd also have ferrite beads between U2's VCC and the 3.3V supply rail, as well as between the star point at top of L1 and the output of the fuse. The FB1 is a ferrite bead - choose the largest impedance you can find that will handle 100mA.

schematic

simulate this circuit – Schematic created using CircuitLab

To minimize the Hall sensor's capacitive coupling to the inductor, there should be a non-magnetic, conductive shield around it. It won't hurt to make an explicit low-pass filter on the sensor's output, as well as decouple any high-frequency content with a ferrite bead FB2. Choose the largest impedance you can find that will handle 15mA.

schematic

simulate this circuit

I have added a representation of how the circuit might look on a breadboard. I've paid particular attention to minimizing the coil circuit's loop area. I've used 74HC14 inverters as a buffer, and I'm paralleling the outputs that drive the LED and the gate.

Due to 123D Circuits' limitations, I had to:

  • Represent the 24V battery and fuse by an AA battery holder and a resistor.

  • Represent the Hall sensor by a potentiometer.

  • Represent FB1 by a small inductor.

Breadboard layout