Bluetooth transmission getting stuck

Hi. I have a project in which I have to command two steppers with ULN2003 using Bluetooth module HC-05 and the app Serial bluetooth. It has a chance to freeze each time I execute a command that is unknown or that cannot be executed. It does not freeze when I let any of the drivers be active after an execution of a command.
The only current way to get it to work again is to have a print spam messages in the monitor and will unfreeze it.

#include <Stepper.h>
#include <AccelStepper.h>
#include <MultiStepper.h>
#include <LiquidCrystal_I2C.h>
#include <Wire.h>
#include <EEPROM.h>

// Definirea adreselor EEPROM pentru pozițiile motoarelor
#define MOTOR1_EEPROM_ADDRESS 0
#define MOTOR2_EEPROM_ADDRESS 10

// Pini pentru motorul 1
#define motor1Pin1 7
#define motor1Pin2 6
#define motor1Pin3 5
#define motor1Pin4 4

// Pini pentru motorul 2
#define motor2Pin1 11
#define motor2Pin2 10
#define motor2Pin3 9
#define motor2Pin4 8

#define bluetoothTx 1
#define bluetoothRx 0

// Definirea adresei I2C pentru LCD QAPASS
#define LCD_ADDRESS 0x27
#define LCD_COLUMNS 16
#define LCD_ROWS 2

LiquidCrystal_I2C lcd(LCD_ADDRESS, LCD_COLUMNS, LCD_ROWS);

// Pini pentru modulul Bluetooth HC-05
#define bluetoothEn 2    // Pinul EN al modulului Bluetooth
#define bluetoothState 3 // Pinul STATE al modulului Bluetooth

AccelStepper motor1(AccelStepper::FULL4WIRE, motor1Pin1, motor1Pin3, motor1Pin2, motor1Pin4);
AccelStepper motor2(AccelStepper::FULL4WIRE, motor2Pin1, motor2Pin3, motor2Pin2, motor2Pin4);

#define MAX_COMMAND_LENGTH 10 // Ajustează dimensiunea maximă a comenzilor
char receivedCommand[MAX_COMMAND_LENGTH + 1]; // Adăugăm un spațiu suplimentar pentru terminator
int commandIndex = 0;

long motor1Position = 0;
long motor2Position = 0;

// Timeout pentru comenzi
unsigned long lastCommandTime = 0;
const unsigned long commandTimeout = 5000; // 5 secunde timeout

// Debug flag
bool debug = true;

void setup() {
  lcd.setBacklight(LOW);  // Setează retroiluminarea la nivel scăzut (LOW) pentru a o opri
  delay(1000);            // Așteaptă o secundă pentru a permite stabilizarea
  lcd.setBacklight(HIGH);

  // Citește pozițiile salvate din EEPROM
  EEPROM.get(MOTOR1_EEPROM_ADDRESS, motor1Position);
  EEPROM.get(MOTOR2_EEPROM_ADDRESS, motor2Position);

  // Setează pozițiile curente ale motoarelor
  motor1.setCurrentPosition(motor1Position);
  motor2.setCurrentPosition(motor2Position);

  Serial.begin(9600);
  pinMode(bluetoothEn, INPUT);
  pinMode(bluetoothState, OUTPUT);

  Wire.begin();
  lcd.begin(LCD_COLUMNS, LCD_ROWS, LCD_5x8DOTS);
  lcd.print("Bun venit!");

  // Afișează informații suplimentare pe LCD, dacă este cazul
  lcd.setCursor(0, 1);
  lcd.print("UNSTPB");
  delay(5000);

  // Afiseaza mesajul original
  lcd.clear();
  lcd.setCursor(0, 1);
  lcd.print("Proiect Arduino");

  motor1.setMaxSpeed(1000);
  motor1.setAcceleration(100);
  motor2.setMaxSpeed(1000);
  motor2.setAcceleration(100);

  // Inițializează modulul Bluetooth
  digitalWrite(bluetoothEn, HIGH); // Activează modulul Bluetooth

  // Inițializează modulul Bluetooth HC-05
  delay(500); // Așteaptă 500 de milisecunde pentru a permite stabilizarea modulului

  // Pini pentru motorul 1
  pinMode(motor1Pin1, OUTPUT);
  pinMode(motor1Pin2, OUTPUT);
  pinMode(motor1Pin3, OUTPUT);
  pinMode(motor1Pin4, OUTPUT);

  // Pini pentru motorul 2
  pinMode(motor2Pin1, OUTPUT);
  pinMode(motor2Pin2, OUTPUT);
  pinMode(motor2Pin3, OUTPUT);
  pinMode(motor2Pin4, OUTPUT);

  // Dezactivează motoarele inițial
  digitalWrite(motor1Pin1, LOW);
  digitalWrite(motor1Pin2, LOW);
  digitalWrite(motor1Pin3, LOW);
  digitalWrite(motor1Pin4, LOW);
  digitalWrite(motor2Pin1, LOW);
  digitalWrite(motor2Pin2, LOW);
  digitalWrite(motor2Pin3, LOW);
  digitalWrite(motor2Pin4, LOW);

  lastCommandTime = millis(); // Inițializează timpul ultimei comenzi
}

