Control of the gear motor at a given speed

Hi, everybody
I am working on a project related to a motor and a button.
The algorithm looks like this:

  1. When the power is connected, all motors turn back and stop when the limit switch is pressed.

  2. There is a regular button with which you can switch cells

  3. There is a touch button, with which you can perform an action inside the cell

  4. If you press the touch button, the motor turns forward at a given number of revolutions and stops

  5. If you press the motor again, turn back according to the specified number of revolutions.

The algorithm works well up to point 5. The problem is that the motor turns well forward, but it's hard to turn back.

I thought it was a motor failure, but no, I checked, turned back and forth everything is fine, but there is an error in the algorithm.

Can you please help in correcting the algorithm code

Code:

// Define the pins used to control the Maxon 344515 engine and the touch button
const int motorPin2 = 2; // New motor pin 2
const int motorPin3 = 3; // New motor pin 3
const int motorPin4 = 4;
const int motorPin5 = 5;


const int motorPin6 = 10;
const int motorPin7 = 11;
const int motorPin8 = A0;
const int motorPin9 = A1;

const int touchPin6 = 6;
const int stepsPerRotation = 200; // Change this value depending on the motor specifications

int numRotations = 10; // Change this value to specify the number of rotations
int motorSpeed = 100; // Change this value to specify the speed of the motor

bool forwardRotation = true;
const int LIMIT_SWITCH_PIN = 7;

int currentFunction = 1;
int touchButtonState = LOW;
int touchButtonPrevState = LOW;
int normalButtonState = LOW;
int normalButtonPrevState = LOW;
int functionCount = 4;

void setup() {
  Serial.begin(9600);
  pinMode(motorPin2, OUTPUT); // New motor pin 2
  pinMode(motorPin3, OUTPUT); // New motor pin 3
  pinMode(motorPin4, OUTPUT);
  pinMode(motorPin5, OUTPUT);

  pinMode(motorPin6, OUTPUT); // New motor pin 2
  pinMode(motorPin7, OUTPUT); // New motor pin 3
  pinMode(motorPin8, OUTPUT);
  pinMode(motorPin9, OUTPUT);

  pinMode(8, INPUT_PULLUP); // Normal button
  pinMode(touchPin6, INPUT_PULLUP);
  pinMode(LIMIT_SWITCH_PIN, INPUT_PULLUP);
  motorBackward();
  motorBackward1();
  motorBackward2();
  motorBackward3();
  while (digitalRead(LIMIT_SWITCH_PIN) == HIGH) {}
  motorStop();
  motorStop1();
  motorStop2();
  motorStop3();

}

void motorForward() {
  digitalWrite(motorPin4, HIGH);
  digitalWrite(motorPin5, LOW);
  digitalWrite(motorPin2, HIGH); // New motor pin 2
  digitalWrite(motorPin3, LOW); // New motor pin 3
}
void motorBackward() {
  digitalWrite(motorPin4, LOW);
  digitalWrite(motorPin5, HIGH);
  digitalWrite(motorPin2, LOW); // New motor pin 2
  digitalWrite(motorPin3, HIGH); // New motor pin 3
}
void motorStop() {
  digitalWrite(motorPin4, LOW);
  digitalWrite(motorPin5, LOW);
  digitalWrite(motorPin2, LOW); // New motor pin 2
  digitalWrite(motorPin3, LOW); // New motor pin 3
}



void motorForward1() {
  digitalWrite(motorPin2, HIGH); // New motor pin 2
  digitalWrite(motorPin3, LOW); // New motor pin 3
}

void motorBackward1() {
  digitalWrite(motorPin2, LOW); // New motor pin 2
  digitalWrite(motorPin3, HIGH); // New motor pin 3
}

void motorStop1() {
  digitalWrite(motorPin2, LOW); // New motor pin 2
  digitalWrite(motorPin3, LOW); // New motor pin 3
}





