AttachInterrupts with Hall sensor, count in big steps

Hi!

I tried to count my hall sesnsor (Like this) digital output with attachinterrupts, but when I pull a magnet in front of the sensor (the hall module led is lighting), in the serial terminal, te counted number is jump by 300-400 or more.
How i do, that if I pull a magnet in front of it once, the counter is increment only one step? What Id oing wrong?

My code:

#define INTERRUPT_INPUT 2

int pulse_counter = 0;


void setup()
{
  pinMode(INTERRUPT_INPUT, INPUT_PULLUP);
  Serial.begin(9600);
  
  attachInterrupt(digitalPinToInterrupt(INTERRUPT_INPUT),interrupt_handler,RISING);
}


void loop(){
    delay(1000);
    Serial.println(pulse_counter);
}


void interrupt_handler()
{
  pulse_counter++;
}

And my serial output (when the value is changet, I pull a magnet in front of it once) :

0
0
0
598
598
845
845
1015
1207
2542
2624
2624
3225
3225
4155
4209

Very big thank you for the answers, and sorry for my bad english!

Do you know which hall sensor is on that module ? Can you read what is written on it (with a magnifier) ?
It could be noise. Is there any capacitor on that module to stop noise or oscillation ?

Please add the word 'volatile' to the pulse_counter: volatile unsigned int pulse-counter;

Some hall sensors measure the magnetic field and output a analog signal. Some hall sensors have a digital output and switch at a certain level. If you would use a hall sensor with digital output, I'm sure it will work. I think that the module is causing the trouble.

I use one of this: 1PCS Hall Magnetic Standard Linear Module For Arduino AVR CA NEW | eBay

It's have analog, and digital output, i use the digital output.
I see on the Hall sensor: 49E 7098C

I add the "volatile" to the pulse counter, but nothing has changed!

I tried a similar sensor, but the result is the same.

UPDATE: I tried with a simple button with an 1k resistor, and the result is the same!

Thank you for help!

rajnaviktor:
UPDATE: I tried with a simple button with an 1k resistor, and the result is the same!

That could be contact bounce.

Try:

#define INTERRUPT_INPUT 2

volatile int pulse_counter = 0;

void setup()
{
  pinMode(INTERRUPT_INPUT, INPUT_PULLUP);
  Serial.begin(9600);  
  attachInterrupt(digitalPinToInterrupt(INTERRUPT_INPUT),interrupt_handler,RISING);
}

void loop(){
    static int lastPulseCount=0;
    int currentPulseCount;

    noInterrupts();
    currentPulseCount = pulse_counter;
    interrupts();

    if (currentPulseCount != lastPulseCount) {
      Serial.println(currentPulseCount);
      lastPulseCount = currentPulseCount;
    }    
}

void interrupt_handler()
{
  pulse_counter++;
}

I try this code, but nothing has changed, the problem is the same. :confused:

I chechk de connection, and use new cable, but it did not help anything.

What Arduino are you using, and what voltage is applied to the sensor module?

The sensor modules 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. Also try adjusting the blue potentiometer as that should be setting a threshold.

I also think that the 49E sensors are polarity sensitive. What kind of magnet are you using? I it a disc you can flip over? Try reversing the magnet polarity the sensor is seeing.

If the hardware changes with threshold adjustment, the capacitor and the magnet polarity do not work, you can write the interrupt routine so that there is a lock out period between responses. That will eliminate multiple responses, but the lock out needs to be implemented with regard to the frequency of expected response i.e. rpm and the number of magnets, etc.

I use Arduino UNO, and connect the module to the Arduino board 5V pin. Yes, it sensitive to magnet polarity, but if i use the bad polarity, the module is do nothing.

By the pontentionmeter adjusting, it's a little better, but not good, still bouncing, but I set it to the minimum.
Tomorrow I try it with a capacitor!

Thank you for your answer.

rajnaviktor:
By the pontentionmeter adjusting, it's a little better, but not good, still bouncing, but I set it to the minimum.
Tomorrow I try it with a capacitor!

