Hall Sensor Counting Seems Wrong

Hi,

I am using the A3144 hall effect sensor to detect RPM of a brushed DC motor. I used the interrupt for counting and reporting the RPM in the main loop. The motor specification says that it runs about 5000-6000 RPM no load. However, when I connect everything, the RPM in serial output shows 30000 RPM to 40000 RPM. I did turn the motor off and spin the rotating plate to see if interrupt kicks off. If i turn it manually, the counter is right. I wonder what can possibly go wrong in this case.

volatile unsigned int revolution = 0;
pinMode(PIN_HALL_SENSOR, INPUT_PULLUP);
digitalWrite(PIN_HALL_SENSOR, LOW);
attachInterrupt(digitalPinToInterrupt(2), count_rotation, RISING);

if (millis() - lastmillis >= 1000) {
//Update every second, this will be equal to reading frecuency (Hz).
//Serial.println("Calculating RPM");
detachInterrupt(digitalPinToInterrupt(2));//Disable interrupt when calculating
rpm = (revolution) * 60 ; // Convert frecuency to RPM, note: this works for one interruption per full rotation. For two interrups per full rotation use half_revolutions * 30.
Serial.print("RPM =\t"); //print the word "RPM" and tab.
Serial.print(rpm); // print the rpm value.
Serial.print("\t Hz=\t"); //print the word "Hz".
Serial.println(revolution); //print revolutions per second or Hz. And print new line or enter.
revolution = 0; // Restart the RPM counter
lastmillis = millis(); // Uptake last millis
attachInterrupt(digitalPinToInterrupt(2), count_rotation, RISING); //enable interrupt
}

void count_rotation() {
revolution = revolution + 1;
}

I did measure the Arduino INPUT pins. I get 5V when the magnet is right above the hall sensor and 0V for other positions. Any ideas? Thanks for any suggestion in advance.

Regards,
Sunny Lo.

The output of the 3144 should have a 10K pullup to 5v, and I don't see that on your circuit diagram.

What is the transisitor doing?

pinMode(PIN_HALL_SENSOR, INPUT_PULLUP);
digitalWrite(PIN_HALL_SENSOR, LOW);

You set INPUT_PULLUP, but then turn it off with the digitalWrite LOW. Why?

The schematic was not right. I draw again. The transistor is just inverting the output, so Arduino read HIGH as magnet is on the hall sensor and LOW when it is not. Since there is a physical pull up resistor for arduino, so i change to pin mode to INPUT and digitalWrite HIGH, and it is still the same (see attached serial output). Any further suggestions? Thanks very much.

serial_output.png

cattledog:
You set INPUT_PULLUP, but then turn it off with the digitalWrite LOW. Why?

Yep. If the pin is configured as an input with pullup..... then what's the reason for 'writing' to that pin?

sunnyksl:
i change to pin mode to INPUT and digitalWrite HIGH, and it is still the same (see attached serial output). Any further suggestions? Thanks very much.

It is like...... your arduino is meant to monitor external voltage transitions on that pin...... but you interfere with that monitoring by using write commands to that pin.

Just make sure that your code is doing what you need need - check all the commands/functions you use in your program.

changed the code already and it doesn't work, still counting a lot of RISING triggers in 1 seconds. The problem I can't figure out is the output works as I expected when I just rotating the platform using my hand, I can see it rise and fall in serial monitor by just looping digitalRead(2) with all interrupts disabled. I am pulling my hair out.

Your circuit has the following errors:

A capacitor across the transistor collector-emitter - completely wrong, remove it.

Unnecessary inverter stage - remove it, route the hall sensor output straight to the Arduino pin.

No decoupling capacitor on the Hall switch chip. Add a 0.1uF ceramic between Vcc and Gnd right
next to the A3144.

Your code repeatedly detaches and re-attaches interrupts - don't do things this way, it will generate
spurious results. Just leave the ISR running all the time, and learn how to communicate with an
ISR properly within noInterrupts() / interrupts() section.