void loop() {
  if (Serial.available() > 0) {
    char receivedChar = Serial.read();
    lastCommandTime = millis(); // Resetează timer-ul la primirea unei comenzi

    if (receivedChar == '\n') {
      // S-a primit o comandă completă, procesează șirul de caractere acumulat
      receivedCommand[commandIndex] = '\0'; // Adaugă terminatorul de șir
      processBluetoothCommand(receivedCommand);
      commandIndex = 0; // Resetează indexul pentru următoarea comandă
    } else if (receivedChar != '\r') {
      if (commandIndex < MAX_COMMAND_LENGTH) {
        // Adaugă caracterul la șirul de caractere acumulat
        receivedCommand[commandIndex++] = receivedChar;
      } else {
        // Gestionare eroare: comanda este prea lungă
        Serial.println("Comanda prea lungă");
        commandIndex = 0; // Resetează indexul în caz de depășire
      }
    }
  }

  // Verifică dacă a trecut timpul de timeout fără a primi comenzi noi
  if (millis() - lastCommandTime > commandTimeout) {
    debugPrint("Timeout: Resetează sistemul");
    // Cod pentru resetarea sistemului sau pentru a lua măsuri adecvate
    lastCommandTime = millis(); // Resetează timer-ul pentru următorul ciclu
  }
}

void saveMotorPositions() {
  // Salvează pozițiile curente ale motoarelor în EEPROM
  EEPROM.put(MOTOR1_EEPROM_ADDRESS, motor1.currentPosition());
  EEPROM.put(MOTOR2_EEPROM_ADDRESS, motor2.currentPosition());
}

void moveMotorToPosition(AccelStepper &motor, long targetPosition) {
  motor.moveTo(targetPosition);
  motor.runToPosition();
  deactivateMotorPins(motor);
}

void deactivateMotorPins(AccelStepper &motor) {
  if (&motor == &motor1) {
    digitalWrite(motor1Pin1, LOW);
    digitalWrite(motor1Pin2, LOW);
    digitalWrite(motor1Pin3, LOW);
    digitalWrite(motor1Pin4, LOW);
  } else if (&motor == &motor2) {
    digitalWrite(motor2Pin1, LOW);
    digitalWrite(motor2Pin2, LOW);
    digitalWrite(motor2Pin3, LOW);
    digitalWrite(motor2Pin4, LOW);
  }
}

void processBluetoothCommand(char* command) {
  debugPrint("Comanda primita: " + String(command)); // Afișează comanda primită

  // Afișează comanda și pe LCD
  lcd.clear();
  lcd.setBacklight(HIGH);
  lcd.setCursor(0, 0);
  lcd.print("Comanda: ");
  lcd.setCursor(0, 1);
  lcd.print(command);

  if (strcmp(command, "1/90") == 0) {
    motor1.runToNewPosition(512);
    deactivateMotorPins(motor1);
    saveMotorPositions();

  } else if (strcmp(command, "2/90") == 0) {
    motor2.runToNewPosition(512);
    deactivateMotorPins(motor2);
    saveMotorPositions();

  } else if (strcmp(command, "0") == 0) {
    motor1.runToNewPosition(0);
    motor2.runToNewPosition(0);
    deactivateMotorPins(motor1);
    deactivateMotorPins(motor2);
    saveMotorPositions();

  } else if (strcmp(command, "1/45") == 0) {
    motor1.runToNewPosition(256);
    deactivateMotorPins(motor1);
    saveMotorPositions();

  } else if (strcmp(command, "2/45") == 0) {
    motor2.runToNewPosition(256);
    deactivateMotorPins(motor2);
    saveMotorPositions();

  } else if (strcmp(command, "01") == 0) {
    motor1.runToNewPosition(0);
    deactivateMotorPins(motor1);
    saveMotorPositions();

  } else if (strcmp(command, "02") == 0) {
    motor2.runToNewPosition(0);
    deactivateMotorPins(motor2);
    saveMotorPositions();

  } else if (strcmp(command, "12/90") == 0) {
    motor1.runToNewPosition(512);
    motor2.runToNewPosition(512);
    deactivateMotorPins(motor1);
    deactivateMotorPins(motor2);

  } else if (strcmp(command, "12/45") == 0) {
    motor1.runToNewPosition(262);
    deactivateMotorPins(motor1);
    motor2.runToNewPosition(262);
    deactivateMotorPins(motor1);
    deactivateMotorPins(motor2);

  } else {
    // Tratează cazurile de comenzi necunoscute
    debugPrint("Comanda Bluetooth necunoscuta");
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Comanda: ");
    lcd.setCursor(0, 1);
    lcd.print("NECUNOSCUTA");
  }
}

