Модули HC-05 с платформой, управляемой джойстиком

Я работаю над созданием платформы с джойстиком, управляемой с помощью Bluetooth для связи, но у меня возникло несколько проблем. Платформе https://www.dfrobot.com/wiki/index.php/Cherokey_4WD_Mobile_Platform_(SKU:ROB0102) для работы требуются RX и TX, но также и модулю HC-05. Я пытаюсь использовать программную последовательную линию связи, но она, похоже, не считывает данные и не подключается между ведущим и ведомым устройствами. Кроме того, джойстик подключен к Arduino с ведущим HC-05, но не будет правильно считывать входные данные, если HC-05 подключен (с использованием программного последовательного порта). Ниже приведен мой код, любые предложения будут оценены по достоинству.

Мастер:

#include <SoftwareSerial.h>

SoftwareSerial mySerial(10, 11); // RX, TX

int xPin = A1;
int yPin = A0;
int buttonPin = 8;
int state = 0;

int xPosition = 0;
int yPosition = 0;
int buttonState = 0;

void setup() {
//-----------Начальная стандартная настройка----------------
  // инициализация последовательной связи на скорости 38400 бит/с:
  Serial.begin(9600); 

  pinMode(xPin, INPUT); //Пин A1
  pinMode(yPin, INPUT); // Контакт A0

  //активировать подтягивающий резистор на выводе кнопки
  pinMode(buttonPin, INPUT_PULLUP); 


//------------настройка программного обеспечения------------------
  while (!Serial) 
  {
    ; // ждем подключения последовательного порта. Требуется только для собственного порта USB
  }
  // установить скорость передачи данных для порта SoftwareSerial
  mySerial.begin(38400);

}

void loop() 
{
//------------------Джойстик чтения-----------------------
  int xplus=0, yplus=0, append=0;
  xPosition = analogRead(xPin);
  yPosition = analogRead(yPin);
  buttonState = digitalRead(buttonPin);

  /*Serial.print("X: ");
  Serial.print(xPosition);
  Serial.print(" | Y: ");
  Serial.print(yPosition);
  Serial.print(" | Button: ");
  Serial.println(buttonState);*/
//----------------Данные об упаковке----------------------------
  if(xPosition < 1000) //гарантирует длину в 4 цифры
  {
    xplus = xPosition + 2000; //2000 будет отменено на стороне ведомого устройства
  }else
xplus = xPosition;

  if(yPosition < 1000) //гарантирует длину в 4 цифры
  {
    yplus = yPosition + 2000; //2000 будет отменено на стороне ведомого устройства
  }else
    yplus = yPosition;

  append = (xplus * 10000) + yplus; //создает место для добавления y, простой способ добавить это


//------------Передача информации-------------------------
  if(mySerial.available() > 0){ // Проверяет, поступают ли данные с последовательного порта
    state = mySerial.read(); // Считывает данные из последовательного порта
 }
  mySerial.write(append); // Отправляет добавленное значение ведомому устройству для управления двигателем
  //Serial.write(xPosition);

  delay(100); // добавляем некоторую задержку между чтениями
}

Раб:

#include <SoftwareSerial.h>

SoftwareSerial mySerial(10, 11); // RX, TX
int state = 0;
int xDir = 508, yDir = 508; //среднее положение для джойстика

//Определения двигателей
int E1 = 5;     // Управление скоростью M1
int E2 = 6;     // Управление скоростью M2
int M1 = 4;     // Управление направлением M1
int M2 = 7;     // Управление направлением M2

// Значения скорости двигателя — начинаются с нуля
int MotorSpeed1 = 0;
int MotorSpeed2 = 0;

void setup() 
{
  //Начальная стандартная настройка
  // инициализация последовательной связи на скорости 38400 бит/с:
  Serial.begin(9600);


//------настройка последовательного порта программного обеспечения-----------
  while (!Serial) 
  {
  ; // ждем подключения последовательного порта. Требуется только для собственного порта USB
  }

  // установить скорость передачи данных для порта SoftwareSerial
  mySerial.begin(38400);
}

