I'm making a micromouse, this is my first robotic project I've ever done. I plan to use a flood fill algorithm and to do that I'm using hall effect sensor to tell the direction and rotation count of the wheel. I'm trying to code it so that both wheels are detected and both their states are printed in the serial monitor. But only one wheel is being detected. Here is my code so far.
// Pin numbers for the Hall effect sensors
const int sensorA_pin = 2;
const int sensorB_pin = 3;
const int sensorC_pin = 4;
const int sensorD_pin = 5;
// Variables to store the previous sensor states
int prevSensorAState = LOW;
int prevSensorBState = LOW;
int prevSensorCState = LOW;
int prevSensorDState = LOW;
// Variables to store the position and direction of rotation
int position = 0;
int direction = 0;
int direction2 = 0;
int position2 = 0;
void setup() {
// Set the Hall effect sensor pins as inputs
pinMode(sensorA_pin, INPUT);
pinMode(sensorB_pin, INPUT);
pinMode(sensorC_pin, INPUT);
pinMode(sensorD_pin, INPUT);
// Start the serial communication
Serial.begin(9600);
}
void loop() {
int sensorAState = digitalRead(sensorA_pin);
int sensorBState = digitalRead(sensorB_pin);
int sensorCState = digitalRead(sensorC_pin);
int sensorDState = digitalRead(sensorD_pin);
if (sensorAState != prevSensorAState) {
if (sensorBState != sensorAState) {
direction = 1; // Clockwise rotation
} else {
direction = -1; // Counterclockwise rotation
}
position += direction;
if (sensorCState != prevSensorCState) {
if (sensorDState != sensorCState) {
direction2 = 1; // Clockwise rotation
} else {
direction2 = -1; // Counterclockwise rotation
}
position2 += direction2;
Serial.print("Position: ");
Serial.println(position2);
Serial.print("Direction: ");
if (direction2 > 0) {
Serial.println("Clockwise2");
} else if (direction2 < 0) {
Serial.println("Counterclockwise2");
} else {
Serial.println("No rotation2");
}
}
// Output the position and direction of rotation
Serial.print("Position: ");
Serial.println(position);
Serial.print("Direction: ");
if (direction > 0) {
Serial.println("Clockwise");
} else if (direction < 0) {
Serial.println("Counterclockwise");
} else {
Serial.println("No rotation");
}
}
// Update the previous sensor states
prevSensorAState = sensorAState;
prevSensorBState = sensorBState;
prevSensorCState = sensorCState;
prevSensorDState = sensorDState;
}
How do I code it so that both wheels are detected and their states printed simultaneously.
Your code, formatted. Now it is easier to see that the handling of sensors C and D is wholly within the code block that handles sensors A and B. This seems wrong.
// Pin numbers for the Hall effect sensors
const int sensorA_pin = 2;
const int sensorB_pin = 3;
const int sensorC_pin = 4;
const int sensorD_pin = 5;
// Variables to store the previous sensor states
int prevSensorAState = LOW;
int prevSensorBState = LOW;
int prevSensorCState = LOW;
int prevSensorDState = LOW;
// Variables to store the position and direction of rotation
int position = 0;
int direction = 0;
int direction2 = 0;
int position2 = 0;
void setup() {
// Set the Hall effect sensor pins as inputs
pinMode(sensorA_pin, INPUT);
pinMode(sensorB_pin, INPUT);
pinMode(sensorC_pin, INPUT);
pinMode(sensorD_pin, INPUT);
// Start the serial communication
Serial.begin(9600);
}
void loop() {
int sensorAState = digitalRead(sensorA_pin);
int sensorBState = digitalRead(sensorB_pin);
int sensorCState = digitalRead(sensorC_pin);
int sensorDState = digitalRead(sensorD_pin);
if (sensorAState != prevSensorAState) {
if (sensorBState != sensorAState) {
direction = 1; // Clockwise rotation
} else {
direction = -1; // Counterclockwise rotation
}
position += direction;
if (sensorCState != prevSensorCState) {
if (sensorDState != sensorCState) {
direction2 = 1; // Clockwise rotation
} else {
direction2 = -1; // Counterclockwise rotation
}
position2 += direction2;
Serial.print("Position: ");
Serial.println(position2);
Serial.print("Direction: ");
if (direction2 > 0) {
Serial.println("Clockwise2");
} else if (direction2 < 0) {
Serial.println("Counterclockwise2");
} else {
Serial.println("No rotation2");
}
}
// Output the position and direction of rotation
Serial.print("Position: ");
Serial.println(position);
Serial.print("Direction: ");
if (direction > 0) {
Serial.println("Clockwise");
} else if (direction < 0) {
Serial.println("Counterclockwise");
} else {
Serial.println("No rotation");
}
}
// Update the previous sensor states
prevSensorAState = sensorAState;
prevSensorBState = sensorBState;
prevSensorCState = sensorCState;
prevSensorDState = sensorDState;
}
It's 2024. You might want to use 115200 instead of your grandfather's "fast" baud rate. It will help avoid timing issues that s l o w printing might cause.
// Start the serial communication
Serial.begin(115200);
Please post the code. The code that you came up with following the advices given, that compiles and runs but does not work.
Please describe what it does now, and how that differs to what it should do.
Obvsly there is still some kind of problem, but without seeing exactly what you are trying now, it is not possible to help.
This is what a rotary encoder does; @paulpaulson no doubt referred you to that article so that you might see how a rotary can be used, with the hope and expectation that you might benefit from learning about what you are trying to do.
Are you fixed the errors in the code?
The sketch in #7 is not a solution, it was only formatted to make the errors more visible for you.
But now you have to fix the errors yourself.
That's right, it is not. It is exactly the code @wyreyt posted.
With the obvious changes, it responds to both encoders.
I say repsond, but the response is unsatisfactory. This is caused by the large amount of printing that is done at the 20th century band rate of 9600.
Changing to
Serial.begin(115200); // it's 2024!
lets the polling successfully read both sensors. I wonder with doubt, however, that this primitive method will work in the context of any other code that might take attention away from the need to continuously poll the sensor inputs.
An alternate method would have no such problem. Since each hall effect sensor is indistinguishable logically from a rotary encoder, it is again suggested that @wyreyt find and deploy a good rotary encoder algorithm.
@paulpaulson has provided a link that appears to cover the ups and downs (see what I did there?) of various ways of capturing the signals and providing meaningful output.
Also, sorry for any misunderstandings, I'm very new to robotics and code so I'm still learning. This is the current code.
// Pin numbers for the Hall effect sensors
const int sensorA_pin = 2;
const int sensorB_pin = 3;
const int sensorC_pin = 6;
const int sensorD_pin = 7;
// Variables to store the previous sensor states
int prevSensorAState = LOW;
int prevSensorBState = LOW;
int prevSensorCState = LOW;
int prevSensorDState = LOW;
// Variables to store the position and direction of rotation
int position = 0;
int direction = 0;
int direction2 = 0;
int position2 = 0;
void setup() {
// Set the Hall effect sensor pins as inputs
pinMode(sensorA_pin, INPUT);
pinMode(sensorB_pin, INPUT);
pinMode(sensorC_pin, INPUT);
pinMode(sensorD_pin, INPUT);
// Start the serial communication
Serial.begin(115200);
}
void loop() {
int sensorAState = digitalRead(sensorA_pin);
int sensorBState = digitalRead(sensorB_pin);
int sensorCState = digitalRead(sensorC_pin);
int sensorDState = digitalRead(sensorD_pin);
if (sensorAState != prevSensorAState) {
if (sensorBState != sensorAState) {
direction = 1; // Clockwise rotation
} else {
direction = -1; // Counterclockwise rotation
}
position += direction;
if (sensorCState != prevSensorCState) {
if (sensorDState != sensorCState) {
direction2 = 1; // Clockwise rotation
} else {
direction2 = -1; // Counterclockwise rotation
}
position2 += direction2;
Serial.print("Position2: ");
Serial.println(position2);
Serial.print("Direction2: ");
if (direction2 > 0) {
Serial.println("Clockwise2");
} else if (direction2 < 0) {
Serial.println("Counterclockwise2");
} else {
Serial.println("No rotation2");
}
}
// Output the position and direction of rotation
Serial.print("Position: ");
Serial.println(position);
Serial.print("Direction: ");
if (direction > 0) {
Serial.println("Clockwise");
} else if (direction < 0) {
Serial.println("Counterclockwise");
} else {
Serial.println("No rotation");
}
}
// Update the previous sensor states
prevSensorAState = sensorAState;
prevSensorBState = sensorBState;
prevSensorCState = sensorCState;
prevSensorDState = sensorDState;
}
What this code is meant to do is respond to the rotation's of two different wheels. It's meant to then tell me the direction it's spinning and how far it has changed from the starting position, adding 1 for every clockwise rotation and taking one away for every counter-clockwise rotation. I'm using a donut magnet with 8 poles on each wheel, and two hall effect sensors per wheel at a 112.5 degree angle I believe. I'm using an arduino Uno as well. It should output the position of wheel 1 when it turns by adding or subtracting 1 from the position variable and outputting the direction it's spinning, it does this successfully. It should do the same for wheel 2 but the serial monitor does not respond to any change in wheel 2's position.
Why is the handling of inputs C and D still wholly within the block that handles inputs A and B? There could be a good reason, somehow I don't think so.
The formatting you applied shows this clearly. Code that is within a block is indented, that is for human consumption, the compiler doesn't care, but the indentation level lets you see what is subordinate to what.
if (A and B whatever) {
stuff for A and B
if (C and D whatever) {
stuff for C and D
}
stuff for both
}
probably should look like
if (A and B whatever) {
stuff for A and B
}
if (C and D whatever) {
stuff for C and D
}
stuff for both sets
So what would you do if this was your code? As I said, I'm very new to code so I can't understand half of what you're saying, the rules of indentation are not known to me so this is why I'm asking for help, I barely know what I'm doing.
// Pin numbers for the Hall effect sensors
const int sensorA_pin = 2;
const int sensorB_pin = 3;
const int sensorC_pin = 6;
const int sensorD_pin = 7;
// Variables to store the previous sensor states
int prevSensorAState = LOW;
int prevSensorBState = LOW;
int prevSensorCState = LOW;
int prevSensorDState = LOW;
// Variables to store the position and direction of rotation
int position = 0;
int direction = 0;
int direction2 = 0;
int position2 = 0;
void setup() {
// Set the Hall effect sensor pins as inputs
pinMode(sensorA_pin, INPUT);
pinMode(sensorB_pin, INPUT);
pinMode(sensorC_pin, INPUT);
pinMode(sensorD_pin, INPUT);
// Start the serial communication
Serial.begin(115200);
}
void loop() {
int sensorAState = digitalRead(sensorA_pin);
int sensorBState = digitalRead(sensorB_pin);
int sensorCState = digitalRead(sensorC_pin);
int sensorDState = digitalRead(sensorD_pin);
if (sensorAState != prevSensorAState) {
if (sensorBState != sensorAState) {
direction = 1; // Clockwise rotation
} else {
direction = -1; // Counterclockwise rotation
}
position += direction;
if (sensorCState != prevSensorCState) {
if (sensorDState != sensorCState) {
direction2 = 1; // Clockwise rotation
} else {
direction2 = -1; // Counterclockwise rotation
}
position2 += direction2;
Serial.print("Position2: ");
Serial.println(position2);
Serial.print("Direction2: ");
if (direction2 > 0) {
Serial.println("Clockwise2");
} else if (direction2 < 0) {
Serial.println("Counterclockwise2");
} else {
Serial.println("No rotation2");
}
}
// Output the position and direction of rotation
Serial.print("Position: ");
Serial.println(position);
Serial.print("Direction: ");
if (direction > 0) {
Serial.println("Clockwise");
} else if (direction < 0) {
Serial.println("Counterclockwise");
} else {
Serial.println("No rotation");
}
}
// Update the previous sensor states
prevSensorAState = sensorAState;
prevSensorBState = sensorBState;
prevSensorCState = sensorCState;
prevSensorDState = sensorDState;
}
Ok, I just shuffled around the statements in the void loop section and it worked, I'll post the code and mark it as the solution for future people.
// Pin numbers for the Hall effect sensors
const int sensorA_pin = 2;
const int sensorB_pin = 3;
const int sensorC_pin = 6;
const int sensorD_pin = 7;
// Variables to store the previous sensor states
int prevSensorAState = LOW;
int prevSensorBState = LOW;
int prevSensorCState = LOW;
int prevSensorDState = LOW;
// Variables to store the position and direction of rotation
int position = 0;
int direction = 0;
int direction2 = 0;
int position2 = 0;
void setup() {
// Set the Hall effect sensor pins as inputs
pinMode(sensorA_pin, INPUT);
pinMode(sensorB_pin, INPUT);
pinMode(sensorC_pin, INPUT);
pinMode(sensorD_pin, INPUT);
// Start the serial communication
Serial.begin(115200);
}
void loop() {
int sensorAState = digitalRead(sensorA_pin);
int sensorBState = digitalRead(sensorB_pin);
int sensorCState = digitalRead(sensorC_pin);
int sensorDState = digitalRead(sensorD_pin);
if (sensorAState != prevSensorAState) {
if (sensorBState != sensorAState) {
direction = 1; // Clockwise rotation
} else {
direction = -1; // Counterclockwise rotation
}
position += direction;
// Output the position and direction of rotation
Serial.print("Position: ");
Serial.println(position);
Serial.print("Direction: ");
if (direction > 0) {
Serial.println("Clockwise");
} else if (direction < 0) {
Serial.println("Counterclockwise");
} else {
Serial.println("No rotation");
}
}
if (sensorCState != prevSensorCState) {
if (sensorDState != sensorCState) {
direction2 = 1; // Clockwise rotation
} else {
direction2 = -1; // Counterclockwise rotation
}
position2 += direction2;
Serial.print("Position2: ");
Serial.println(position2);
Serial.print("Direction2: ");
if (direction2 > 0) {
Serial.println("Clockwise2");
} else if (direction2 < 0) {
Serial.println("Counterclockwise2");
} else {
Serial.println("No rotation2");
}
}
// Update the previous sensor states
prevSensorAState = sensorAState;
prevSensorBState = sensorBState;
prevSensorCState = sensorCState;
prevSensorDState = sensorDState;
}