Модули 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, чтобы учесть задержку во время расчета программы
}
@Aruss, 👍-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]);
- Bluetooth-модуль HC-05 неправильно считывает данные с моего телефона Android
- Я могу отправлять на software serial, но не прочитать?
- Проблема: Срабатывание концевого выключателя для остановки двигателя постоянного тока.
- Проблемы с подключением Bluetooth OBD2 ELM327
- Управление скоростью двигателя постоянного тока с батареей 9 В
- SoftwareSerial читается до тех пор, пока не станет пустым, работает только с задержкой
- Переменная скорость разгона для двигателей, управляемых джойстиком
- mySerial.available() возвращает 0