void debugPrint(String message) {
  if (debug) {
    Serial.println(message);
  }
}

First thing first, you need to fix or replace the ENTER/RETURN key on your keyboard.

Excuse me, please explain

This felt to me like a bit of a joke, but maybe I do not understand your point.

WALL OF TEXT

Life is too short to bother parsing that wall of text.

Please take some time to clearly explain the problem, using short, to-the-point sentences or paragraphs with at most 2 to 3 lines.

Ok...Tried to explain in details what happened but I made a shorter version

You are probably overflowing the command input buffer, which will cause such unexpected behavior.

This code, which should be executed in case of an unrecognized command, should reset the command buffer index to zero.

else {
    // Tratează cazurile de comenzi necunoscute
    debugPrint("Comanda Bluetooth necunoscuta");
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Comanda: ");
    lcd.setCursor(0, 1);
    lcd.print("NECUNOSCUTA");
  }

Here, you should always check whether the length of the input buffer could be exceeded:

        // Adaugă caracterul la șirul de caractere acumulat
        receivedCommand[commandIndex++] = receivedChar;

and here, too:

      receivedCommand[commandIndex] = '\0'; // Adaugă terminatorul de șir

I did the first thing you mentioned but the problem is still there. I am not sure if it is the buffer. I did some tests. sometimes I can send but one message and everything would freeze, other times 50 without issues.
More often than not would freeze on third or forth.

I did the first thing you mentioned

But not the other things, which may actually be the problem?

Please post the revised code, using code tags.

#include <Stepper.h>
#include <AccelStepper.h>
#include <MultiStepper.h>
#include <LiquidCrystal_I2C.h>
#include <Wire.h>
#include <EEPROM.h>

// Define EEPROM addresses for motor positions
#define MOTOR1_EEPROM_ADDRESS 0
#define MOTOR2_EEPROM_ADDRESS 10

// Motor 1 pins
#define motor1Pin1 7
#define motor1Pin2 6
#define motor1Pin3 5
#define motor1Pin4 4

// Motor 2 pins
#define motor2Pin1 11
#define motor2Pin2 10
#define motor2Pin3 9
#define motor2Pin4 8

#define bluetoothTx 1
#define bluetoothRx 0

// I2C address for LCD
#define LCD_ADDRESS 0x27
#define LCD_COLUMNS 16
#define LCD_ROWS 2

LiquidCrystal_I2C lcd(LCD_ADDRESS, LCD_COLUMNS, LCD_ROWS);

// Bluetooth HC-05 module pins
#define bluetoothEn 2    // EN pin
#define bluetoothState 3 // STATE pin

AccelStepper motor1(AccelStepper::FULL4WIRE, motor1Pin1, motor1Pin3, motor1Pin2, motor1Pin4);
AccelStepper motor2(AccelStepper::FULL4WIRE, motor2Pin1, motor2Pin3, motor2Pin2, motor2Pin4);

#define MAX_COMMAND_LENGTH 10 // Adjust the maximum command length
char receivedCommand[MAX_COMMAND_LENGTH + 1]; // Extra space for null terminator
int commandIndex = 0;

long motor1Position = 0;
long motor2Position = 0;

// Command timeout
unsigned long lastCommandTime = 0;
const unsigned long commandTimeout = 5000; // 5 seconds timeout

// Debug flag
bool debug = true;

void setup() {
  lcd.setBacklight(LOW);
  delay(1000);
  lcd.setBacklight(HIGH);

  // Read saved positions from EEPROM
  EEPROM.get(MOTOR1_EEPROM_ADDRESS, motor1Position);
  EEPROM.get(MOTOR2_EEPROM_ADDRESS, motor2Position);

  // Set current motor positions
  motor1.setCurrentPosition(motor1Position);
  motor2.setCurrentPosition(motor2Position);

  Serial.begin(9600);
  pinMode(bluetoothEn, INPUT);
  pinMode(bluetoothState, OUTPUT);

  Wire.begin();
  lcd.begin(LCD_COLUMNS, LCD_ROWS, LCD_5x8DOTS);
  lcd.print("Bun venit!");

  lcd.setCursor(0, 1);
  lcd.print("UNSTPB");
  delay(5000);

  lcd.clear();
  lcd.setCursor(0, 1);
  lcd.print("Proiect Arduino");

  motor1.setMaxSpeed(1000);
  motor1.setAcceleration(100);
  motor2.setMaxSpeed(1000);
  motor2.setAcceleration(100);

  digitalWrite(bluetoothEn, HIGH); // Enable Bluetooth module
  delay(500);

  // Motor 1 pins
  pinMode(motor1Pin1, OUTPUT);
  pinMode(motor1Pin2, OUTPUT);
  pinMode(motor1Pin3, OUTPUT);
  pinMode(motor1Pin4, OUTPUT);

  // Motor 2 pins
  pinMode(motor2Pin1, OUTPUT);
  pinMode(motor2Pin2, OUTPUT);
  pinMode(motor2Pin3, OUTPUT);
  pinMode(motor2Pin4, OUTPUT);

  // Initially deactivate motors
  deactivateMotorPins(motor1);
  deactivateMotorPins(motor2);

  lastCommandTime = millis(); // Initialize the last command time
}

