1

I'm using this motor driver with 2 of these motors to control a skid steer robot. To get the robot to coast to a stop, I use this code:

  analogWrite(MotLPWM, 0);  //coast to stop
  analogWrite(MotRPWM, 0);
  digitalWrite(MotL1, HIGH);
  digitalWrite(MotL2, HIGH);
  digitalWrite(MotR1, HIGH);
  digitalWrite(MotR2, HIGH);

to get the robot to hard stop, I use this code:

analogWrite(M1PWM, 0);
analogWrite(M2PWM, 0);
digitalWrite(M1INA, LOW);
digitalWrite(M2INA, LOW);
digitalWrite(M1INB, LOW);
digitalWrite(M2INB, LOW);

I would like for the robot to stop and/or brake with something in between so it isn't so hard on the gears. The following snippet of the whole sketch is supposed to let the motors coast for 1/4 second then hard stop. Unfortunately, it doesn't coast and goes straight to the hard stop. Any ideas how to fix it?

    void allStop () {
//COAST
  analogWrite(MotLPWM, 0);  //coast for 1/4 second before fast stop
  analogWrite(MotRPWM, 0);
  digitalWrite(MotL1, HIGH);
  digitalWrite(MotL2, HIGH);
  digitalWrite(MotR1, HIGH);
  digitalWrite(MotR2, HIGH);
//HARD STOP
  if ((millis() - previousCoastMillis) > 250) {
  analogWrite(MotLPWM, 0);  
  analogWrite(MotRPWM, 0);
  digitalWrite(MotL1, LOW);
  digitalWrite(MotL2, LOW);
  digitalWrite(MotR1, LOW);
  digitalWrite(MotR2, LOW);
    previousCoastMillis = millis();
  }
}

The full sketch is here:

int ledB = 5;

int MotL1 = 8;
int MotL2 = 7;
int MotLPWM = 9;

int MotR1 = 11;
int MotR2 = 12;
int MotRPWM = 10;

unsigned long previousCoastMillis = 0;
const int coastInterval = 500;

void setup() {
  pinMode(MotL1, OUTPUT);
  pinMode(MotL2, OUTPUT);
  pinMode(MotLPWM, OUTPUT);
  pinMode(MotR1, OUTPUT);
  pinMode(MotR2, OUTPUT);
  pinMode(MotRPWM, OUTPUT);
  pinMode(ledB, OUTPUT);
}

void loop() {
  go();
  allStop();
}


void allStop () {
//COAST
  analogWrite(MotLPWM, 0);  //coast for 1/4 second before fast stop
  analogWrite(MotRPWM, 0);
  digitalWrite(MotL1, HIGH);
  digitalWrite(MotL2, HIGH);
  digitalWrite(MotR1, HIGH);
  digitalWrite(MotR2, HIGH);
//HARD STOP
  if ((millis() - previousCoastMillis) > 250) {
  analogWrite(MotLPWM, 0);  
  analogWrite(MotRPWM, 0);
  digitalWrite(MotL1, LOW);
  digitalWrite(MotL2, LOW);
  digitalWrite(MotR1, LOW);
  digitalWrite(MotR2, LOW);
    previousCoastMillis = millis();
  }
}

void go () {
  analogWrite(MotLPWM, 150);
  analogWrite(MotRPWM, 150);
  digitalWrite(MotL1, HIGH);
  digitalWrite(MotL2, LOW);
  digitalWrite(MotR1, HIGH);
  digitalWrite(MotR2, LOW);
  digitalWrite(ledB, HIGH);
  delay(1000);

}
1

You are trying to use a mix of delay and millis

Instead you will want a proper state machine:

void loop(){

    switch (state){
    case GOING: go(); 
       state = WAIT_FOR_COAST; 
       transition = millis();break;

    case WAIT_FOR_COAST: if(millis()-transition > 1000){
            allStop(false);
            state = WAIT_FOR_STOP; transition = millis();
        }
        break;
    case WAIT_FOR_STOP: if(millis()-transition > 250){
            allStop(true);
            state = WAIT_FOR_GO; transition = millis();
        }
        break;
    case WAIT_FOR_GO: if(millis()-transition > 1000){
            allStop(true);
            state = WAIT_FOR_GO; transition = millis();
        }
        break;

    }

}

Remove the delay in go and use a simple if-else in the allStop where parameter == true means hard stop and false means coast.

Another option is to use a extra mosfet to put a resistor across the motor instead of shorting it out (which is what the hard stop will do). That will reduce the breaking torque but defeats the isolation of the board.

  • I forgot to comment out the delay in the go function when I was transferring the code to this forum. Clerical error. – Daniel Shields Nov 18 '17 at 13:11
0

This works. When allStop gets called, previousCoastMillis is reset. Then the motor coasts while it's stuck in the while loop for 150ms. Then it hard stops.

void allStop () {
  previousCoastMillis = millis();
  while (millis() - previousCoastMillis < 150) {
    analogWrite(enA, 0);
    analogWrite(enB, 0);
    digitalWrite(in1, HIGH);
    digitalWrite(in2, HIGH);
    digitalWrite(in3, HIGH);
    digitalWrite(in4, HIGH);
  }

  analogWrite(enA, 0);
  analogWrite(enB, 0);
  digitalWrite(in1, LOW);
  digitalWrite(in2, LOW);
  digitalWrite(in3, LOW);
  digitalWrite(in4, LOW);
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.