Hall Sensor Tachometer Code printing strangely small values

// The hall sensor pin
static const byte sensor_pin = 2;

// The base for RPM count
uint8_t revolution_halves;

// Here are all supported input type detection types
typedef enum { LOW_LEVEL, BOTH_EDGES, FALLING_EDGE, RISING_EDGE } transition_t;

// We don't wnat to rely upon attachInterrupt, here's our way! At least
// we know if a pin supports external interrupts or not.
//
// TODO: Account for other platforms than just ATmega328 (aka Uno)
inline bool enableTransitions(byte pin, transition_t type)
{
	switch (pin)
	{
		case 2:
			EICRA &= _BV(ISC11) | _BV(ISC10);
			EICRA |= type << ISC00;
			break;

		case 3:
			EICRA &= _BV(ISC01) | _BV(ISC00);
			EICRA |= type << ISC10;
			break;

		// Unsupported pin ID, no way!
		default:
			return false;
	}

	return true;
}

// Return true if a transition has occurred on the given pin
bool testTransition(byte pin)
{
	uint8_t state = EIFR;
	switch (pin)
	{
		case 2: state &= ~INTF0; break;
		case 3: state &= ~INTF1; break;

		// Unsupported pin ID, no way!
		default:
			return false;
	}

	// First reset the interrupt bit and return the detected state
	EIFR = state;
	return state;
}

// Return true if the display was updated. The delay is measured in milliseconds
// and also serves as a base for RPM computation
bool updateDisplay(uint8_t count)
{
	// For how many milliseconds we count pulses (also how often the LCD is updated)
	static const long interval_millis = 300;

	// Keep track of elapsed time and update LCD about 3 times a second
	static long prev_millis;

	// Wait a small amount of time before updating the display
	if (! (millis() - prev_millis >= interval_millis)) return false;

	// Now update the display
	// Note: we only send through the serial output so adjust to fit your
	// requirements (e.g. LCD update)
	const uint32_t rpm = 30 * count * 1000 / interval_millis;
	Serial.print("Rev=");
	Serial.println(count);

	// Set the new elapsed time and account for updating the LCD
	prev_millis = millis();
	return true;
}


void setup()
{
	Serial.begin(9600);
	pinMode(sensor_pin, INPUT_PULLUP);
	pinMode(LED_BUILTIN, OUTPUT);

	// Prepare slope detection on sensor pin (2, i.e. INT0)
	enableTransitions(sensor_pin, FALLING_EDGE);

	Serial.println("Ready!");
}

void loop()
{
	// Just a test...
	digitalWrite(LED_BUILTIN, digitalRead(sensor_pin) == LOW ? HIGH : LOW);
	if (testTransition(sensor_pin))
		revolution_halves++;

	// Reset the pulse counter after the display was updated
	if (updateDisplay(revolution_halves))
		revolution_halves = 0;
}

This code should be calculating my RPM, but seems only to be printing the raw amount of counts the sensor picks up during interval_millis which is set equal to 300. I am using an A3144 Hall sensor. I am using a fidget spinner with a small neodymium magnet.

digitalWrite(LED_BUILTIN, digitalRead(sensor_pin) == LOW ? HIGH : LOW);

^this def seems to work, and just by looking it seems to be flashing every time the magnet passes.

Does anyone see an apparent issue with the code? my project is due Monday, aka June 7th, 2021.

Any help is much appreciated. Thank you in advance
P.S. the LCD is obviously not being used at the moment, waiting for everything to prove accurate before I bother.

You maybe should mention your previous post on the same subject so members don't repeat advice.

You are telling it to print count not rpm.

const uint32_t rpm = 30 * count * 1000 / interval_millis;
Serial.print("Rev=");
Serial.println(count);

Hi,
Can I recommend you add an external pull up to the sensor, the 3144 can output up to 25mA.
So a 4K7 would be suitable.
The internal pull up is in the range of 40K and you may need less.

5 /4700 = 10.6mA.
5/40000 = 0.1mA

The Hall Effect test graphs use 20mA.

Hope that helps... Tom... :smiley: :+1: :coffee: :australia:

I'd say that suggestion is fair enough

Rev= is RPM

Hi Tom,

I've been using a 10k ohm external pull up resistor up until like 20 minutes before this post haha :slight_smile:

Just took it out because we are using pinMode(sensor_pin, INPUT_PULLUP); which can be used in place of the external pull up. I took it out to see if it would fix my issue.

although, I'm using a completely different code now. So any advice on this post is bound to be dissimilar to the advice offered on the other, especially to do the few responses I got, other than the much-obliged guidance of @wildbill

As # cattledog said you are printing count NOT rpm
AND uint32_t rpm is NOT a const.

I see what he meant now, I'll give this a try and define const uint32_t rpm.

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.