void loop() 
{
//------------Передача информации----------------------
  if(mySerial.available() > 0)// Проверяет, поступают ли данные с последовательного порта
  { 
    state = mySerial.read(); // Считывает данные из последовательного порта
  }
  xDir = state / 10000; //отрезает последние 4 цифры
  yDir = state % 10000; //отрезает первые 4 цифры
  if(xDir > 1999) //было добавлено 2000
  {
    xDir -= 2000;
  }
  if(yDir > 1999) //было добавлено 2000
  {
    yDir -= 2000;
  }


// -----------Управление двигателем----------------------

if (yDir < 460) // Это обратный путь
 {
 // Установить двигатель A назад
 digitalWrite(M1, LOW);

 // Установить мотор B назад
 digitalWrite(M2, HIGH);

 // Определить скорость двигателя далее

 // Поскольку мы идем назад, нам нужно изменить показания

 yDir -= 460; // Это дает отрицательное число
 yDir *= -1;  // Сделаем число положительным

 MotorSpeed1 = map(yDir, 0, 460, 0, 255);
 MotorSpeed2 = map(yDir, 0, 460, 0, 255);

 }else if (yDir > 564)// Это пересылка
 {
 // Установить двигатель A вперед

 digitalWrite(M1, HIGH);

 // Установить двигатель B вперед

 digitalWrite(M2, LOW);

 // Определить скорость двигателя

 MotorSpeed1 = map(yDir, 564, 1023, 0, 255);
 MotorSpeed2 = map(yDir, 564, 1023, 0, 255); 

 }else // Это остановлено
 {
 MotorSpeed1 = 0;
 MotorSpeed2 = 0; 
 }

 // Теперь займемся рулевым управлением
 // Горизонтальное положение будет «взвешивать» скорость двигателя
 // Значения для каждого двигателя

if (xDir >564)// Переместить вправо
 {
   // Сопоставьте число со значением максимум 255
   xDir = map(xDir, 564, 1023, 0, 255);

   MotorSpeed1 += xDir;
   MotorSpeed2 -= xDir;

   // Не превышайте диапазон 0-255 для скоростей двигателя
   if (MotorSpeed1 > 255)MotorSpeed1 = 255;
   if (MotorSpeed2 < 0)MotorSpeed2 = 0;  
 }else if (xDir < 460) // Переместить влево
 {
   // Так как мы движемся налево, нам нужно поменять показания местами
   xDir -= 460; // Это дает отрицательное число
   xDir *= -1;  // Делаем число положительным

   // Сопоставьте число со значением максимум 255
   xDir = map(xDir, 0, 460, 0, 255);

   MotorSpeed1 -= xDir;
   MotorSpeed2 += xDir;

   // Не превышайте диапазон 0-255 для скоростей двигателя
   if (MotorSpeed1 < 0)MotorSpeed1 = 0;
   if (MotorSpeed2 > 255)MotorSpeed2 = 255;

 }

 // Отрегулируйте, чтобы предотвратить «жужжание» на очень низкой скорости
 if (MotorSpeed1 < 8) MotorSpeed1 = 0;
 if (MotorSpeed2 < 8) MotorSpeed2 = 0;

 // Установите скорость двигателя — может потребоваться digitalWrite, так как аналоговые контакты не используются
// analogWrite(E1, MotorSpeed1); //левый мотор
// analogWrite(E2, MotorSpeed2); //правый мотор
 digitalWrite(E1, MotorSpeed1); //левый мотор
 digitalWrite(E2, MotorSpeed2); //правый мотор



 delay(97); // добавить некоторую задержку между чтениями - не 100, чтобы учесть задержку во время расчета программы
}

, 👍-1


1 ответ


1

Ну, как уже упоминалось в комментариях, у вас, похоже, проблема с размерами. Serial.read() (и, предположительно, SoftwareSerial.read()) возвращает один байт данных (8 бит) как int (это тип, который имеет размер 2 байта?!). Поэтому, чтобы получить все отправляемые вами данные, вам следует читать непрерывно, пока не получите все, что ожидалось. С этим есть проблема: если возникает проблема и отправитель не отправляет все ожидаемые байты, получатель застревает в ожидании отсутствующего байта. Поэтому, возможно, лучше всего читать, пока не получите байт или серию байтов, которые обычно не быть получено.

Если рассматривать это в вашем контексте:

Вы хотите отправить следующие данные:

  • Значение X, от 0 до 1016(?) (мы предположим 1024, это делает математику проще)
  • Значение Y, от 0 до 1024.
  • Значение B, 0 не нажато, 1 нажато.

256 — это максимальное значение, которое может содержать байт, 65 535 — это максимум для двух байтов. Таким образом, ваши данные поместятся в 5 байтах, если мы используем 0xFFFF в качестве маркера конца данных, дополнительные два байта, которые никогда не могут встретиться в ваших данных, каждая передача должна быть 7 байтов.

Теперь измените свой главный (Tx) код так, чтобы он отправлял 7 байт данных, xxyybff.

Затем измените настройки приемника так, чтобы он считывал данные из последовательной линии в буфер «int», пока не увидит байты 0xFF, за которыми следуют 0xFF.

Вам не понадобятся все те добавления, которые вы делали, для извлечения значений вы можете использовать memcpy() или

int buffer[7] = {0x01, 0xFC, 0x01, 0xFC, 0x00, 0xFF, 0xFF}; // Данные из последовательного порта
int x = (buffer[0] << 8) + buffer[1];
int x = (buffer[2] << 8) + buffer[3];
int b = (buffer[3]);
,