I am using a hall effect sensor to detect positions as a wheel rotates. The speed is roughly 2 RPM so considerably slow. There are 12 positions, and the wheel is 6 inches in diameter. So, the magnets are not interfering with one another as there is plenty of space between them.
The Hall Sensor I am using has a built in LED and blinks each time a magnet is detected, I can see that the sensor is not missing the pulses, however the Arduino seems to be. I want it to move 12 positions and then stop in this example. However, it often moves 16-18 instead. I tried using an interrupt to ensure the sensor is read, however this still did not seem to help.
I think I have stared at this issue too long and just cannot find the issue. If anyone with a fresh set of eyes and better understanding than myself is able to help that would be wonderful!
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 20, 4); // set the LCD address to 0x3F for a 16 chars and 2 line display
volatile int hallFlag;
const int hallSensor = 19;
int hallSensorState;
int hallSensorPrevState;
int hallSensorCount = 0;
const int motorPin1 = 11;
const int motorPin2 = 13;
const int pwm = 12;
int motorSpeed = 100;
#define CLK 3
#define DT 4
#define SW 2
int counter = 0;
int currentStateCLK;
int lastStateCLK;
String currentDir = "";
unsigned long lastButtonPress = 0;
int currentPosition;
int prevPosition = 1;
int currentRotation;
int prevRotation;
void setMotor(int dir, int motorSpeed, int pwm) {
currentRotation = dir;
analogWrite(pwm, motorSpeed);
if (dir == 1) {
digitalWrite(motorPin1, HIGH);
digitalWrite(motorPin2, LOW);
} else if (dir == -1) {
digitalWrite(motorPin1, LOW);
digitalWrite(motorPin2, HIGH);
} else {
digitalWrite(motorPin1, LOW);
digitalWrite(motorPin2, LOW);
}
}
void autoHome() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Homing....");
delay(1000);
hallSensorState = digitalRead(hallSensor);
while (hallSensorState != LOW) {
setMotor(1, motorSpeed, pwm);
hallSensorState = digitalRead(hallSensor);
Serial.println();
if (hallSensorState == HIGH) {
Serial.print("Hall Sensor State: HIGH");
} else if (hallSensorState == LOW) {
Serial.print("Hall Sensor State: LOW");
} else {
Serial.print("Hall Sensor State: Unknown");
}
}
setMotor(0, motorSpeed, pwm);
currentPosition = 1;
delay(2000);
}
void ISR_hallSensor() {
hallFlag = 1;
}
void setup() {
Serial.begin(9600);
lcd.init();
lcd.clear();
lcd.backlight(); // Make sure backlight is on
attachInterrupt(digitalPinToInterrupt(19), ISR_hallSensor, FALLING);
pinMode(hallSensor, INPUT);
pinMode(motorPin1, OUTPUT);
pinMode(motorPin2, OUTPUT);
pinMode(pwm, OUTPUT);
// Set encoder pins as inputs
pinMode(CLK, INPUT);
pinMode(DT, INPUT);
pinMode(SW, INPUT_PULLUP);
// Setup Serial Monitor
Serial.begin(9600);
// Read the initial state of CLK
lastStateCLK = digitalRead(CLK); // put your setup code here, to run once:
autoHome();
}
void loop() {
int btnState = digitalRead(SW);
if (btnState == LOW) {
currentPosition = 1;
}
hallSensorState = digitalRead(hallSensor);
Serial.print("Current Poistion is: ");
Serial.print(currentPosition);
Serial.print(" Hall Sensor Previous State is: ");
Serial.print(hallSensorPrevState);
Serial.print(" Flag State is: ");
Serial.print(hallFlag);
Serial.print(" Hall Sensor State is: ");
Serial.println(hallSensorState);
while (currentPosition < 13) {
Serial.print("Current Poistion is: ");
Serial.print(currentPosition);
Serial.print(" Hall Sensor Previous State is: ");
Serial.print(hallSensorPrevState);
Serial.print(" Flag State is: ");
Serial.print(hallFlag);
Serial.print(" Hall Sensor State is: ");
Serial.println(hallSensorState);
setMotor(1, motorSpeed, pwm);
hallSensorState = digitalRead(hallSensor);
// currentRotation = -1;
if (hallFlag == 1 && hallSensorState != hallSensorPrevState) {
// if (hallSensorState == LOW && hallSensorState != hallSensorPrevState) {
// currentPosition = currentPosition + 1;
if (currentRotation == 1) {
currentPosition = currentPosition + 1;
} else if (currentRotation == -1) {
currentPosition = currentPosition - 1;
}
hallSensorPrevState = hallSensorState;
hallFlag = 0;
}
}
setMotor(0, motorSpeed, pwm);
}
