Gear Motor

I am using a gear motor with hall sensor, I am reading the revolutions per position. After a certain amount of time, the gear motor somehow couldn't get back to the exact position where I have set it. I am trying to rotate the motor clockwise and anti-clockwise.

How can I fix this issue to get a more precise angle?

I have different positions and I have set the revolutions to 706 per position. 2 cycles are completed the motor is going to the exact positions, for the 3 times when it starts the rotation, It can't get to its exact angles and is slightly off.

I have some fraction on my setup

I have attached the code I am using. I have change the revolutions if it can help me to get the gear motor back to the position I have set it to.

dc-motor_test.ino (1.87 KB)

For the benefit of other readers this is the OP's program

// Define pin setup
#define motor_in1 7
#define motor_in2 8
#define motor_enA 9

int half_revolutions = 0;


void setup() {
  // Set pin mode
  pinMode(motor_enA, OUTPUT);
  pinMode(motor_in1, OUTPUT);
  pinMode(motor_in2, OUTPUT);

  Serial.begin(115200);
  
  // Hallsensor connected to the interrupt pin (Pin 2 on Arduino Uno)
  attachInterrupt(0, magnet_detect, RISING);
}

void loop() {
  // Run full cycle to each position and back to 0
  move_amount(1, 706, 255);
  Serial.print(1);
  delay(1000);

  move_amount(-1, 712, 255);
  Serial.print(0);
  delay(1000);
 
 

  move_amount(2, 710, 255);
  Serial.print(2);
  delay(1000);
 

  move_amount(-2, 715, 255);
  Serial.print(0);
  delay(1000);



  move_amount(3, 700, 255);
  Serial.print(3);
  delay(1000);



  move_amount(-3, 712, 255);
  Serial.print(0);
  delay(1000);



move_amount(-1, 702, 255);
  Serial.print(4);
  delay(1000);



move_amount(1,710, 255);
  Serial.print(0);
  delay(1000);

move_amount(-2, 700, 255);
  Serial.print(5);
  delay(1000);
 
  
move_amount(2, 715, 255);
  Serial.print(0);
  delay(1000);




move_amount(-3,720, 255);
  Serial.print(6);
  delay(1000);



  
move_amount(3, 715, 80);
    Serial.print(0);
  delay(1000);

}

void magnet_detect() {
  half_revolutions++;
}

void move_amount(int no_pos, int revolutions_per_pos, int carousel_speed) {
  half_revolutions = 0;
  if (no_pos < 0) {
    // Set rotation direction
    digitalWrite(motor_in1, HIGH);
    digitalWrite(motor_in2, LOW);
    no_pos *= -1;
  }
  else {
    // Set rotation direction
    digitalWrite(motor_in1, LOW);
    digitalWrite(motor_in2, HIGH);
  }

  while (half_revolutions < (no_pos * (2 * revolutions_per_pos))) {
    Serial.println(half_revolutions);
    analogWrite(motor_enA, 180);
  }
  analogWrite(motor_enA, 0);
}

A few things occur to me ...

This line

int half_revolutions = 0;

should be

volatile int half_revolutions = 0;

because the variable is being updated in the ISR and the compiler might not know that.

And because it is a two-byte variable you should copy it into a working variable with interrupts suspended to avoid the risk of the value changing while you read it. Have a look at how it is done in the example code in this link

It may be that variable friction in the motor and gearbox is throwing your precision off - for example it may stop more quickly in one direction rather than the other.

Is your sensor on the motor shaft or on the output shaft of the gearbox

...R

A motor does not stop immediately.
Gears can introduce a backlash, different for both directions.