void motorForward2() {
  digitalWrite(motorPin4, HIGH);
  digitalWrite(motorPin5, LOW);
}
void motorBackward2() {
  digitalWrite(motorPin4, LOW);
  digitalWrite(motorPin5, HIGH);
}
void motorStop2() {
  digitalWrite(motorPin4, LOW);
  digitalWrite(motorPin5, LOW);
}





void motorForward3() {
  digitalWrite(motorPin6, HIGH);
  digitalWrite(motorPin7, LOW);
  digitalWrite(motorPin8, HIGH); // New motor pin 2
  digitalWrite(motorPin9, LOW); // New motor pin 3

}
void motorBackward3() {
  digitalWrite(motorPin6, LOW);
  digitalWrite(motorPin7, HIGH);
  digitalWrite(motorPin8, LOW); // New motor pin 2
  digitalWrite(motorPin9, HIGH); // New motor pin 3

}
void motorStop3() {
  digitalWrite(motorPin6, LOW);
  digitalWrite(motorPin7, LOW);
  digitalWrite(motorPin8, LOW); // New motor pin 2
  digitalWrite(motorPin9, LOW); // New motor pin 3
}









void loop() {
  touchButtonState = digitalRead(6);
  if (touchButtonState == HIGH && touchButtonPrevState == LOW) {
    switch (currentFunction) {
      case 1:
        function1();
        break;
      case 2:
        function2();

        break;
      case 3:
        function3();

        break;
      case 4:
        function4();

        break;
    }
  }
  touchButtonPrevState = touchButtonState;

  normalButtonState = digitalRead(8);
  if (normalButtonState == HIGH && normalButtonPrevState == LOW) {
    currentFunction++;
    if (currentFunction > functionCount) {
      currentFunction = 1;
    }
    Serial.print("Switched to function ");
    Serial.println(currentFunction);
  }
  normalButtonPrevState = normalButtonState;
  delay(50);
}

void function1() {
  Serial.print("function1");
  int numSteps = numRotations * stepsPerRotation;
  if (forwardRotation) {
    motorForward();
  } else {
    motorBackward();
  }
  for (int i = 0; i < numSteps; i++) {
    digitalWrite(motorPin4, HIGH);
    digitalWrite(motorPin2, HIGH); // New motor pin 2
    delayMicroseconds(500);
    digitalWrite(motorPin4, LOW);
    digitalWrite(motorPin2, LOW); // New motor pin 2
    delayMicroseconds(500);
  }
  motorStop();
  Serial.print("Number of revolutions: ");
  Serial.println(numRotations);
  forwardRotation = !forwardRotation;
}
void function2() {
  Serial.print("function2");
  int numSteps = numRotations * stepsPerRotation;
  if (forwardRotation) {
    motorForward1();
  } else {
    motorBackward1();
  }
  for (int i = 0; i < numSteps; i++) {
    digitalWrite(motorPin2, HIGH); // New motor pin 2
    delayMicroseconds(500);
    digitalWrite(motorPin2, LOW); // New motor pin 2
    delayMicroseconds(500);
  }
  motorStop1();
  Serial.print("Number of revolutions: ");
  Serial.println(numRotations);
  forwardRotation = !forwardRotation;
}
void function3() {
  Serial.print("function3");
  int numSteps = numRotations * stepsPerRotation;
  if (forwardRotation) {
    motorForward2();
  } else {
    motorBackward2();
  }
  for (int i = 0; i < numSteps; i++) {
    digitalWrite(motorPin4, HIGH);

    delayMicroseconds(500);
    digitalWrite(motorPin4, LOW);
    delayMicroseconds(500);
  }
  motorStop2();
  Serial.print("Number of revolutions: ");
  Serial.println(numRotations);
  forwardRotation = !forwardRotation;
}
void function4() {
  Serial.print("function4");
  int numSteps = numRotations * stepsPerRotation;
  if (forwardRotation) {
    motorForward3();
  } else {
    motorBackward3();
  }
  for (int i = 0; i < numSteps; i++) {
    digitalWrite(motorPin6, HIGH);
    digitalWrite(motorPin8, HIGH); // New motor pin 2
    delayMicroseconds(500);
    digitalWrite(motorPin6, LOW);
    digitalWrite(motorPin8, LOW); // New motor pin 2
    delayMicroseconds(500);

  }
  motorStop3();
  Serial.print("Number of revolutions: ");
  Serial.println(numRotations);
  forwardRotation = !forwardRotation;
}

