Filter/smooth analog output from a Hall Sensor

I have browsed the forums and the web and found some useful information but nothing that fully answers my question so I am asking for help.

I am working with a Hall Sensor to sense magnetic field when exposed to a bipolar magnetic strip and actuate a cylinder if conditional statements are true.

Applicable Hardware:
-Microcontroller: Arduino Mega 2560
-Hall Sensor: HHP-SU 696 (see attached data sheet)

Problems:

  1. The Hall sensor is picking up a lot of background “noise”.

For calibration I use a smoothing function to take 500 readings while computing the running average with the final value taken as the analog value returned by the Hall sensor when no magnetic field is applied. This appears to be working ok, see attachment “calibration_image”.

The raw analog value returned by the Hall sensor via the serial monitor appears very jumpy. My calculations to convert from analog to Gauss depend on the raw value so I have tried to smooth it the same way as in calibration. While this does smooth the value it is not enough, my final analog value should be close to zero but it still fluctuates too much (ideally I need it as close to zero as possible). See “compensated_analog”. KEEP IN MIND THIS IS WHEN NO MAGNETIC FIELD IS APPLIED.

Question: How do I go about filtering or smoothing to get that analog value closer to zero? (see smoothing function below)

  1. I convert the analog value (returned from the Hall sensor to the Arduino) to Gauss. Because the Hall sensor’s extreme sensitivity (29.2 [mV/T]) one jump in analog value is a far too large jump in Gauss because the poles on the magnetic strip I am working with are approx 150 to 200 Gauss and -150 to -200 Gauss. See “analog_to_Gauss” for my conversion calculations.

Question: How do I accurately scale down the analog to gauss conversion factor?

I am not an Arduino master by any means. If I forgot to add any necessary details please let me know.

Smoothing function used:

// Define the number of samples to keep track of. The higher the number,
// the more the readings will be smoothed, but the slower the output will
// respond to the input. Using a constant rather than a normal variable lets
// use this value to determine the size of the readings array.
// see: http://arduino.cc/en/Tutorial/Smoothing
float noFieldHallCalibraiton2() {

const int numReadings = 50;
int readings[numReadings]; // the readings from the analog input
int index = 0; // the index of the current reading
int total = 0; // the running total
int average = 0; // the average
int breakCount = 1; // used to determine how many samples to calibrate over

// setup output table
Serial.print(“Loop Count”);
Serial.print("\t");
Serial.print(“Raw [analog]”);
Serial.print("\t");
Serial.println("Smoothing FN [analog] ");

//*************************************************************************
// initialize readings to 0
for(int thisReading = 0; thisReading < numReadings; thisReading++)
readings[thisReading] = 0;

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

while(1) {
// subtract the last reading:
total= total - readings[index];
// read from the sensor:
readings[index] = analogRead(HallSensorPin);
// add the reading to the total:
total= total + readings[index];

// send it to the computer as ASCII digits
Serial.print(breakCount);
Serial.print("\t\t");
Serial.print(readings[index]);
Serial.print("\t\t");

// advance to the next position in the array:
index = index + 1;

// if we’re at the end of the array…
if (index >= numReadings)
// …wrap around to the beginning:
index = 0;

// calculate the average:
average = total / numReadings;

Serial.println(average);
delay(1); // delay in between reads for stability

// this determines when to break
breakCount++;
if(breakCount == 500) {
break;
} //end if

} //end while loop

return(average);

} //end noFieldHallCalibration2

HHP-SU_696.pdf (65 KB)

analog_to_Gauss.png

How have you connected the Hall sensor to the Arduino?

PS - it sounds to me that you have a raw Hall sensor, and you will need a precision amplifier before you can use it with an Arduino. You would be better off getting a Hall sensor with a built-in amplifier, such as this one http://uk.farnell.com/allegro-microsystems/a1302kua-t/sensor-hall-effect-linear-3sip/dp/1791388. The built-in amplifier makes it much more sensitive. Even better, if you are just trying to sense the bipolar magnetic strip going past, use a digital Hall switch such as US1881.

How have you connected the Hall sensor to the Arduino?

See the schematic “Hall_schematic”. It is from the Arduino Mega 5 [V] supply to analog pin A0.

PS - it sounds to me that you have a raw Hall sensor, and you will need a precision amplifier before you can use it with an Arduino.

I have been directed to use this sensor for my project due to small size, high sensitivity and large range requirements so unfortunately I cannot use a different one unless absolutely necessary.

Even better, if you are just trying to sense the bipolar magnetic strip going past, use a digital Hall switch such as US1881.

I need to sense position movement. My current approach is to sense a Gauss value that is in between the South pole and the North pole by using an analog sensor in addition to more conditional statements to determine if a change in position has occurred. I am not sure how I would do this with a digital hall sensor.

-I was advised to use a notch filter to handle the background “noise” in the lab. I am having difficulty understanding this. The Hall sensor is reading magnetic field and returning an analog value. I thought magnetic field doesn’t have a frequency. So maybe it is electromagnetic field causing the background noise (I am in a mechatronics lab)?

-How would I determine the frequency to use a low pass notch filter (I assume this would be around 15 Hz?)

-I was considering using something like the Matlab function “iirnotch”. I assume it would be easier to just develop my own filter and keep all the code in Arduino. Any advice on this?
http://www.mathworks.com/help/dsp/ref/iirnotch.html

I attached another document with limited info on the HHP-SU 696 Hall Sensor.

Thanks for your help so far!

HallProbes-1.PDF (1.03 MB)

I thought magnetic field doesn't have a frequency.

It does if you change the intensity, it is the rate of change of the reading that gives it a frequency.

to use a low pass notch filter

There is no such thing. You either have a low pass filter, lets trough low frequency cuts out high ones, or you have a notch filter that just removes one frequency.

