My code only runs once ? It seems to get stuck in a function, not allowing my car to move after the first click

Problem: I am new to coding and my code may look messy but please help me out if you can.
When I press any direction button to move the car, it only runs once. For example - I turn the car on press forward once, it'll move forward once. I try pressing the forward button again but it does not move. I have checked on my serial monitor it looks like forward is printed correctly as many times as I press it. So the problem could like with my "car. forward();" function.
Although when I reset the car and press forward, it'll move forward once again, then nothing until I press reset again.
What is wrong with my function can anyone let me know how I can fix this?

Code starts from here:

#include <IRremote.h>
#include "move.h"

Move car(true);
int IRpin = 9;
//IRrecv IR(IRpin);
//decode_results cmd;

void setup() {
  Serial.begin(9600);
  //IR.enableIRIn();
  IrReceiver.begin(IRpin, ENABLE_LED_FEEDBACK);

}

void loop() {
  float d = 0.3;
  float s = 0.42;

  while (IrReceiver.decode() == 0) {}

  if (IrReceiver.decodedIRData.command == 0x46) {
    Serial.println("forward");
    car.forward(d, s);
  }
  if (IrReceiver.decodedIRData.command == 0x15) {
    Serial.println("backward");
    car.backward(0.3, 0.42);
  }
  if (IrReceiver.decodedIRData.command == 0x43) {
    Serial.println("right");
    car.right(90);
  }
  if (IrReceiver.decodedIRData.command == 0x44) {
    Serial.println("left");
    car.left(90);
  }
  IrReceiver.resume();


}

//d (distance) = Meters 0.3m = 1 foot
//speed (AW)= 100-255
//v (Velocity) = 0.42 - 0.75 - 00.85 - 1.0875 m/s
//Serial.println(IrReceiver.decodedIRData.command, HEX);


**Move.cpp file**

#include "move.h"

Move::Move(bool a) {
  pinMode(PWMA, OUTPUT);
  pinMode(PWMB, OUTPUT);
  pinMode(AIN_1, OUTPUT);
  pinMode(BIN_1, OUTPUT);
  pinMode(STBY, OUTPUT);
  digitalWrite(STBY, HIGH); // Standby mode off

}

// FORWARD, BACKWARD AND STOP

void Move::forward(float d, float v) {
  float t, AW;
  AW = (v + 0.009) / 0.0043;
  analogWrite(PWMA, AW);
  analogWrite(PWMB, AW);
  digitalWrite(AIN_1, HIGH);
  digitalWrite(BIN_1, HIGH);
  t = d / v * 1000;
  delay(t);
  stopCar();
}

void Move::backward(float d, float v) {
  float t, AW;
  AW = (v + 0.009) / 0.0043;
  analogWrite(PWMA, AW);
  analogWrite(PWMB, AW);
  digitalWrite(AIN_1, LOW);
  digitalWrite(BIN_1, LOW);
  t = d / v * 1000;
  delay(t);
  stopCar();
}


void Move::stopCar() {
  analogWrite(PWMA, 0);
  analogWrite(PWMB, 0);
  digitalWrite(STBY, LOW);
}

// LEFT AND RIGHT

void Move::left(int deg) {
  float t;
  int AW = 100;
  analogWrite(PWMA, AW);
  analogWrite(PWMB, AW);
  digitalWrite(AIN_1, LOW);
  digitalWrite(BIN_1, HIGH);
  t = ((0.3333 + deg) / 136.86) * 1000;
  delay(t);
  stopCar();
}

void Move::right(int deg) {
  float t;
  int AW = 100;
  analogWrite(PWMA, AW);
  analogWrite(PWMB, AW);
  digitalWrite(AIN_1, HIGH);
  digitalWrite(BIN_1, LOW);
  t = ((0.3333 + deg) / 136.86) * 1000;
  delay(t);
  stopCar();
}

**Move.h file**

#ifndef movel  
#define movel 

#include "Arduino.h" 


class Move
{
  public:
    Move(bool a); 
    //Methods
    void calR(float degreeRot);
    void forward(float d, float v);
    void backward(float d, float v);
    void left(int deg);
    void right(int deg);
    void stopCar();

  private:
    int PWMA = 5; //PIN Motor A = Speed - Right Side
    int PWMB = 6; //PIN Motor B = Speed - Left Side
    int BIN_1 = 7; //PIN Motor B = Spin
    int AIN_1 = 8; //PIN Motor A = Spin
    int STBY = 3; //Motor Standby
    int deg; // Rotation 
};


#endif

Please follow the advice given in the link below when posting code, in particular the section entitled 'Posting code and common code problems'

Use code tags (the </> icon above the compose window) to make it easier to read and copy for examination

1 Like

stopCar does

  digitalWrite(STBY, LOW);

What is the STBY signal for?

a7

STBY is for Standby. STBY low puts the car on standby. Whereas STBY high puts it on.

Once you have set the pin LOW to put the car on standby, where do you ever set it HIGH to let it run again? Looks like you should add digitalWrite(STBY, HIGH); to the beginning of forward(), backward(), left(), and right().

1 Like

I see what you mean. But as my constructor is set to TRUE shouldn't the STBY switch to HIGH?

Thank you very much you were right! It was getting stuck on standby.
I thought it would turn on again as my constructor was switched on and STBY was on HIGH within the constructor.
I added a STBY, HIGH line to forward and it works now.
Thanks again!

void loop() {
  float d = 0.3;
  float s = 0.42;

  while (IrReceiver.decode() == 0) {}

  if (IrReceiver.decodedIRData.command == 0x46) {
    Serial.println("forward");
    car.forward(d, s);
  }
  if (IrReceiver.decodedIRData.command == 0x15) {
    Serial.println("backward");
    car.backward(0.3, 0.42);
  }
  if (IrReceiver.decodedIRData.command == 0x43) {
    Serial.println("right");
    car.right(90);
  }
  if (IrReceiver.decodedIRData.command == 0x44) {
    Serial.println("left");
    car.left(90);
  }
  IrReceiver.resume();
}

So this code reads from the IR, hangs in a loop if nothing is received and then does the moves based on the command code?

If so it might be better to use a switch case here...

Something along the lines of:

void loop() {
  float d = 0.3;
  float s = 0.42;

  if (IrReceiver.decode() != 0) {
    switch (IrReceiver.decodedIRData.command) {
      case 0x46:
        Serial.println("forward");
        car.forward(d, s);
        break;
      case 0x15:
        Serial.println("backward");
        car.backward(0.3, 0.42);
        break;
      case 0x43:
        Serial.println("right");
        car.right(90);
        break;
      case 0x44:
        Serial.println("left");
        car.left(90);
        break;
      
      default:
        break;
    }
    IrReceiver.resume();
  }
}