Servo error - Obstacle Avoiding Robot Car

I was try to build a car which can be 1) controlled manually (through remote as well as bluetooth, which are working fine), 2) put to obstacle avoiding mode

This is the code: Arduino Obstacle Avoiding Robot Car - Pastebin.com
This is the schematic: (only data pin connections)

MY TRIES

  1. But when the car is switched to obstacle mode, the servo turns only to one of the side
      distanceLeft = lookLeft();
      delay(300);
      distanceRight = lookRight();
      delay(300);

in this case the servo is only look to its left and then rotate to its mean position (skips the line distanceRight = lookRight(); but makes a very very faint noise when its time to look to the right).

      distanceRight = lookRight();
      delay(300);
      distanceLeft = lookLeft();
      delay(300);

in this case the servo is only look to its right and then rotate to its mean position (skips the line distanceLeft = lookLeft(); but makes a very very faint noise when its time to look to the left).

  1. But when I plug in the arduino nano to the computer and also turn on the battery pack (3S 18650), it seems to work.

  2. I also tried to connect 2 more 18650 batteries in series to the 3S 18650 battery pack, but it still didnt work (only turning to one of the sides).

Pls help solve this issue...

Note: my arduino nano is powered through the 5V out of the L298N to the vin port. all other modules are directly connected to that 5V out of the L298N.

so is better, instead of PasteBin

#include <IRremote.h>
#include <SoftwareSerial.h>
#include <Servo.h>    //Servo motor library. This is standard library
#include <NewPing.h>  //Ultrasonic sensor function library. You must install this library

SoftwareSerial BTSerial(10, 11);
#define irPin A3
IRrecv irrecv(irPin);
decode_results rslts;

#define trig_pin A2  //analog input 1
#define echo_pin A1  //analog input 2

#define maximum_distance 200
boolean goesForward = false;
int distance = 100;

NewPing sonar(trig_pin, echo_pin, maximum_distance);  //sensor function
Servo servo_motor;                                    //our servo name


//PWM 3, 5, 6, 9, 10, 11

char c = ' ';
String irNum = "";
String btNum = "";
String receivedData = "";

String mode = "obstacle";  //NRFL01, HC-05, IR, Eyeblink
// mode = "line";
char data;

// Motor A
int enA = 6;
int in1 = 7;
int in2 = 4;

// Motor B
int enB = 5;
int in3 = 3;
int in4 = 2;

void inits() {
  pinMode(enA, OUTPUT);
  pinMode(enB, OUTPUT);
  pinMode(in1, OUTPUT);
  pinMode(in2, OUTPUT);
  pinMode(in3, OUTPUT);
  pinMode(in4, OUTPUT);
}

void setup() {
  inits();

  //------------------------------------
  //----------manual---------------

  Serial.begin(9600);
  irrecv.enableIRIn();

  BTSerial.begin(38400);
  Serial.println("Enter AT commands:");

  //------------------------------------
  //----------obstacle servo---------------
  servo_motor.attach(13);  //our servo pin

  servo_motor.write(115);
  delay(2000);
  distance = readPing();
  delay(100);
  distance = readPing();
  delay(100);
  distance = readPing();
  delay(100);
  distance = readPing();
  delay(100);
}