A notch filter is for removing a frequency you don't want. It is not clear why you have been advised to use one unless you have an interfering signal at a fixed frequency like mains hum.

That data sheet seems to have little to do with your schematic.

OK, there are several things wrong:

  1. You have far too much current flowing through the Hall sensor. It is designed for 5mA current and has an input resistance of 67 ohms. You have connected it directly across the 3.3V pin, which will give (3.3/67) = 49mA. So you have probably wrecked it already. You need to use a series resistor to bring the current down to 5mA.

  2. The device appears to be a raw Hall sensor, without an integrated amplifier. You say you have chosen the device for its high sensitivity, however its sensitivity (2.5mV/T) is very low compared to devices with built-in amplifier (25000mV/T for the A1301 whose datasheet I linked to). One Tesla is a very strong magnetic field, and your magnetic strip will produce very much less than a Tesla. So you need to measure microvolts from that device.

  3. A raw Hall sensor needs a differential amplifier. You can't just ground one of the outputs and measure the voltage on the other, as you have done.

In summary, you might possibly get that device to work in that application if you use a series resistor and put a high gain differential amplifier between it and the Arduino. Even then, the input offset voltage of the amplifier will make getting a good reading difficult. That is completely the wrong device for sensing the alternating poles of a magnetic strip passing. I suggest you spend $1 on a US1881 instead.

In response to Grumpy_Mike

It does if you change the intensity, it is the rate of change of the reading that gives it a frequency

The magnetic strip with North and South poles is moved manually by a user so I don’t think it is possible to determine a frequency because the movement would be at varying speeds and could stop at random.

Thank you for clarifying the difference between low pass and notch filters.
Some of the people advising me to filter is based on their experience where they know the signal they expect to receive and how to eliminate the unwanted background frequencies. They were working with EMG rather than magnetic field.

If my hall sensor is picking up jumpy readings with no applied magnetic field do you have an idea of a source the “noise” could be coming from?

I attached more graphs of output data I am getting. The samples were smoothed using a running 50 value average for all except “appliedMField_noSmoothing”.


In response to dc42

You are correct about the resistor. I apologize, I accidentally attached an older schematic, I am using a 1kOhm resistor and the Hall sensor is supplied with the 5 V Arduino pin.

For the Hall sensor, thanking you for further explaining the advantages of your recommendations. I will request funding for a different sensor (I know it is cheap but still need to go through the paper work)

If I do use the US1881 can I expect to not have jumps in data due to the built in amplifier? In other words is their a filter implemented in the built in amplifier?

The US1881 is a latch Hall sensor, does this mean it is digital? I still think I need to use an analog sensor for my position tracking algorithm as I need to sense a transition between poles for movement to occur. Is there any analog device you would recommend?

Thanks you both for the help!

AerE: If I do use the US1881 can I expect to not have jumps in data due to the built in amplifier? In other words is their a filter implemented in the built in amplifier?

The US1881 is a latch Hall sensor, does this mean it is digital? I still think I need to use an analog sensor for my position tracking algorithm as I need to sense a transition between poles for movement to occur. Is there any analog device you would recommend?

The output for that sensor (assuming the datasheet is correct and the sensitivity is 2.5mV/T) is far too small to read on an Arduino analog pin. Also, if you have a 1K resistor to 5V now, then the output should be only about 200mV, which would give much lower readings. I suspect that the output pin of the device has gone open circuit and the oscillations you are seeing are because you are measuring a floating pin.

The US1181 output goes low when it sees a north pole, and stays low until it sees a south pole, at which point it goes high. Then it stays high until it sees a north pole, and the cycle repeats. Isn't this exactly what you need? See https://www.sparkfun.com/datasheets/Components/General/Hall-US1881EUA.pdf. It needs a magnetic field strength of only 10mT to operate reliably. It has an open drain output, so you need to provide it with a pullup resistor (e.g. enable the one on the digital input pin you connect it to). If for any reason you decide on an analog sensor, then try the A1301 or A1302 that I linked to earlier. If you need to go through paperwork to get them, then I suggest you get both a US1881 and a A1301.

PS - depending on where you are, the US1881 may not be available from local distributors. Here http://uk.farnell.com/honeywell-s-c/ss460s/sensor-hall-effect-bipolar-to-92/dp/2301768 is an alternative.

I suspect that the output pin of the device has gone open circuit and the oscillations you are seeing are because you are measuring a floating pin.

This initially was my problem so I re-attached the Hall sensor output wire to a wire I have attached to the Arduino analog input pin (probably not the best method but the Hall sensor wire is tiny so I didn't put it in the bread board).

Isn't this exactly what you need?

Almost but not quite. The magnetic strip reads: N/S/N/S/N/S... When the Hall sensor senses an N (north) pole it will actuate the cylinder and magnetize the N pole to become an S pole. Then I need to track if movement has occurred. Complications arise as the movement of the magnetic strip is controlled by the user at random.

So- I was thinking the analog would be able to sense the former N pole, now S pole after magnetization. Sense a transition value between the newly magnetized S pole and the next S pole on the strip. Sense the next S pole on the strip and therefore a movement has occurred.

If I use the digital Hall sensor it will sense an N pole, then sense the newly magnetized S pole then sense the next S pole on the magnetic strip if the user moves it. It will continually sense the newly magnetized S pole if the user does not move it.

So the analog Hall sensor allows sensing the transition between 2 poles to determine if movement occurred or not.

AerE: So the analog Hall sensor allows sensing the transition between 2 poles to determine if movement occurred or not.

If you are saying that you need to sense that one S pole has passed the sensor and the magnetic field has dropped, and then sense the arrival of a new S pole without an intervening N pole, then I agree, you should use an analog Hall sensor.