Control of the gear motor at a given speed

What happens when you test it?

1 Like

Everything works well, I mean, is the algorithm built well.

What do you consider "the algorithm"?

Replace this by your limit switch test.

1 Like

I think, is the code well constructed?
Will there be any problems in the future due to these delays?
Is this considered a big delay?

Can you please tell me in more detail what you mean
Like add a second limit switch?

Yes, but not for your problem.

Your code is "blocking". This means if you want to home multiple motors then it will home one motor after another. In a non-blocking approach all the motors can be homed at the same time.

What's the purpose of waiting past lastActionTime?
Why do you start the motor when it already is at home position?

Check your program logic and comments. If you don't understand what your code does then you are not yet ready for adding further functionality.

1 Like

Thank you for the information
The motor has 2 position.
To recognize the home position, I use the limit switch
The second starting position is also needed. But due to pin shortage I can't use the limit switch

That is when "cams" are used. Only one switch can be triggered by multiple pins on a cam. Just have to remember the sequence of switch operations based on motor direction.

1 Like

I decided to connect a second limit switch in order to turn the motor and stop where necessary.
The algorithm looks like this:
When the engine is powered, it rotates in the opposite direction, and the first limit switch will be pressed, the engine will stop.

If you press the touch button, if the first limit switch is pressed, the engine will turn forward, and when the second limit switch is pressed, the engine will stop.

If you press the touch button, if you press the second limit switch, the engine will turn back, and when the first limit switch is pressed, the engine will stop.
Please help me to correct the code so that later it would be convenient to add more motors and limit switches

enum barrierStates {
  UNKNOWN,
  DOWN,
  GOING_UP,
  UP,
  GOING_DOWN
};

enum barrierStates barrierState;

const uint8_t upLimitSwitchPin = 22;    
const uint8_t downLimitSwitchPin = 23;  
const uint8_t touchSwitchPin = 10;      
const int motorPin4 = 4;
const int motorPin5 = 5;

uint8_t upLimitSwitch;
uint8_t downLimitSwitch;
uint8_t touchSwitch;
uint8_t prevTouchSwitch;

void setup() {
  Serial.begin(9600);
  pinMode( upLimitSwitchPin, INPUT_PULLUP );
  pinMode( downLimitSwitchPin, INPUT_PULLUP );
  pinMode( touchSwitchPin, INPUT_PULLUP );
  pinMode(motorPin4, OUTPUT);
  pinMode(motorPin5, OUTPUT);

  delay(100);
  touchSwitch = digitalRead( touchSwitchPin );
  prevTouchSwitch = touchSwitch;
  
  // a HIGH here means the limit switch is open
  upLimitSwitch = digitalRead( upLimitSwitchPin );
  downLimitSwitch = digitalRead( downLimitSwitchPin );
  
  // determine the initial barrier position
  if ( upLimitSwitch == LOW && downLimitSwitch == LOW ){
    Serial.println(F("ERROR - both limit switches activated"));
    while(1);
  }
  else if ( upLimitSwitch == HIGH && downLimitSwitch == HIGH ){
    barrierState = UNKNOWN;
    Serial.println(F("BARRIER POSITION UNKNOWN"));
  }
  else if ( upLimitSwitch == LOW ) {
    Serial.println(F("BARRIER UP"));
    barrierState = UP;
  }
  else {
    Serial.println(F("BARRIER DOWN"));
    barrierState = DOWN;
  }
}

void loop() {
  // assume HIGH = switch touched
  touchSwitch = digitalRead( touchSwitchPin );

  switch ( barrierState ) {
    case UNKNOWN:
      // INSERT YOUR CODE TO ACTIVATE MOTOR TO MAKE BARRIER GO UP
      digitalWrite(motorPin4, HIGH);
      upLimitSwitch = digitalRead( upLimitSwitchPin );
      if ( upLimitSwitch == LOW ) {
        // INSERT YOUR CODE TO STOP MOTOR
        digitalWrite(motorPin4, LOW);
        Serial.println(F("BARRIER UP"));
        barrierState = UP;
      }
      break;
      
    case DOWN:
      if (( touchSwitch != prevTouchSwitch ) && ( touchSwitch == HIGH ) ) {
        // INSERT YOUR CODE TO ACTIVATE MOTOR TO MAKE BARRIER GO UP
        digitalWrite(motorPin4, HIGH);
        Serial.println(F("BARRIER GOING UP"));
        barrierState = GOING_UP;
      }
      break;
      
    case GOING_UP:
      upLimitSwitch = digitalRead( upLimitSwitchPin );
      if ( upLimitSwitch == LOW ) {
        // INSERT YOUR CODE TO STOP MOTOR
        digitalWrite(motorPin4, LOW);
        Serial.println(F("BARRIER UP"));
        barrierState = UP;
      }
      break;
      
    case UP:
      if (( touchSwitch != prevTouchSwitch ) && ( touchSwitch == HIGH ) ) {
        // INSERT YOUR CODE TO ACTIVATE MOTOR TO MAKE BARRIER GO DOWN
        digitalWrite(motorPin5, HIGH);
        Serial.println(F("BARRIER GOING DOWN"));
        barrierState = GOING_DOWN;
      }
      break;
      
    case GOING_DOWN:
      downLimitSwitch = digitalRead( downLimitSwitchPin );
      if ( downLimitSwitch == LOW ) {
        // INSERT YOUR CODE TO STOP MOTOR
        digitalWrite(motorPin5, LOW);
        Serial.println(F("BARRIER DOWN"));
        barrierState = DOWN;
      }
      break;
  }
  prevTouchSwitch = touchSwitch;
}

Where did this magic pin come from? Did you forget that you really did have a spare pin?

1 Like

I have used arduino nano before. Now switched to arduino mega

Good luck with your project.

1 Like

Where you zero the encoder position.

You can have any number of positions with the encoder positions. Start adding the encoder to your code.

1 Like

So far, I've given up on the encoder.
At first I want to use only gear motors

These are absolutely unrelated. You need the encoders for control of the motor speed and position.

1 Like

But the encoder sensor is not present in the project. Or is it not a sensor but software?

Or do you mean such fix the position in the algorithm

int homePosition = 0;
int closePosition = 1;

int currentPosition = homePosition;

void setup() {
  currentPosition = homePosition;
}

void loop() {
  currentPosition = closePosition;

  currentPosition = homePosition;
}

The encoder is part of the motor.

1 Like

I use n20 motors in this project. They don't have an encoder.


Okay, what do I need to do next to adjust the algorithm so that it's convenient to add motors and limit switches later?

These motors have encoders. If you use motors without encoders then add encoders or start a new thread where no speed or position is given.

1 Like

I'm sorry if I don't understand you. The algorithm I sent is missing the speed and position of the motor.
The algorithm has a gear motor and a limit switch.

enum barrierStates {
  UNKNOWN,
  DOWN,
  GOING_UP,
  UP,
  GOING_DOWN
};

enum barrierStates barrierState;

const uint8_t upLimitSwitchPin = 22;    
const uint8_t downLimitSwitchPin = 23;  
const uint8_t touchSwitchPin = 10;      
const int motorPin4 = 4;
const int motorPin5 = 5;

uint8_t upLimitSwitch;
uint8_t downLimitSwitch;
uint8_t touchSwitch;
uint8_t prevTouchSwitch;

void setup() {
  Serial.begin(9600);
  pinMode( upLimitSwitchPin, INPUT_PULLUP );
  pinMode( downLimitSwitchPin, INPUT_PULLUP );
  pinMode( touchSwitchPin, INPUT_PULLUP );
  pinMode(motorPin4, OUTPUT);
  pinMode(motorPin5, OUTPUT);

  delay(100);
  touchSwitch = digitalRead( touchSwitchPin );
  prevTouchSwitch = touchSwitch;
  
  // a HIGH here means the limit switch is open
  upLimitSwitch = digitalRead( upLimitSwitchPin );
  downLimitSwitch = digitalRead( downLimitSwitchPin );
  
  // determine the initial barrier position
  if ( upLimitSwitch == LOW && downLimitSwitch == LOW ){
    Serial.println(F("ERROR - both limit switches activated"));
    while(1);
  }
  else if ( upLimitSwitch == HIGH && downLimitSwitch == HIGH ){
    barrierState = UNKNOWN;
    Serial.println(F("BARRIER POSITION UNKNOWN"));
  }
  else if ( upLimitSwitch == LOW ) {
    Serial.println(F("BARRIER UP"));
    barrierState = UP;
  }
  else {
    Serial.println(F("BARRIER DOWN"));
    barrierState = DOWN;
  }
}

void loop() {
  // assume HIGH = switch touched
  touchSwitch = digitalRead( touchSwitchPin );

  switch ( barrierState ) {
    case UNKNOWN:
      // INSERT YOUR CODE TO ACTIVATE MOTOR TO MAKE BARRIER GO UP
      digitalWrite(motorPin4, HIGH);
      upLimitSwitch = digitalRead( upLimitSwitchPin );
      if ( upLimitSwitch == LOW ) {
        // INSERT YOUR CODE TO STOP MOTOR
        digitalWrite(motorPin4, LOW);
        Serial.println(F("BARRIER UP"));
        barrierState = UP;
      }
      break;
      
    case DOWN:
      if (( touchSwitch != prevTouchSwitch ) && ( touchSwitch == HIGH ) ) {
        // INSERT YOUR CODE TO ACTIVATE MOTOR TO MAKE BARRIER GO UP
        digitalWrite(motorPin4, HIGH);
        Serial.println(F("BARRIER GOING UP"));
        barrierState = GOING_UP;
      }
      break;
      
    case GOING_UP:
      upLimitSwitch = digitalRead( upLimitSwitchPin );
      if ( upLimitSwitch == LOW ) {
        // INSERT YOUR CODE TO STOP MOTOR
        digitalWrite(motorPin4, LOW);
        Serial.println(F("BARRIER UP"));
        barrierState = UP;
      }
      break;
      
    case UP:
      if (( touchSwitch != prevTouchSwitch ) && ( touchSwitch == HIGH ) ) {
        // INSERT YOUR CODE TO ACTIVATE MOTOR TO MAKE BARRIER GO DOWN
        digitalWrite(motorPin5, HIGH);
        Serial.println(F("BARRIER GOING DOWN"));
        barrierState = GOING_DOWN;
      }
      break;
      
    case GOING_DOWN:
      downLimitSwitch = digitalRead( downLimitSwitchPin );
      if ( downLimitSwitch == LOW ) {
        // INSERT YOUR CODE TO STOP MOTOR
        digitalWrite(motorPin5, LOW);
        Serial.println(F("BARRIER DOWN"));
        barrierState = DOWN;
      }
      break;
  }
  prevTouchSwitch = touchSwitch;
}