Hi,

How many motors and buttons?
What is a cell?
What action does this other button do?

Can we please have a circuit diagram?
An image of a hand drawn schematic will be fine, include ALL power supplies, component names and pin labels.

Thanks... Tom.. :smiley: :+1: :coffee: :australia:

1 Like

upload a copy of the serial monitor output (as text not an image)
possible add some more print statement showing button states etc - you can always remove them when the system works

1 Like

Sorry if this is inconvenient. I've done what I can

Your code is a bad mix of stepper and DC motor functions that can not work properly. Which driver modules do you use?

See e.g. this topic.

1 Like

I use the drv8833 driver

I checked this code even on a stepper motor, the result is the same
Connected the stepper motor in this way
1st red wire: Driver A
2nd gray wire: 5 V Encoder
3rd gray wire: Encoder output A
4th gray wire: encoder output B
5th gray wire: GND encoder
6th grey wire: Driver Board

Or should I connect these wires to the driver?
3rd gray wire: encoder output A
4th gray wire: encoder output B

Connect your motor first (red) and last grey wire to the H-bridge.
Use code like your motorForward(), motorBackward() and motorStop() or the motor 3 functions to drive your motors. The motor 1 and 2 functions don't work with your motors and driver boards.
Edit: each motor driver channel has 2 control inputs.

Connect the remaining wires directly to the Arduino and use an encoder library to track the motor position from Encoder output A and B.

1 Like

Thanks for the information, I'll try it.
But for now I will use gear motors rather than stepper motors. Can you help fix the error in the algorithm?

The motor drivers are okay for geared DC motors.

Please forget my previous reply, I had in mind a different driver.

If you don't understand the code then rename the motor pins into Fwd1, Back1, Fwd2 and so on. Then set the Fwd and Back inputs for a motor for the direction, either Fwd1=true, Back1=false for forward movement of motor 1, or Fwd2=false, Back2=true for backward movement of motor 2.

2 Likes

I did so. So I realized that everything works well.
But I need the algorithm that I sent and it partially works. I need to make it fully work.

Set the motor positions to 0 when the limit switch is reached (home position). To return to the home position run the motor backwards and wait until its position is 0 again. Read the motor position from the Encoder library, stepsPerRotation etc. applies to stepper motors only.

1 Like

This is the algorithm I wanted to use.
That is, we wanted to make 4 limit switches for every 4 motors.
To fix the home position.
Well, then let's start developing the algorithm more correctly and anew.

Now I'm going to try to make an algorithm and send

Here's a simple algorithm made
How do I use this encoding on the main algorithm?

// Motor control pins
const int MOTOR_PIN1 = 2;
const int MOTOR_PIN2 = 3;

// Limit switch and touch button pins
const int LIMIT_SWITCH_PIN = 7;
const int TOUCH_BUTTON_PIN = 6;

// Motor direction constants
const int FORWARD = HIGH;
const int BACKWARD = LOW;

void setup() {
  // Set motor pins as outputs
  pinMode(MOTOR_PIN1, OUTPUT);
  pinMode(MOTOR_PIN2, OUTPUT);

  // Set limit switch and touch button pins as inputs with pull-up resistors
  pinMode(LIMIT_SWITCH_PIN, INPUT_PULLUP);
  pinMode(TOUCH_BUTTON_PIN, INPUT_PULLUP);

  // Set motor initial direction to backward
  digitalWrite(MOTOR_PIN1, BACKWARD);
  digitalWrite(MOTOR_PIN2, FORWARD);
}