void loop() {

  //------------------------------------
  //----------manual---------------

  if (mode == "manual") {


    // if (BTSerial.available()) {
    //   // Serial.write(BTSerial.read()); //writes full words to serial monitor
    //   btNum = BTSerial.read();

    //   if (data == "OK") {
    //     Serial.println("Stopped");
    //     Stop();
    //   }
    //   Serial.println(btNum);
    // }

    // Check if data is available from the HC-05 module
    while (BTSerial.available()) {
      // Read a byte from the software serial port
      char incomingByte = BTSerial.read();
      // Append the byte to the string
      if (isalnum(incomingByte))
        receivedData += incomingByte;
    }

    // If data has been received, print it and clear the string
    if (receivedData.length() > 0) {
      Serial.print("Received data: ");
      Serial.println(receivedData.length());
      // move (receivedData);
      btNum = receivedData;
      // Clear the string after processing
      receivedData = "";
    }

    // Keep reading from Arduino Serial Monitor and send to HC-05
    if (Serial.available()) {
      BTSerial.write(Serial.read());
    }

    if (irrecv.decode()) {
      Serial.println(rslts.value);
      irNum = String(irrecv.decodedIRData.command, HEX);
      Serial.println(irrecv.decodedIRData.command, HEX);
      Serial.println(irNum);
      irrecv.resume();
    }

    // Add a small delay to avoid overwhelming the serial buffer
    delay(50);

    if (irNum == "44" || btNum == "T")
      Forward();
    else if (irNum == "1d" || btNum == "B")
      Back();
    else if (irNum == "1c" || btNum == "L")
      Left();
    else if (irNum == "48" || btNum == "R")
      Right();
    else if (irNum == "5c" || btNum == "OK" || btNum == "O" || btNum == "K")
      Stop();
  }

  //------------------------------------
  //----------obstacle servo---------------

  else if (mode == "obstacle") {
    int distanceRight = 0;
    int distanceLeft = 0;
    delay(50);

    if (distance <= 20) {
      moveStop();
      delay(300);
      moveBackward();
      delay(400);
      moveStop();
      delay(300);
      distanceLeft = lookLeft();
      delay(300);
      distanceRight = lookRight();
      delay(300);

      if (distance >= distanceLeft) {
        turnRight();
        moveStop();
      } else {
        turnLeft();
        moveStop();
      }
    } else {
      moveForward();
    }
    distance = readPing();
  }
  // else if (mode == "line") {
  // }
  // }
}

//------------------------------------
//----------manual---------------

void Forward() {
  digitalWrite(in1, LOW);
  digitalWrite(in2, HIGH);
  analogWrite(enA, 150);

  digitalWrite(in3, HIGH);
  digitalWrite(in4, LOW);
  analogWrite(enB, 150);
}

void Back() {
  digitalWrite(in1, HIGH);
  digitalWrite(in2, LOW);
  analogWrite(enA, 150);

  digitalWrite(in3, LOW);
  digitalWrite(in4, HIGH);
  analogWrite(enB, 150);
}

void Right() {
  digitalWrite(in1, LOW);
  digitalWrite(in2, LOW);
  analogWrite(enA, 150);

  digitalWrite(in3, HIGH);
  digitalWrite(in4, LOW);
  analogWrite(enB, 150);
}

void Left() {
  digitalWrite(in1, LOW);
  digitalWrite(in2, HIGH);
  analogWrite(enA, 150);

  digitalWrite(in3, LOW);
  digitalWrite(in4, LOW);
  analogWrite(enB, 150);
}

void Stop() {
  analogWrite(enA, 0);
  analogWrite(enB, 0);

  // digitalWrite(in1, LOW);
  // digitalWrite(in2, LOW);
  // digitalWrite(in3, LOW);
  // digitalWrite(in4, LOW);
}

//------------------------------------
//----------obstacle servo---------------

int lookRight() {
  servo_motor.write(50);
  delay(500);
  int distance = readPing();
  delay(100);
  servo_motor.write(115);
  return distance;
  delay(100);
}

int lookLeft() {
  servo_motor.write(180);
  delay(500);
  int distance = readPing();
  delay(100);
  servo_motor.write(115);
  return distance;
  delay(100);
}

int readPing() {
  delay(70);
  int cm = sonar.ping_cm();
  if (cm == 0) {
    cm = 250;
  }
  return cm;
}

void moveStop() {
  digitalWrite(in3, LOW);
  digitalWrite(in1, LOW);
  digitalWrite(in4, LOW);
  digitalWrite(in2, LOW);
}

void moveForward() {

  if (!goesForward) {
    goesForward = true;

    digitalWrite(in1, LOW);
    digitalWrite(in2, HIGH);
    analogWrite(enA, 150);

    digitalWrite(in3, HIGH);
    digitalWrite(in4, LOW);
    analogWrite(enB, 150);
  }
}

void moveBackward() {
  goesForward = false;

  digitalWrite(in1, HIGH);
  digitalWrite(in2, LOW);
  analogWrite(enA, 150);

  digitalWrite(in3, LOW);
  digitalWrite(in4, HIGH);
  analogWrite(enB, 150);
}

