Hall Effect Sensor triggering multiple interrupts near threshold

Hi! I'm trying to make a tachometer/speedometer for a small electric car I'm building. I bought a hall effect sensor (digital and analog outputs) and some magnets. After testing it out by hand, I noticed that the hall effect sensor is triggering multiple interrupts near the threshold of detection. I've experienced this with a button before, but I did not expect the same with a hall effect sensor.

Can anyone explain why this is occurring? I could add some software debouncing logic, but wouldn't that limit the max rpm it can detect?

If you're interested, here's my code:

const int HallEffectInterruptPin = 2;
const unsigned long updatePeriod = 1e+6; // microseconds

volatile int revs = 0;

void setup() {
  attachInterrupt(digitalPinToInterrupt(HallEffectInterruptPin), rev, RISING);
  Serial.begin(9600);
}

void loop() {
  static unsigned long lastTime = micros();
  unsigned long currentTime = micros();
  
  if (currentTime - lastTime > updatePeriod) {
    detachInterrupt(digitalPinToInterrupt(HallEffectInterruptPin));

    int rpm = revs * 60e+6 / updatePeriod;
    lastTime = currentTime;
    revs = 0;
    
    attachInterrupt(digitalPinToInterrupt(HallEffectInterruptPin), rev, RISING);

    Serial.println(rpm);
  }
  
}

void rev() {
  revs++;
}

If it has analog output its probably not a hall switch, so there's no hysteresis. You could read the analog output
and add your own hysteresis in software... If you just want to count pulses get a hall switch,
not an analog sensor.

However we may be missing something and you haven't said which sensor this is - please get in the
habit of providing details (datasheet, partnumber) of hardware in a question unless you only
want a vague and possibly wrong answer. Details are all-important.

Yes, please post a link to the device.

The ones with analog and digital output are often based on an lm393 comparator configured without feedback for hysteresis control. Try a capacitor between the D0 pin and ground.

Hi!

I have the same problem as OP. I'm using part nr UGN3132UA on a breadboard. I've connected the supply pin with the 3.3V port at Arduino Uno, the ground pin goes to ground on Arduino, and the output pin is connected to pin 2 on the Arduino. My code is very similar to WillFreeman:

Whenever I move a magnet close to the sensor, I get 10-20 interrupts. Sometimes, I can keep my hand in a "sweet spot" where interrupts are being generated continuously. I'd rather get exactly one interrupt. What can I do ?

#define HALL_PIN 2
#define LED_PIN 13
bool lit = true;

void setup()
{
  Serial.begin(115200);
  attachInterrupt(digitalPinToInterrupt(HALL_PIN), magnet_detect, RISING);//Initialize the intterrupt pin (Arduino digital pin 2)
  pinMode(LED_PIN, OUTPUT);
  pinMode(HALL_PIN, INPUT_PULLUP);
  digitalWrite(LED_PIN, HIGH);
}
void loop()//Measure RPM
{
  if (digitalRead(HALL_PIN) == LOW) {
    Serial.println("LOW");
  }
  else Serial.println("HIGH");
  delay(1000);
}

void magnet_detect()//This function is called whenever a magnet/interrupt is detected by the arduino
{
  Serial.println("interrupt");
  lit = (digitalRead(HALL_PIN) == HIGH);
  if (lit) {
    digitalWrite(LED_PIN, HIGH);
  }
  else {
    digitalWrite(LED_PIN, LOW);
  }
}

I'm using part nr UGN3132UA on a breadboard. I've connected the supply pin with the 3.3V port at Arduino Uno,

You do not have the same kind of hall sensor as the original poster, and the data sheet I'm looking at indicates that yours is a 5v device. Why are you running it at 3.3v.

If it does not work in a stable fashion at 5v, I would try a stronger external pullup (10K or 4.7K) on the output than you get with the internal INPUT_PULLUP.

The sensor should not be oscillating as you indicate, but you could try some software debouncing with a lock out period between allowed interrupts. Choose a lock out time consistent with the application and the expected rate of switching.

void magnet_detect()//This function is called whenever a magnet/interrupt is detected by the arduino
{
  static unsigned long last_interrupt_time = 0;
  unsigned long interrupt_time = millis();
  const unsigned long lock_out = 50;
  // Serial.println("interrupt"); //no serial printing within an ISR
  if (interrupt_time - last_interrupt_time >= lock_out)
  {
    lit = (digitalRead(HALL_PIN) == HIGH);
    if (lit) {
      digitalWrite(LED_PIN, HIGH);
    }
    else {
      digitalWrite(LED_PIN, LOW);
    }
  }
}

cattledog:
You do not have the same kind of hall sensor as the original poster, and the data sheet I'm looking at indicates that yours is a 5v device. Why are you running it at 3.3v.

Oops! I missed the line about minimum operating voltage being 4.5V. I've connected it to the 5V pin and now there is no bouncing at all.

Thanks! :slight_smile: