Motor with 2 limit switches

Hello all, the project I am working on is to press a button, and have a motor spin until it hits a limit switch and stops. Then, when the button is pressed again, the motor spins in the opposite direction until it hits the other limit switch. The code below works for these purposes, but the only issue seems to be that when a limit switch is pressed, I cannot start the motor back up with the button until that limit switch is released. In the real world however, the motor will be resting on the limit switch until activated again.

I am using an Arduino Uno R3 and a L298N motor driver.

I am very new to Arduino, so any help is appreciated. Below is also a wiring diagram for my set up, which could also be a part of the problem. Thank you in advance!

int motorAenablePin = 6;              // Motor A, PWM-Pin
int motorAfwdPin = 7;                // Motor A, control line 1
int motorArevPin = 2;                // Motor A, control line 2
boolean motorRun = false;
char motorDirection = 'F';

int controlButtonPin = 8;
int controlButtonState = 0;
int buttonPushCounter = 0;      // counter for the number of button presses
int lastControlButtonState = 0;        // previous state of the button

int rightLimitSwitchPin = 9;
int leftLimitSwitchPin = 10;

int rightLimitswitchState = 0;
int leftLimitswitchState = 0;




void setup() {

    Serial.begin(9600);

    pinMode(motorAenablePin, OUTPUT);
    pinMode (motorAfwdPin, OUTPUT);
    pinMode (motorArevPin, OUTPUT);
    digitalWrite(motorAenablePin, HIGH);

    pinMode(controlButtonPin,INPUT);
    pinMode(rightLimitSwitchPin,INPUT);
    pinMode(leftLimitSwitchPin,INPUT);

}

//=========

void loop() {
    readSwitches();
    updateMotorControl();
    moveMotor();
}

//=========

void readSwitches() {
    rightLimitswitchState = digitalRead(rightLimitSwitchPin);
    leftLimitswitchState = digitalRead(leftLimitSwitchPin);

    controlButtonState = digitalRead(controlButtonPin);
    buttonPushCounter = 0;
    if (controlButtonState != lastControlButtonState) {
        lastControlButtonState = controlButtonState;
        if (controlButtonState == 1) {
            buttonPushCounter = 1;
            Serial.println("on");
        }
    }
}

//===========

void updateMotorControl() {
    if (rightLimitswitchState == HIGH) {
        motorRun = false;
        motorDirection = 'F';
    }
    if (leftLimitswitchState == HIGH) {
        motorRun = false;
        motorDirection = 'R';
    }
    if (buttonPushCounter == 1) {
        motorRun = true;
    }
}

//===========

void moveMotor() {
    if (motorRun == true) {
        if (motorDirection == 'F') {
            digitalWrite(motorArevPin, LOW);  // write LOW before HIGH
            digitalWrite(motorAfwdPin, HIGH);
        }
        else {
            digitalWrite(motorAfwdPin, LOW);
            digitalWrite(motorArevPin, HIGH);
        }
    }
    else {
        digitalWrite(motorAfwdPin, LOW);
        digitalWrite(motorArevPin, LOW);
    }
}

Hello tb77

Welcome to worldbest Arduino forum.

I´ve made a small code review of your sketch.

To start the motor spin again you can use either the "controlButtonPin" input or a timer function.

Have a nice day and enjoy coding in C++.

1 Like
  • Why is 5v connected to Arduino pin 6 ?

  • The switch resistors are not needed.


    pinMode(controlButtonPin,INPUT);
    pinMode(rightLimitSwitchPin,INPUT);
    pinMode(leftLimitSwitchPin,INPUT);

  • These should be:
    pinMode(controlButtonPin,INPUT_PULLUP); //LOW is closed

Wiring a single pole double pole (limit) switch to an Arduino input.

image

The cap is optional. The cap will help to shunt noise picked up by longer wires to ground and will add some hardware debounce for the switch.

The internal pullups are relatively weak (30K to 50K on mega328 boards) so a lower value external pullup may be necessary if the wires between the switch and processor are long. Start at 10K and go down till performance is satisfactory.

In your picture that shall be a schematic (but is a frowny frizzing) you have connected the resistor between ground and switch.

The picture says the switch is a normally closed switch. This means as soon as the switch is pressed down and the contact opens the input-pin is floating. Which means there is no defined state of the input-pin. The connected wire will catch up some elctromagnetic noise and will make the digitalRead() randomly jump between HIGH and LOW

Are you sure that you have wired it in exact this way?
If you activate the internal pullup resistor the circuitry would make some sense. Still the resistor is not nescessary. Depending on the resistors value it might even become unpossibe to detect a LOW

If your motor has stopped because the limit-switch is pressed
and then you want the motor to drive into the opposite direction

these are two things that you can check in your code with an if-condition that uses the logical AND-operator "&&"

as pseudo-code

if (limitSwitch pressed down && button pressed down) {
  start motor in the direction that moves away from the limit switch
}

best regards Stefan

because it immediately checks the limit button and resets. need to check the limit switch depending on the direction

void updateMotorControl ()
{
    if (motorDirection == 'R' && rightLimitswitchState == LOW) {
        motorDirection = 'F';
        motorRun       = false;
    }
    if (motorDirection == 'F' && leftLimitswitchState == LOW) {
        motorDirection = 'R';
        motorRun       = false;
    }
}
2 Likes

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.