void turnRight() {

  //turning right little
  digitalWrite(in1, LOW);
  digitalWrite(in2, LOW);
  analogWrite(enA, 150);

  digitalWrite(in3, HIGH);
  digitalWrite(in4, LOW);
  analogWrite(enB, 150);

  delay(500);

  //moving backward little
  digitalWrite(in1, HIGH);
  digitalWrite(in2, LOW);
  analogWrite(enA, 150);

  digitalWrite(in3, LOW);
  digitalWrite(in4, HIGH);
  analogWrite(enB, 150);
}

void turnLeft() {

  //turning left little
  digitalWrite(in1, LOW);
  digitalWrite(in2, HIGH);
  analogWrite(enA, 150);

  digitalWrite(in3, LOW);
  digitalWrite(in4, LOW);
  analogWrite(enB, 150);

  delay(500);

  //moving backward little
  digitalWrite(in1, HIGH);
  digitalWrite(in2, LOW);
  analogWrite(enA, 150);

  digitalWrite(in3, LOW);
  digitalWrite(in4, HIGH);
  analogWrite(enB, 150);
}

ChatGPT generated ?

int lookLeft() {
  servo_motor.write(180);
  delay(500);
  int distance = readPing();
  delay(100);
  servo_motor.write(115);
  return distance;
  delay(100); <<--------------- this is pointless, bc of earlier return
}

Show a complete wiring diagram and program.

nah. The code was publicly available. I was just modifying according to my project. The comments are mine but they are of no use (I was trying to understand what the section of code meant).

get rid of any Strings variable and comparisons

as said- it seems to work.......when I plug in the arduino nano to the computer and also turn on the battery pack (3S 18650)? why?

I would have loved to share the complete diagram if it hadn't been clumsy due to the VCC and GND lines (I am new to this field). However, I have included an almost complete schematic in the question itself.

The complete code is available via a link to make the question clearer.

Hand-drawn is good.

Click the < CODE > button in the message box then paste your formatted code where you see ```type or paste code here```

also if I connect the second battery pack (18650 2S), its positive terminal to the vin of Arduino and and negative terminal to GND of arduino....it margically works..

The Schematic:

Note: in the very very rough schematic, brown -> negative, red -> positive and the battery pack is 3S not 2S.

The Code

#include <IRremote.h>
#include <SoftwareSerial.h>
#include <Servo.h>    //Servo motor library. This is standard library
#include <NewPing.h>  //Ultrasonic sensor function library. You must install this library

SoftwareSerial BTSerial(10, 11);
#define irPin A3
IRrecv irrecv(irPin);
decode_results rslts;

#define trig_pin A2  //analog input 1
#define echo_pin A1  //analog input 2

#define maximum_distance 200
boolean goesForward = false;
int distance = 100;

NewPing sonar(trig_pin, echo_pin, maximum_distance);  //sensor function
Servo servo_motor;                                    //our servo name


//PWM 3, 5, 6, 9, 10, 11

char c = ' ';
String irNum = "";
String btNum = "";
String receivedData = "";

String mode = "obstacle";  //NRFL01, HC-05, IR, Eyeblink
// mode = "line";
char data;

// Motor A
int enA = 6;
int in1 = 7;
int in2 = 4;

// Motor B
int enB = 5;
int in3 = 3;
int in4 = 2;

void inits() {
  pinMode(enA, OUTPUT);
  pinMode(enB, OUTPUT);
  pinMode(in1, OUTPUT);
  pinMode(in2, OUTPUT);
  pinMode(in3, OUTPUT);
  pinMode(in4, OUTPUT);
}

void setup() {
  inits();

  //------------------------------------
  //----------manual---------------

  Serial.begin(9600);
  irrecv.enableIRIn();

  BTSerial.begin(38400);
  Serial.println("Enter AT commands:");

  //------------------------------------
  //----------obstacle servo---------------
  servo_motor.attach(13);  //our servo pin

  servo_motor.write(115);
  delay(2000);
  distance = readPing();
  delay(100);
  distance = readPing();
  delay(100);
  distance = readPing();
  delay(100);
  distance = readPing();
  delay(100);
}