void loop() {
  // Check if touch button is pressed
  if (digitalRead(TOUCH_BUTTON_PIN) == LOW) {
    // If motor is at home position (limit switch is pressed)
    if (digitalRead(LIMIT_SWITCH_PIN) == LOW) {
      // Spin motor forward
      digitalWrite(MOTOR_PIN1, FORWARD);
      digitalWrite(MOTOR_PIN2, BACKWARD);

      // Wait for motor to complete numRotations revolutions
      int numRotations = 5;
      int delayTime = 60000 * numRotations / 60; // Convert rotations per minute to delay time in milliseconds
      delay(delayTime);

      // Stop motor
      digitalWrite(MOTOR_PIN1, BACKWARD);
      digitalWrite(MOTOR_PIN2, BACKWARD);
    }
    // If motor is not at home position
    else {
      // Spin motor backward
      digitalWrite(MOTOR_PIN1, BACKWARD);
      digitalWrite(MOTOR_PIN2, FORWARD);

      // Keep spinning motor backward until limit switch is pressed
      while (digitalRead(LIMIT_SWITCH_PIN) == HIGH) {
        // Do nothing, just keep spinning
      }

      // Stop motor
      digitalWrite(MOTOR_PIN1, BACKWARD);
      digitalWrite(MOTOR_PIN2, BACKWARD);
    }

    // Wait for touch button release
    while (digitalRead(TOUCH_BUTTON_PIN) == LOW) {
      // Do nothing, wait for button release
    }
  }
}

Format the code in the IDE for better readability.

That part is unusable if you don't know how far to move and how much time a rotation takes.

After the motor stops it may be necessary/helpful to move back slowly until the limit switch is released again. Then set the encoder position to zero (home).

For slow motor movement you can use PWM as indicated in the driver datasheet.

1 Like

As I know this driver has no PWM. You are probably confused with the Tb6612 driver. Because they are very similar in appearance.

I didn't really understand this part. Can you please send a sketch?

But the Arduino has :slight_smile:

Remove it from the code.

2 Likes

It turned out like this:
If you do this, the motor cannot spin forward after pressing the limit switch?

// Motor control pins
const int MOTOR_PIN1 = 2;
const int MOTOR_PIN2 = 3;

// Limit switch and touch button pins
const int LIMIT_SWITCH_PIN = 7;
const int TOUCH_BUTTON_PIN = 6;

// Motor direction constants
const int FORWARD = HIGH;
const int BACKWARD = LOW;

void setup() {
  // Set motor pins as outputs
  pinMode(MOTOR_PIN1, OUTPUT);
  pinMode(MOTOR_PIN2, OUTPUT);

  // Set limit switch and touch button pins as inputs with pull-up resistors
  pinMode(LIMIT_SWITCH_PIN, INPUT_PULLUP);
  pinMode(TOUCH_BUTTON_PIN, INPUT_PULLUP);

  // Set motor initial direction to backward
  digitalWrite(MOTOR_PIN1, BACKWARD);
  digitalWrite(MOTOR_PIN2, FORWARD);
}