you can also debounce the sensor in Software by making sure some time has passed between interrupts.

something like this:

void interrupt_handler()
{
  static uint32_t lastSenseMillis = 0;
  if (millis() - lastSenseMillis > 50) // assures 50 milliseconds have elapsed between signals, you have to play around with this
  {
    pulse_counter++;
    lastSenseMillis = millis();
  }
}

Whit this code, the counting is work correctly! :slight_smile:

But i want to count about 1000 impulse/min, and it seems slow, so i tried to modify the millisecond, but if i reduce to 15 millisecond, the bouncing is come again, and in the highest millisecond value i feel, it too slow! :frowning:

rajnaviktor:
Whit this code, the counting is work correctly! :slight_smile:

But i want to count about 1000 impulse/min, and it seems slow, so i tried to modify the millisecond, but if i reduce to 15 millisecond, the bouncing is come again, and in the highest millisecond value i feel, it too slow! :frowning:

16Hz is an eon for your arduino...

I'm not sure I understand your issue

But i want to count about 1000 impulse/min, and it seems slow, so i tried to modify the millisecond, but if i reduce to 15 millisecond, the bouncing is come again, and in the highest millisecond value i feel, it too slow! :frowning:

What do you mean by "too slow". Are you missing pulses? How do you know? Please post your latest complete code. You can always test the code independent of the sensor by using the tone function to create a clean square wave at different frequencies to see what the code can handle.

With 1000 pulses/minute there are 60 milliseconds between pulses. The 50 millisecond lock out period should not cause you to miss counts. Clearly, you should set the lock out period for more than 15 ms if you see bouncing.

Serial output at 9600 baud is slow. Use Serial.begin(115200) if you are using the serial monitor with the ide.

I think this miss impulses, because i use a small fan with a magnet on propeller, and if i tried with 5V, the result is same as i tried with 12V, but i hear and see, the fan speed is much more.

Yes, i calculated, that in theroy, the 50ms is ok, but it does not seem. :confused:

I try with 115200 baud rate, but the problem is not this, because noting has changed!

UPDATE: Now I change the RISING to FALLING in the attacInterrupt, and it seems, works correctly, but i don't understand, why?

My latest code:

#define INTERRUPT_INPUT 2

volatile int pulse_counter = 0;

void setup()
{
  pinMode(INTERRUPT_INPUT, INPUT_PULLUP);
  Serial.begin(115200);  
  attachInterrupt(digitalPinToInterrupt(INTERRUPT_INPUT),interrupt_handler,FALLING);
}

void loop(){
    static int lastPulseCount=0;
    int currentPulseCount;

    noInterrupts();
    currentPulseCount = pulse_counter;
    interrupts();

/*    if (currentPulseCount != lastPulseCount) {*/
      Serial.println(currentPulseCount);
      lastPulseCount = currentPulseCount;
//    }    
}

void interrupt_handler()
{
  static uint32_t lastSenseMillis = 0;
  if (millis() - lastSenseMillis > 50) // assures 50 milliseconds have elapsed between signals, you have to play around with this
  {
    pulse_counter++;
    lastSenseMillis = millis();
  }
}

UPDATE: Now I change the RISING to FALLING in the attachInterrupt, and it seems, works correctly, but i don't understand, why?

One signal edge is cleaner than the other. You could use an oscilloscope to view this.

It is common to switch the interrupt edge of the interrupt from RISING to FALLING or the other way around when developing a program. I would not worry about which edge you use if the results are satisfactory.

The root cause is likely something to do with the internal sensor electronics and how the analog hall signal is processed by the comparator. The configuration and strength of the pullup or pulldown resistors can also effect which signal edge is preferred.

Hi There, I am using the optical encoders disk mounted on the shaft of wheelchair's motor. But I'm getting the irregular response of ticks on arduino. I am using above code. But I'm unable to get precise ticks count. Anyone if can help I will be very thankful.