void loop() {

  //------------------------------------
  //----------manual---------------

  if (mode == "manual") {


    // if (BTSerial.available()) {
    //   // Serial.write(BTSerial.read()); //writes full words to serial monitor
    //   btNum = BTSerial.read();

    //   if (data == "OK") {
    //     Serial.println("Stopped");
    //     Stop();
    //   }
    //   Serial.println(btNum);
    // }

    // Check if data is available from the HC-05 module
    while (BTSerial.available()) {
      // Read a byte from the software serial port
      char incomingByte = BTSerial.read();
      // Append the byte to the string
      if (isalnum(incomingByte))
        receivedData += incomingByte;
    }

    // If data has been received, print it and clear the string
    if (receivedData.length() > 0) {
      Serial.print("Received data: ");
      Serial.println(receivedData.length());
      // move (receivedData);
      btNum = receivedData;
      // Clear the string after processing
      receivedData = "";
    }

    // Keep reading from Arduino Serial Monitor and send to HC-05
    if (Serial.available()) {
      BTSerial.write(Serial.read());
    }

    if (irrecv.decode()) {
      Serial.println(rslts.value);
      irNum = String(irrecv.decodedIRData.command, HEX);
      Serial.println(irrecv.decodedIRData.command, HEX);
      Serial.println(irNum);
      irrecv.resume();
    }

    // Add a small delay to avoid overwhelming the serial buffer
    delay(50);

    if (irNum == "44" || btNum == "T")
      Forward();
    else if (irNum == "1d" || btNum == "B")
      Back();
    else if (irNum == "1c" || btNum == "L")
      Left();
    else if (irNum == "48" || btNum == "R")
      Right();
    else if (irNum == "5c" || btNum == "OK" || btNum == "O" || btNum == "K")
      Stop();
  }

  //------------------------------------
  //----------obstacle servo---------------

  else if (mode == "obstacle") {
    int distanceRight = 0;
    int distanceLeft = 0;
    delay(50);

    if (distance <= 20) {
      moveStop();
      delay(300);
      moveBackward();
      delay(400);
      moveStop();
      delay(300);
      distanceLeft = lookLeft();
      delay(300);
      distanceRight = lookRight();
      delay(300);

      if (distance >= distanceLeft) {
        turnRight();
        moveStop();
      } else {
        turnLeft();
        moveStop();
      }
    } else {
      moveForward();
    }
    distance = readPing();
  }
  // else if (mode == "line") {
  // }
  // }
}

//------------------------------------
//----------manual---------------

void Forward() {
  digitalWrite(in1, LOW);
  digitalWrite(in2, HIGH);
  analogWrite(enA, 150);

  digitalWrite(in3, HIGH);
  digitalWrite(in4, LOW);
  analogWrite(enB, 150);
}

void Back() {
  digitalWrite(in1, HIGH);
  digitalWrite(in2, LOW);
  analogWrite(enA, 150);

  digitalWrite(in3, LOW);
  digitalWrite(in4, HIGH);
  analogWrite(enB, 150);
}

void Right() {
  digitalWrite(in1, LOW);
  digitalWrite(in2, LOW);
  analogWrite(enA, 150);

  digitalWrite(in3, HIGH);
  digitalWrite(in4, LOW);
  analogWrite(enB, 150);
}

void Left() {
  digitalWrite(in1, LOW);
  digitalWrite(in2, HIGH);
  analogWrite(enA, 150);

  digitalWrite(in3, LOW);
  digitalWrite(in4, LOW);
  analogWrite(enB, 150);
}

void Stop() {
  analogWrite(enA, 0);
  analogWrite(enB, 0);

  // digitalWrite(in1, LOW);
  // digitalWrite(in2, LOW);
  // digitalWrite(in3, LOW);
  // digitalWrite(in4, LOW);
}

//------------------------------------
//----------obstacle servo---------------

int lookRight() {
  servo_motor.write(50);
  delay(500);
  int distance = readPing();
  delay(100);
  servo_motor.write(115);
  return distance;
  delay(100);
}

