Автомобиль с дистанционным управлением Arduino останавливается через несколько секунд

Я делаю автомобиль с дистанционным управлением для проекта в университете. Автомобиль сделан из Arduino Uno, драйвера с 2 двигателями и приемопередатчика Bluetooth. Я написал для него некоторый код, но он случайным образом останавливается после 2 или 3 циклов.

Вот мой код:

#include "SoftwareSerial.h"

typedef unsigned char u8;

typedef struct {
  u8 right;
  u8 left;
} speed;

SoftwareSerial bluetooth(4, 2);

const u8 RIGHT_MOTOR_PIN1 = 3;
const u8 RIGHT_MOTOR_PIN2 = 5;
const u8 LEFT_MOTOR_PIN1 = 6;
const u8 LEFT_MOTOR_PIN2 = 9;

const u8 MAX_SPEED = 0xFFU;
const u8 HALF_SPEED = MAX_SPEED / 2;
const u8 NO_SPEED = 0x0U;

static u8 command = 0U;
static speed potentialSpeed;
static speed actualSpeed;

void setup() {
  bluetooth.begin(115200);
  while (0U != bluetooth.available()) bluetooth.read();
  potentialSpeed.right = MAX_SPEED;
  potentialSpeed.left = MAX_SPEED;
  actualSpeed.right = NO_SPEED;
  actualSpeed.left = NO_SPEED;
}

void loop() {
  readCommand();
  {
    if (clockwise(command)) {
      if (0U == (command & 0xFEU)) {
        actualSpeed.right = - MAX_SPEED;
        actualSpeed.left = + MAX_SPEED;
      }
    } else if (counterclockwise(command)) {
      if (0U == (command & 0xFDU)) {
        actualSpeed.right = + MAX_SPEED;
        actualSpeed.left = - MAX_SPEED;
      }
    } else {
      if (right(command)) {
        potentialSpeed.right = HALF_SPEED;
      }
      if (left(command)) {
        potentialSpeed.left = HALF_SPEED;
      }
      if (forward(command)) {
        if (!backward(command)) {
          actualSpeed.right = + potentialSpeed.right;
          actualSpeed.left = + potentialSpeed.left;
        }
      } else if (backward(command)) {
        actualSpeed.right = - potentialSpeed.right;
        actualSpeed.left = - potentialSpeed.left;
      }
    }
    if (0U == command) {
      potentialSpeed.right = MAX_SPEED;
      potentialSpeed.left = MAX_SPEED;
      actualSpeed.right = NO_SPEED;
      actualSpeed.left = NO_SPEED;
    }
  }
  runAt(actualSpeed);
  delay(95);
}

void readCommand(void) {
  command = 0U;
  if (1U == bluetooth.available())
    command = bluetooth.read();
}

inline boolean clockwise(u8 command) {
  return (boolean)((command >> 0U) & 1U);
}
inline boolean counterclockwise(u8 command) {
  return (boolean)((command >> 1U) & 1U);
}
inline boolean right(u8 command) {
  return (boolean)((command >> 2U) & 1U);
}
inline boolean left(u8 command) {
  return (boolean)((command >> 3U) & 1U);
}
inline boolean forward(u8 command) {
  return (boolean)((command >> 4U) & 1U);
}
inline boolean backward(u8 command) {
  return (boolean)((command >> 5U) & 1U);
}

void runAt(speed Speed) {
  if (Speed.right > 0U) {
    analogWrite(RIGHT_MOTOR_PIN1, 0U);
    analogWrite(RIGHT_MOTOR_PIN2, Speed.right);
  } else {
    analogWrite(RIGHT_MOTOR_PIN1, (-(Speed.right)));
    analogWrite(RIGHT_MOTOR_PIN2, 0U);
  }
  if (Speed.left > 0U) {
    analogWrite(LEFT_MOTOR_PIN1, 0U);
    analogWrite(LEFT_MOTOR_PIN2, Speed.left);
  }
  else {
    analogWrite(LEFT_MOTOR_PIN1, (-(Speed.left)));
    analogWrite(LEFT_MOTOR_PIN2, 0U);
  }
}

Не могли бы вы, пожалуйста, помочь мне найти причину?
Кроме того, я не могу заставить его двигаться в обратном направлении. Может ли это быть как-то связано?

, 👍0

Обсуждение

замените if (1U == bluetooth.available()) command = bluetooth.read(); на фиксированную команду command = turn_left .... посмотрите, продолжает ли он это делать, @jsotola

Скорость передачи программного обеспечения ограничена. используйте 9600 или 19200 бод, @Juraj

вы пытались отладить последовательную связь того, какую команду вы получаете от модуля Bluetooth? возможно, вы получили неправильную передачу данных в бодах или программное обеспечение отправляет неверные данные, @max246

У меня такая же проблема. Вот мой код: #включить <Servo.h>#включить <AFMotor.h>#включить <SoftwareSerial.h>// Библиотека программного обеспечения TX RX для bluetooth Servo myservo; // создать сервообъект для управления сервоприводом // можно создать максимум восемь сервообъектов AF_DCMotor motor1 (1, MOTOR12_1KHZ); // создать двигатель # 1 с использованием вывода M1 на Экран привода двигателя, установленный на частоту ШИМ 1 кГц int state = '0'; int PosRight = 45; int PosLeft = 135; int PosF = 90; int pos = 90; int Speed = 150; void setup() { Serial.begin(9600); myservo.attach(9); // присоединяет сервопривод на выводе 9 к объекту сервопривода } void loop() {, @Greenman828


1 ответ


1

Проблема заключалась в том, что модуль Bluetooth получал байты быстрее, чем мог считывать SoftwareSerial, поэтому функция bluetooth.available() возвращала более 1U после пары циклов. Это было исправлено путем изменения следующего:

void readCommand(void) {
  command = 0U;
  if (bluetooth.available()) {
    while(bluetooth.available() > 1U)
      bluetooth.read();
    command = bluetooth.read();
  }
}

Проблема "заставить его работать в обратном направлении" также была решена, но не была связана с этим.

,