void loop() {
  if (Serial.available() > 0) {
    char receivedChar = Serial.read();
    lastCommandTime = millis(); // Reset the timer on receiving a command

    if (receivedChar == '\n') {
      // Complete command received, process it
      receivedCommand[commandIndex] = '\0'; // Null-terminate the string
      processBluetoothCommand(receivedCommand);
      commandIndex = 0; // Reset index for the next command
    } else if (receivedChar != '\r') {
      if (commandIndex < MAX_COMMAND_LENGTH) {
        // Add character to the accumulated command string
        receivedCommand[commandIndex++] = receivedChar;
      } else {
        // Handle error: command is too long
        Serial.println("Comanda prea lungă");
        commandIndex = 0; // Reset index in case of overflow
      }
    }
  }

  // Check if command timeout has been reached
  if (millis() - lastCommandTime > commandTimeout) {
    debugPrint("Timeout: Resetează sistemul");
    // Reset the system or take appropriate actions
    lastCommandTime = millis(); // Reset the timer for the next cycle
  }
}

void saveMotorPositions() {
  // Save current motor positions to EEPROM
  EEPROM.put(MOTOR1_EEPROM_ADDRESS, motor1.currentPosition());
  EEPROM.put(MOTOR2_EEPROM_ADDRESS, motor2.currentPosition());
}

void moveMotorToPosition(AccelStepper &motor, long targetPosition) {
  motor.moveTo(targetPosition);
  while (motor.distanceToGo() != 0) {
    motor.run();
  }
  deactivateMotorPins(motor);
}

void deactivateMotorPins(AccelStepper &motor) {
  if (&motor == &motor1) {
    digitalWrite(motor1Pin1, LOW);
    digitalWrite(motor1Pin2, LOW);
    digitalWrite(motor1Pin3, LOW);
    digitalWrite(motor1Pin4, LOW);
  } else if (&motor == &motor2) {
    digitalWrite(motor2Pin1, LOW);
    digitalWrite(motor2Pin2, LOW);
    digitalWrite(motor2Pin3, LOW);
    digitalWrite(motor2Pin4, LOW);
  }
}

void processBluetoothCommand(char* command) {
  debugPrint("Comanda primita: " + String(command)); // Print received command

  // Display the command on the LCD
  lcd.clear();
  lcd.setBacklight(HIGH);
  lcd.setCursor(0, 0);
  lcd.print("Comanda: ");
  lcd.setCursor(0, 1);
  lcd.print(command);

  if (strcmp(command, "1/90") == 0) {
    moveMotorToPosition(motor1, 512);
    saveMotorPositions();

  } else if (strcmp(command, "2/90") == 0) {
    moveMotorToPosition(motor2, 512);
    saveMotorPositions();

  } else if (strcmp(command, "0") == 0) {
    moveMotorToPosition(motor1, 0);
    moveMotorToPosition(motor2, 0);
    saveMotorPositions();

  } else if (strcmp(command, "1/45") == 0) {
    moveMotorToPosition(motor1, 256);
    saveMotorPositions();

  } else if (strcmp(command, "2/45") == 0) {
    moveMotorToPosition(motor2, 256);
    saveMotorPositions();

  } else if (strcmp(command, "01") == 0) {
    moveMotorToPosition(motor1, 0);
    saveMotorPositions();

  } else if (strcmp(command, "02") == 0) {
    moveMotorToPosition(motor2, 0);
    saveMotorPositions();

  } else if (strcmp(command, "12/90") == 0) {
    moveMotorToPosition(motor1, 512);
    moveMotorToPosition(motor2, 512);
    saveMotorPositions();

  } else if (strcmp(command, "12/45") == 0) {
    moveMotorToPosition(motor1, 262);
    moveMotorToPosition(motor2, 262);
    saveMotorPositions();

  } else {
    // Handle unknown command cases
    debugPrint("Comanda Bluetooth necunoscuta");
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Comanda: ");
    lcd.setCursor(0, 1);
    lcd.print("NECUNOSCUTA");
    commandIndex = 0; // Reset the command buffer index
  }
}

void debugPrint(String message) {
  if (debug) {
    Serial.println(message);
  }
}

It has some minor modifications