int lookLeft() {
  servo_motor.write(180);
  delay(500);
  int distance = readPing();
  delay(100);
  servo_motor.write(115);
  return distance;
  delay(100);
}

int readPing() {
  delay(70);
  int cm = sonar.ping_cm();
  if (cm == 0) {
    cm = 250;
  }
  return cm;
}

void moveStop() {
  digitalWrite(in3, LOW);
  digitalWrite(in1, LOW);
  digitalWrite(in4, LOW);
  digitalWrite(in2, LOW);
}

void moveForward() {

  if (!goesForward) {
    goesForward = true;

    digitalWrite(in1, LOW);
    digitalWrite(in2, HIGH);
    analogWrite(enA, 150);

    digitalWrite(in3, HIGH);
    digitalWrite(in4, LOW);
    analogWrite(enB, 150);
  }
}

void moveBackward() {
  goesForward = false;

  digitalWrite(in1, HIGH);
  digitalWrite(in2, LOW);
  analogWrite(enA, 150);

  digitalWrite(in3, LOW);
  digitalWrite(in4, HIGH);
  analogWrite(enB, 150);
}

void turnRight() {

  //turning right little
  digitalWrite(in1, LOW);
  digitalWrite(in2, LOW);
  analogWrite(enA, 150);

  digitalWrite(in3, HIGH);
  digitalWrite(in4, LOW);
  analogWrite(enB, 150);

  delay(500);

  //moving backward little
  digitalWrite(in1, HIGH);
  digitalWrite(in2, LOW);
  analogWrite(enA, 150);

  digitalWrite(in3, LOW);
  digitalWrite(in4, HIGH);
  analogWrite(enB, 150);
}

void turnLeft() {

  //turning left little
  digitalWrite(in1, LOW);
  digitalWrite(in2, HIGH);
  analogWrite(enA, 150);

  digitalWrite(in3, LOW);
  digitalWrite(in4, LOW);
  analogWrite(enB, 150);

  delay(500);

  //moving backward little
  digitalWrite(in1, HIGH);
  digitalWrite(in2, LOW);
  analogWrite(enA, 150);

  digitalWrite(in3, LOW);
  digitalWrite(in4, HIGH);
  analogWrite(enB, 150);
}

Either (1) use over 7vdc on Nano VIN or (2) 5vdc on Nano 5V pin. You are using 5vdc on VIN.

Hand drawn wiring diagrams are good... BUT...

If you need words to explain... you need to re-draw your drawing.

for your soln (1):

will this wiring work? I am getting approx 10V from that battery pack. (I am afraid of frying / damaging anything).

for your soln (2):

I have always used Nano 5V pin as 5V OUT. Can it be used for 5V IN...as u suggested? will Nano be safe?

(1) Now I am using the second battery pack (2S 18650) to power all the modules. I have put lm2596 dc-dc buck converter to convert 8V to 5V.

(2) I am using the first battery pack (3S 18650) to power the motor driver, motors and the Nano through that VIN port (5V in Vin.. seems to work?).

Everything now, is working fine, all problems gone... same code.

Is this approach, good or okay? or is there anything better that can be done..?

There seems to be a very little leak current from RX pin of HC-05 to D10 which is being indicated a faint glow on PWR / ON led of Nano, when I switch on the second battery pack. (Dont know why...)

I can not tell by your drawing. ONLY one power supply per Arduino. Do not use VIN and 5vdc at the same time.

This is the updated schematic (in accordance with my previous reply):

Again, Is this approach, good or okay? or is there anything better that can be done..?

Do not use 5vdc on VIN. Only 7vdc - 12vdc on VIN.

Yup, u are right.... I now learned the thing after a bit of research..

Anything else to keep in mind (in general) to make these kinds of project a success?

You probably read "7vdc - 12vdc" before, but it did not register as "must be"... and "Anything else" you probably have seen, but same result. You will find these "aha" moments all the time (you saw it, forgot it, saw it again, remember it). Know that new information is the easiest not to "see" because we only "see" what we know. Now you know, and every piece of knowledge you retain will allow you to use for yourself and others who did not "see." Never stop learning. (and keep asking questions)