Добрый день. Нужна небольшая помощь с кодом. Система перестает корректно обрабатывать команды "прямо-влево" и тд. поскольку неправильное обращение приводит к конфликту между специальным маневром и последующим поведением. Нужно чтобы одна сторона крутилась медленнее при движении прямо-влево, прямо-вправо и тд , тем самым происходило плавное отклонение от курса. При смене команды или отпускании кнопки на смартфоне, ШИМ сигнал восстанавливал свое значение. Подскажите в каком направлении двигаться. Спасибо.
C++:
/*
F – вперед
B – назад
L – влево
R – вправо
G – прямо и влево
I – прямо и вправо
H – назад и влево
J – назад и вправо
S – стоп
W – передняя фара включена
w – передняя фара выключена
U – задняя фара включена
u – задняя фара выключена
V – звуковой сигнал включен
v – звуковой сигнал выключен
X – сигнал "аварийка” включен
x - сигнал "аварийка” выключен
0 – скорость движения 0%
1 – скорость движения 10%
2 – скорость движения 20%
3 – скорость движения 30%
4 – скорость движения 40%
5 – скорость движения 50%
6 – скорость движения 60%
7 – скорость движения 70%
8 – скорость движения 80%
9 – скорость движения 90%
q – скорость движения 100%
*/
#include <SoftwareSerial.h>
#define rxPin 10 // RX-пин модуля HC-06
#define txPin 11 // TX-пин модуля HC-06
#define ledRX 13 // Светодиод индикации (пин RX на модуле)
#define ledStop 12 // Светодиод индикации стоп сигнала
// Назначение выводов для драйверов двигателя
#define motorLeftForward 2 // Вперед левое колесо
#define motorRightForward 7 // Вперед правое колесо
#define motorLeftBackward 4 // Назад левое колесо
#define motorRightBackward 8 // Назад правое колесо
#define pwmLeft 3 // ШИМ вывод для левого колеса
#define pwmRight 6 // ШИМ вывод для правого колеса
unsigned long lastCommandTime = 0; // Время последней полученной команды
bool isConnected = true; // Индикатор текущего статуса соединения
int speedFactor = 255; // Текущая скорость двигателей
SoftwareSerial BTserial(rxPin, txPin);
void setup() {
pinMode(motorLeftForward, OUTPUT);
pinMode(motorRightForward, OUTPUT);
pinMode(motorLeftBackward, OUTPUT);
pinMode(motorRightBackward, OUTPUT);
pinMode(pwmLeft, OUTPUT);
pinMode(pwmRight, OUTPUT);
pinMode(ledRX, INPUT_PULLUP); // Используем внутренний подтягивающий резистор
pinMode(ledStop, OUTPUT);
resetPWM();
analogWrite(pwmLeft, speedFactor); // Установка начальной скорости
analogWrite(pwmRight, speedFactor);
BTserial.begin(9600);
Serial.begin(9600);
}
void resetPWM() {
analogWrite(pwmRight, speedFactor);
analogWrite(pwmLeft, speedFactor);
}
void moveForward() {
digitalWrite(motorLeftForward, HIGH);
digitalWrite(motorRightForward, HIGH);
digitalWrite(motorLeftBackward, LOW);
digitalWrite(motorRightBackward, LOW);
digitalWrite(ledStop, LOW);
}
void moveBackward() {
digitalWrite(motorLeftForward, LOW);
digitalWrite(motorRightForward, LOW);
digitalWrite(motorLeftBackward, HIGH);
digitalWrite(motorRightBackward, HIGH);
digitalWrite(ledStop, LOW);
}
void turnLeft() {
digitalWrite(motorLeftForward, HIGH);
digitalWrite(motorRightForward, LOW);
digitalWrite(motorLeftBackward, LOW);
digitalWrite(motorRightBackward, HIGH);
digitalWrite(ledStop, LOW);
}
void turnRight() {
digitalWrite(motorLeftForward, LOW);
digitalWrite(motorRightForward, HIGH);
digitalWrite(motorLeftBackward, HIGH);
digitalWrite(motorRightBackward, LOW);
digitalWrite(ledStop, LOW);
}
void Right_Forward() { // Повернуть направо вперёд
const int slowdownFactor = 90; // Величина уменьшения скорости двигателя
analogWrite(pwmLeft, speedFactor);
analogWrite(pwmRight, 150);
digitalWrite(ledStop, LOW);
moveForward();
resetPWM();
}
void Left_Forward() { // Повернуть налево вперёд
const int slowdownFactor = 90; // Величина уменьшения скорости двигателя
analogWrite(pwmRight, speedFactor);
analogWrite(pwmLeft, 150);
digitalWrite(ledStop, LOW);
moveForward();
resetPWM();
}
void Right_Back() { // Повернуть направо назад
const int slowdownFactor = 90; // Величина уменьшения скорости двигателя
analogWrite(pwmRight, speedFactor - slowdownFactor);
analogWrite(pwmLeft, speedFactor);
digitalWrite(ledStop, LOW);
moveBackward();
resetPWM();
}
void Left_Back() { // Повернуть налево назад
const int slowdownFactor = 90; // Величина уменьшения скорости двигателя
analogWrite(pwmRight, speedFactor);
analogWrite(pwmLeft, speedFactor - slowdownFactor);
digitalWrite(ledStop, LOW);
moveBackward();
resetPWM();
}
void stopMotors() {
digitalWrite(motorLeftForward, LOW);
digitalWrite(motorRightForward, LOW);
digitalWrite(motorLeftBackward, LOW);
digitalWrite(motorRightBackward, LOW);
digitalWrite(ledStop, HIGH);
}
void setSpeed(int newSpeed) {
speedFactor = map(newSpeed, 0, 9, 0, 255); // Преобразование входных значений в диапазоне [0..9]
resetPWM();
}
void checkConnection() {
bool currentLedState = !digitalRead(ledRX); // Низкий уровень на RX говорит о быстром мигании (потеря связи)
if (currentLedState != isConnected) { // Изменилось состояние подключения
isConnected = currentLedState;
if (!isConnected) {
stopMotors(); // Если потерялось соединение, останавливаем двигатели
}
}
}
void loop() {
checkConnection(); // Непрерывно проверяем статус подключения
if (isConnected && BTserial.available()) { // Если соединены и получили данные
char command = BTserial.read();
lastCommandTime = millis(); // Записываем время получения команды
switch (command) {
case 'F': // Едем прямо
moveForward();
break;
case 'B': // Задний ход
moveBackward();
break;
case 'L': // Поворот налево
turnLeft();
break;
case 'R': // Поворот направо
turnRight();
break;
case 'I':
Right_Forward();
break;
case 'G':
Left_Forward();
break;
case 'J':
Right_Back();
break;
case 'H':
Left_Back();
break;
case 'S': // Полностью останавливаемся
stopMotors();
break;
case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9':
setSpeed(command - '0'); // Определяем текущую скорость по символу (0-9)
break;
default:
stopMotors(); // Все остальные команды означают остановку
break;
}
} else {
if ((millis() - lastCommandTime > 1000) || !isConnected) { // Остановка через каждую секунду или при потере связи
stopMotors();
}
}
}
Изменено: