How can I reverse the direction of the motor's movement?

Hello friends, in the following code, I have connected a motor driver and an encoder, and a motor to Arduino, which starts moving the motor by rotating the encoder and stops when it reaches 600.

In this code, if the encoder rotates to the right, which means it has a positive pulse, the motor rotates to the right, and if it has a negative pulse, it rotates to the left.
Now, I want that when I rotate the encoder to the right and after reaching 600 and stopping the motor, as soon as I rotate the encoder in the opposite direction (to the left), the motor also rotates in the opposite direction (to the left), without having a negative pulse to the left.
Best Regards
Neda


#include <Encoder.h>
#define RPWM 5
#define LPWM 6
#define REN 8
#define LEN 9

#define MAX_SPEED 255 

Encoder myEncoder(2, 4); 

int out1;

void setup() {
  Serial.begin(9600);
  pinMode(RPWM, OUTPUT);
  pinMode(LPWM, OUTPUT);
  pinMode(LEN, OUTPUT);
  pinMode(REN, OUTPUT);
  digitalWrite(REN, HIGH);
  digitalWrite(LEN, HIGH);
}

void loop() {
  long position = myEncoder.read(); 
  Serial.println(position); 
  
  
  if (position >= 600) {
    analogWrite(LPWM, 0);
    analogWrite(RPWM, 0);
    return; 
  }

  int speed = min(MAX_SPEED, abs(position));

  if (position > 0) { 
    analogWrite(RPWM, MAX_SPEED);
    analogWrite(LPWM, 0);
  } else if (position < 0) { 
    analogWrite(LPWM, MAX_SPEED);
    analogWrite(RPWM, 0);
  } else { 
    analogWrite(LPWM, 0);
    analogWrite(RPWM, 0);
  }
}

Is this code works?

yes it works correctly

Then it´s time for you to tell us which motor driver you do have and show a schematic of how are all the things connected.

#define RPWM 5
#define LPWM 6
#define REN 8
#define LEN 9

If by REN and LEN you mean Right Enable and Left Enable, this suggests that you may be confusing the pins of your driver. On a L293N, for example, you need 3 pins to control 1 motor. 2 inputs (common digital pins) and 1 enable (PWM).

Reverse direction is just changing InputX HIGH / inputY LOW to InputX LOW / inputY HIGH

this is my motor driver

Looks like a BTS7960. In this case, pins assignment in the code seems to be ok. You didn´t provide the schematics though.

Test this version:

#include <Encoder.h>
#define RPWM 5
#define LPWM 6
#define REN 8
#define LEN 9

#define MAX_SPEED 255 

Encoder myEncoder(2, 4); 

int out1;

void setup() {
  Serial.begin(9600);
  pinMode(RPWM, OUTPUT);
  pinMode(LPWM, OUTPUT);
  pinMode(LEN, OUTPUT);
  pinMode(REN, OUTPUT);
  digitalWrite(REN, HIGH);
  digitalWrite(LEN, HIGH);
}

void loop() {
  long position = myEncoder.read(); 
  Serial.println(position); 
  
  
  if (position >= 600) {
    analogWrite(LPWM, 0);
    analogWrite(RPWM, 0);
    position = 0;
    return; 
  }

  int speed = min(MAX_SPEED, abs(position));

  if (position > 0) { 
    analogWrite(RPWM, MAX_SPEED);
    analogWrite(LPWM, 0);
  } else if (position < 0) { 
    analogWrite(LPWM, MAX_SPEED);
    analogWrite(RPWM, 0);
  } else { 
    analogWrite(LPWM, 0);
    analogWrite(RPWM, 0);
  }
}

I tried this code and it worked just like my own code.

It means that when I rotate the encoder, the motor stops at 600 and when I rotate the encoder in the opposite direction, the motor rotates in the same direction as before until it reaches zero and its value becomes negative, and then it moves in the opposite direction.

  if (position >= 600) {
    analogWrite(LPWM, 0);
    analogWrite(RPWM, 0);
    position = 0;  // <--     **I added this line to your code**
    return; 
  }

When "position" comes to 600, it should be set to zero again. So, the motor should turn off and if you move the encoder CCW "position" should become <0. What are the results of:

 Serial.println(position); 

when "position" reaches 600?

I exactly wrote your codes and it shows 600 in Serial Monitor I took picture:

1

Ok, sorry. It´s not enough to set position to zero. It´s necessary to reset the encoder position. So, instead of this line:

position = 0;

put this other one:

myEncoder.write(0);

Hope it helps!

consider the following which uses buttons to simulate changing the position of the encode

// check multiple buttons and toggle LEDs

enum { Off = HIGH, On = LOW };

byte pinsLed [] = { 10, 11, 12 };
byte pinsBut [] = { A1, A2, A3 };
#define N_BUT   sizeof(pinsBut)

byte butState [N_BUT];

enum { P0 = 0, P1 = 6 };
int posZero = P0;
int position;

// -----------------------------------------------------------------------------
int
chkButtons ()
{
    for (unsigned n = 0; n < sizeof(pinsBut); n++)  {
        byte but = digitalRead (pinsBut [n]);

        if (butState [n] != but)  {
            butState [n] = but;

            delay (10);     // debounce

            if (On == but)
                return n;
        }
    }
    return -1;
}

// -----------------------------------------------------------------------------
void
loop ()
{
    switch (chkButtons ())  {
    case 2:
        break;

    case 1:
        position--;
        Serial.println (position);
        if (P0 >= position)  {
            Serial.println (" stop - reset");
            posZero = P0;
        }
        else if (posZero > position)
            Serial.println (" reverse");
        break;

    case 0:
        position++;
        Serial.println (position);
        if (P1 <= position)  {
            Serial.println (" stop");
            posZero = P1;
        }
        else if (posZero < position)
            Serial.println (" forward");
        break;
    }
}

// -----------------------------------------------------------------------------
void
setup ()
{
    Serial.begin (9600);

    for (unsigned n = 0; n < sizeof(pinsBut); n++)  {
        pinMode (pinsBut [n], INPUT_PULLUP);
        butState [n] = digitalRead (pinsBut [n]);
    }

    for (unsigned n = 0; n < sizeof(pinsLed); n++)  {
        digitalWrite (pinsLed [n], Off);
        pinMode      (pinsLed [n], OUTPUT);
    }
}

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