Car With 2 Modes Line Following and Bluetooth Control

Hello..... I recently coded this line following car and a bluetooth controlled car. I've been trying to combine both the codes to make the car change the modes via a button in the app. Here's how far I've gotten

#include <SoftwareSerial.h>

SoftwareSerial BTSerial(10, 11);

char BT = BTSerial.read();

int IRL = 16;
int IRR = 17;
int M1H = 2;
int M1L = 3;
int M2H = 4;
int M2L = 5;

void setup() {
  Serial.begin(9600);
  pinMode(M1H, OUTPUT);
  pinMode(M1L, OUTPUT);
  pinMode(M2H, OUTPUT);
  pinMode(M2L, OUTPUT);
  pinMode(IRL, INPUT);
  pinMode(IRR, INPUT);
}

void Forward() {
  digitalWrite(M1H, HIGH);
  digitalWrite(M1L, LOW);
  digitalWrite(M2H, HIGH);
  digitalWrite(M2L, LOW);
}

void Backward() {
  digitalWrite(M1H, LOW);
  digitalWrite(M1L, HIGH);
  digitalWrite(M2H, LOW);
  digitalWrite(M2L, HIGH);
}

void Stop() {
  digitalWrite(M1H, LOW);
  digitalWrite(M1L, LOW);
  digitalWrite(M2H, LOW);
  digitalWrite(M2L, LOW);
}

void Left() {
  digitalWrite(M1H, LOW);
  digitalWrite(M1L, LOW);
  digitalWrite(M2H, HIGH);
  digitalWrite(M2L, LOW);
}

void Right() {
  digitalWrite(M1H, HIGH);
  digitalWrite(M1L, LOW);
  digitalWrite(M2H, LOW);
  digitalWrite(M2L, LOW);
}

void Line() {
  if ((digitalRead(IRR) == HIGH) && (digitalRead(IRL) == HIGH)) {
    digitalWrite(M1H, LOW);
    digitalWrite(M1L, HIGH);
    digitalWrite(M2H, LOW);
    digitalWrite(M2L, HIGH);
  }
  if ((digitalRead(IRR) == LOW) && (digitalRead(IRL) == HIGH)) {
    digitalWrite(M1H, LOW);
    digitalWrite(M1L, LOW);
    digitalWrite(M2H, LOW);
    digitalWrite(M2L, HIGH);
  }
  if ((digitalRead(IRR) == HIGH) && (digitalRead(IRL) == LOW)) {
    digitalWrite(M1H, LOW);
    digitalWrite(M1L, HIGH);
    digitalWrite(M2H, LOW);
    digitalWrite(M2L, LOW);
  }
  if ((digitalRead(IRR) == LOW) && (digitalRead(IRL) == LOW)) {
    digitalWrite(M1H, LOW);
    digitalWrite(M1L, LOW);
    digitalWrite(M2H, LOW);
    digitalWrite(M2L, LOW);
  }
}

void Bluetooth(){

}

void loop() {
  if (Serial.available() > 0) {
    char BT = BTSerial.read();
  }

  if (BT == 'U') {
    Forward();
  } else if (BT == 'D') {
    Backward();
  } else if (BT == 'S') {
    Stop();
  } else if (BT == 'L') {
    Left();
  } else if (BT == 'R') {
    Right();
  } else if (BT == 'X') {
    Line();
  } else if (BT == 'x') {
    Bluetooth();
  }
}

add a bool variable that says if you are in manual or automatic mode

bool automaticMode = false; // start in manual mode

when you receive the right command you flip the bool to alternate between manual and automated

something like this (assuming everything else works) - where X or x will alternate between manual and automated

bool automaticMode = false; // start in manual mode

... the rest of your code

void loop() {
  switch (BTSerial.read()) { // returns -1 if nothing to read
    case 'U': if (!automaticMode) Forward(); break;
    case 'D': if (!automaticMode) Backward(); break;
    case 'S': Stop(); break; // keep this always active regardless of the mode, just in case
    case 'L': if (!automaticMode) Left(); break;
    case 'R': if (!automaticMode) Right(); break;
    case 'X':
    case 'x': automaticMode = !automaticMode;  break;
    default: break; // ignore any other command or -1
  }
  
  if (automaticMode) Line(); // drive in automatic mode independently from BT input
}

Rather than re-writing motor directions...

Try re-using your functions... for example

  if ((digitalRead(IRR) == HIGH) && (digitalRead(IRL) == HIGH))
    Backward();

   if ((digitalRead(IRR) == LOW) && (digitalRead(IRL) == LOW))
    Stop();

I also noticed you have two methods of turning right and two methods of turning left.

Turning right #1 (left wheel forward):

  digitalWrite(M1H, HIGH);
  digitalWrite(M1L, LOW);
  digitalWrite(M2H, LOW);
  digitalWrite(M2L, LOW);

Turning right #2 (right wheel backward):

    digitalWrite(M1H, LOW);
    digitalWrite(M1L, LOW);
    digitalWrite(M2H, LOW);
    digitalWrite(M2L, HIGH);

Turning left #1 (left wheel forward):

  digitalWrite(M1H, LOW);
  digitalWrite(M1L, LOW);
  digitalWrite(M2H, HIGH);
  digitalWrite(M2L, LOW);

Turning left #2 (left wheel backwards):

    digitalWrite(M1H, LOW);
    digitalWrite(M1L, HIGH);
    digitalWrite(M2H, LOW);
    digitalWrite(M2L, LOW);

The two methods of turning (left or right) have their own advantages... but you should put them in their own functions, then use function calls, rather than re-writing the motor movements. Using function calls lets you avoid writing mistakes as well as editing one function effects all calls to the function, rather than needing to edit every occurrence of a motor movement.

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