ARDUINO Помощь с кодом. Управление машинкой со смартфона по BLT на модуле HC-05

SL.y

★✩✩✩✩✩✩
22 Мар 2020
156
44
Добрый день. Нужна небольшая помощь с кодом. Система перестает корректно обрабатывать команды "прямо-влево" и тд. поскольку неправильное обращение приводит к конфликту между специальным маневром и последующим поведением. Нужно чтобы одна сторона крутилась медленнее при движении прямо-влево, прямо-вправо и тд , тем самым происходило плавное отклонение от курса. При смене команды или отпускании кнопки на смартфоне, ШИМ сигнал восстанавливал свое значение. Подскажите в каком направлении двигаться. Спасибо.

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();
    }
  }
}
 
Изменено:

Bruzzer

★★★★✩✩✩
23 Май 2020
729
225
Не знаю, как другие, но я совсем не понял это предложение.
Дополнительно вопрос -вы не можете придумать сам принцип управления, или не знаете, как записать его в программе?
 

SL.y

★✩✩✩✩✩✩
22 Мар 2020
156
44
@Bruzzer, Постарался переформулировать. ) У меня не получается замедлить левый или правый двигатель без последующего конфликта в поведении, так как при смене команды замедленная сторона сохраняет значения ШИМ и при движении прямо,продолжает медленно вращаться. Прикрутил функцию resetPWM, вообще перестал реагировать.
C++:
void resetPWM() {
  analogWrite(pwmRight, speedFactor);
  analogWrite(pwmLeft, speedFactor);
}
 
Изменено:

Bruzzer

★★★★✩✩✩
23 Май 2020
729
225
@SL.y,
Я не понял ваш код (ваши задумки). Зачем у вас вызывается resetPWM(); в конце блока, как оно вообще может поворачивать в таком случае. Хотя может ваш драйвер это позволяет.
Что будет если speedFactor < slowdownFactor (будет сюрприз)

C++:
void Right_Back() {                   // Повернуть направо назад
  const int slowdownFactor = 90;        // Величина уменьшения скорости двигателя
  analogWrite(pwmRight, speedFactor - slowdownFactor);
  analogWrite(pwmLeft, speedFactor);
  digitalWrite(ledStop, LOW);
  moveBackward();
  resetPWM();
}
}
В рамках вашего кода, если надо при смене команды сбрасывать шим, то вызывайте ваш resetPWM(); При смене команды
C++:
case 'F':                               // Едем прямо
    resetPWM();
    moveForward();
    break;
 
  • Лойс +1
Реакции: SL.y

SL.y

★✩✩✩✩✩✩
22 Мар 2020
156
44
Зачем у вас вызывается resetPWM(); в конце блока, как оно вообще может поворачивать в таком случае.
Ну так оно и не поворачивает теперь :-D
если надо при смене команды сбрасывать шим, то вызывайте ваш resetPWM();
Об этом я как-то не подумал. Намудрил, уже не знал с какой стороны зайти )
Что будет если speedFactor < slowdownFactor (будет сюрприз)
Вопрос хороший, могу попробовать))) Ну можно в map попробовать выставить границы..
 

viktor1703

★★★✩✩✩✩
9 Дек 2021
773
191
при смене команды замедленная сторона сохраняет значения ШИМ и при движении прямо,продолжает медленно вращаться. Прикрутил функцию resetPWM
А вы в правильном месте применяете resetPWM()? Вот, например, функция
C++:
void Right_Forward() {                 // Повернуть направо вперёд   
  const int slowdownFactor = 90;        // Величина уменьшения скорости двигателя
  analogWrite(pwmLeft, speedFactor);
  analogWrite(pwmRight, 150);
  digitalWrite(ledStop, LOW);
  moveForward();
  resetPWM();
}
Какое поведение вы ожидаете? Вы устанавливаете пониженную скорость мотора, и следующим шагом сбрасываете её функцией resetPWM() что заставит оба мотора вращаться с одинаковой скоростью. Никакого поворота и не будет.
 

SL.y

★✩✩✩✩✩✩
22 Мар 2020
156
44
@viktor1703,Согласен, это я уже позднее пытался исправить.
C++:
analogWrite(pwmLeft, 255);
analogWrite(pwmRight, 150);
Дело в том, что искал путь решения сбросить значение шим при движении. Вот и создал функцию resetPWM.
 

SL.y

★✩✩✩✩✩✩
22 Мар 2020
156
44
@bort707, попробую лучше функцию resetPWM на "S" стоп и "F" вперед повесить. Есть предложение, что не корректно драйвер мотора себя ведёт. Поэтому не получается настроить. АКБ поставил на зарядку, позднее понаблюдаю.