Автомобиль с дистанционным управлением 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);
}
}
Не могли бы вы, пожалуйста, помочь мне найти причину?
Кроме того, я не могу заставить его двигаться в обратном направлении. Может ли это быть как-то связано?
@Bogdan Ionică, 👍0
Обсуждение1 ответ
Проблема заключалась в том, что модуль Bluetooth получал байты быстрее, чем мог считывать SoftwareSerial, поэтому функция bluetooth.available()
возвращала более 1U
после пары циклов. Это было исправлено путем изменения следующего:
void readCommand(void) {
command = 0U;
if (bluetooth.available()) {
while(bluetooth.available() > 1U)
bluetooth.read();
command = bluetooth.read();
}
}
Проблема "заставить его работать в обратном направлении" также была решена, но не была связана с этим.
- Управление скоростью вентилятора с помощью библиотеки Arduino PID
- Как устранить шум от вентилятора 12 В с ШИМ-управлением на низкой скорости
- Arduino uno + cnc Shield v3 + драйвер шагового двигателя A4988 + AccelStepper?
- Как заставить сервопривод вращаться на угол больше 180°
- Почему Adafruit motor shield не крутит моторы?
- Как управлять 6 шаговыми двигателями с помощью Arduino?
- Пропорциональный контроль расхода воды
- L298N Dual Motor Controller Enable Pin имеет питание, но двигатели не работают
замените
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