void loop() {
  // Check if touch button is pressed
  if (digitalRead(TOUCH_BUTTON_PIN) == LOW) {
    // If motor is at home position (limit switch is pressed)
    if (digitalRead(LIMIT_SWITCH_PIN) == LOW) {
      // Spin motor forward
      digitalWrite(MOTOR_PIN1, FORWARD);
      digitalWrite(MOTOR_PIN2, BACKWARD);

      // Stop motor
      digitalWrite(MOTOR_PIN1, BACKWARD);
      digitalWrite(MOTOR_PIN2, BACKWARD);
    }
    // If motor is not at home position
    else {
      // Spin motor backward
      digitalWrite(MOTOR_PIN1, BACKWARD);
      digitalWrite(MOTOR_PIN2, FORWARD);

      // Keep spinning motor backward until limit switch is pressed
      while (digitalRead(LIMIT_SWITCH_PIN) == HIGH) {
        // Do nothing, just keep spinning
      }

      // Stop motor
      digitalWrite(MOTOR_PIN1, BACKWARD);
      digitalWrite(MOTOR_PIN2, BACKWARD);
    }

    // Wait for touch button release
    while (digitalRead(TOUCH_BUTTON_PIN) == LOW) {
      // Do nothing, wait for button release
    }
  }
}

Consider how many microseconds this code will spin the motor forward?

You may look into https://docs.arduino.cc/built-in-examples/digital/StateChangeDetection techniques to do actions on the changes of the buttons & limit switches instead of the levels.

1 Like

Your described algorithm does not count partial revolutions and cannot stop a revolution at the same exact location each time.

1 Like

Does this count as millis or is it also a delay?


// Motor control pins
const int MOTOR_PIN1 = 2;
const int MOTOR_PIN2 = 3;

// Limit switch and touch button pins
const int LIMIT_SWITCH_PIN = 7;
const int TOUCH_BUTTON_PIN = 6;

// Motor direction constants
const int FORWARD = HIGH;
const int BACKWARD = LOW;

// Motor spin time constants
const unsigned long MOTOR_SPIN_TIME = 2000; // 2 seconds

// Variables to keep track of motor spin time and last action time
unsigned long motorSpinStartTime = 0;
unsigned long lastActionTime = 0;

void setup() {
  // Set motor pins as outputs
  pinMode(MOTOR_PIN1, OUTPUT);
  pinMode(MOTOR_PIN2, OUTPUT);

  // Set limit switch and touch button pins as inputs with pull-up resistors
  pinMode(LIMIT_SWITCH_PIN, INPUT_PULLUP);
  pinMode(TOUCH_BUTTON_PIN, INPUT_PULLUP);

  // Set motor initial direction to backward
  digitalWrite(MOTOR_PIN1, BACKWARD);
  digitalWrite(MOTOR_PIN2, FORWARD);
}

void loop() {
  // Check if touch button is pressed and enough time has passed since last action
  if (digitalRead(TOUCH_BUTTON_PIN) == LOW && millis() - lastActionTime >= 1000) {
    // If motor is at home position (limit switch is pressed)
    if (digitalRead(LIMIT_SWITCH_PIN) == LOW) {
      // Spin motor forward
      digitalWrite(MOTOR_PIN1, FORWARD);
      digitalWrite(MOTOR_PIN2, BACKWARD);
      motorSpinStartTime = millis();
      // Wait for motor spin time
      while (millis() - motorSpinStartTime < MOTOR_SPIN_TIME) {
        // Do nothing, wait for spin time to complete
      }

      // Stop motor
      digitalWrite(MOTOR_PIN1, BACKWARD);
      digitalWrite(MOTOR_PIN2, BACKWARD);
    }
    // If motor is not at home position
    else {
      // Spin motor backward
      digitalWrite(MOTOR_PIN1, BACKWARD);
      digitalWrite(MOTOR_PIN2, FORWARD);

      // Keep spinning motor backward until limit switch is pressed
      while (digitalRead(LIMIT_SWITCH_PIN) == HIGH) {
        // Do nothing, just keep spinning
      }

      // Stop motor
      digitalWrite(MOTOR_PIN1, BACKWARD);
      digitalWrite(MOTOR_PIN2, BACKWARD);
    }

    // Update last action time
    lastActionTime = millis();

    // Wait for touch button release
    while (digitalRead(TOUCH_BUTTON_PIN) == LOW) {
      // Do nothing, wait for button release

    }}}