Подключение джойстика Logitech к Arduino и прерывание цикла while
Я работаю над проектом руки-робота. Соединения выполнены из серводвигателя. Основную функцию можно описать следующим образом:
- Манипулятор робота (сервоприводы) перемещался вручную с помощью джойстика Logitech.
- Пользователь может нажать определенную кнопку, чтобы запомнить позицию. Я сделал 6 кнопок на 6 позиций, подробно.
- После запоминания, если была нажата кнопка активации, рука робота будет несколько раз перемещаться по этим 6 позициям, пока не будет нажата кнопка остановки.
Проблема заключалась в смелых словах.
Для того, чтобы рука робота могла многократно перемещаться одним нажатием, я использовал петлю while.
Однако, когда программа находилась в цикле while, события джойстика перестали обновляться независимо от того, как я нажимал или тянул джойстик. Поэтому я не мог запрограммировать кнопку остановки.
Я догадался, что это потому, что события джойстика вызывались вне цикла, но я не знаю, как это сделать внутри. Мой код был основан на примере библиотеки USB Host Shield.
Вот код. В нем содержалось 3 файла. У моего робота также есть еще несколько функций, поэтому я цитирую только ту часть, с которой у меня возникли проблемы.
.файл ino:
#include <usbhid.h>
#include <hiduniversal.h>
#include <usbhub.h>
#include "le3dp_rptparser.h"
// Satisfy the IDE, which needs to see the include statment in the ino too.
#ifdef dobogusinclude
#include <spi4teensy3.h>
#include <SPI.h>
#endif
USB Usb;
USBHub Hub(&Usb);
HIDUniversal Hid(&Usb);
JoystickEvents JoyEvents;
JoystickReportParser Joy(&JoyEvents);
//int waist_back, shoulder_back, wrist_back, gripper_back;
void setup()
{
Serial.begin( 115200 );
#if !defined(__MIPSEL__)
while (!Serial);
#endif
Serial.println("Start");
if (Usb.Init() == -1)
Serial.println("OSC did not start.");
delay( 200 );
if (!Hid.SetReportParser(0, &Joy))
ErrorMessage<uint8_t>(PSTR("SetReportParser"), 1 );
}
void loop()
{
Usb.Task();
}
файл .cpp: Здесь я работал. Пожалуйста, посмотрите на события Joystick::OnGamePadChanged
#include "le3dp_rptparser.h"
//Many parameters for robot here
JoystickReportParser::JoystickReportParser(JoystickEvents *evt) :
joyEvents(evt)
{}
void JoystickReportParser::Parse(USBHID *hid, bool is_rpt_id, uint8_t len, uint8_t *buf)
{
bool match = true;
// Checking if there are changes in report since the method was last called
for (uint8_t i=0; i<RPT_GAMEPAD_LEN; i++) {
if( buf[i] != oldPad[i] ) {
match = false;
break;
}
}
// Calling Game Pad event handler
if (!match && joyEvents) {
joyEvents->OnGamePadChanged((const GamePadEventData*)buf);
for (uint8_t i=0; i<RPT_GAMEPAD_LEN; i++) oldPad[i] = buf[i];
}
}
void JoystickEvents::OnGamePadChanged(const GamePadEventData *evt)
{
Serial.print("X: ");
Serial.print(evt->x);
Serial.print(" Y: ");
Serial.print(evt->y);
Serial.print(" Hat Switch: ");
Serial.print(evt->hat);
Serial.print(" Twist: ");
Serial.print(evt->twist);
Serial.print(" Slider: ");
Serial.print(evt->slider);
Serial.print(" Buttons A: ");
Serial.print(evt->buttons_a);
Serial.print(" Buttons B: ");
Serial.print(evt->buttons_b);
Serial.println("");
// Manual control program here. I didn't post because it was so long.
//Activation
if (evt->buttons_a == 32){
while (evt->slider == 0){
//Robot working here, also a long code that was out of limit for a block here.
Serial.print(evt->slider);
}
}
}
файл .h:
#if !defined(__HIDJOYSTICKRPTPARSER_H__)
#define __HIDJOYSTICKRPTPARSER_H__
#include <usbhid.h>
struct GamePadEventData
{
union { //axes and hut switch
uint32_t axes;
struct {
uint32_t x : 10;
uint32_t y : 10;
uint32_t hat : 4;
uint32_t twist : 8;
};
};
uint8_t buttons_a;
uint8_t slider;
uint8_t buttons_b;
};
class JoystickEvents
{
public:
virtual void OnGamePadChanged(const GamePadEventData *evt);
static GamePadEventData mostRecentEvent;
};
#define RPT_GAMEPAD_LEN sizeof(GamePadEventData)/sizeof(uint8_t)
class JoystickReportParser : public HIDReportParser
{
JoystickEvents *joyEvents;
uint8_t oldPad[RPT_GAMEPAD_LEN];
public:
JoystickReportParser(JoystickEvents *evt);
virtual void Parse(USBHID *hid, bool is_rpt_id, uint8_t len, uint8_t *buf);
};
#endif // __HIDJOYSTICKRPTPARSER_H__
После активации //
в разделе JoystickEvents::OnGamePadChanged
, независимо от того, как я потянул ползунок джойстика, событие не обновлялось, evt->ползунок>
всегда возвращал ноль, и рука робота не могла быть остановлена.
Есть ли какой-либо способ обновить событие джойстика внутри цикла while?
Или другой метод, отличный от цикла while, чтобы заставить что-то двигаться несколько раз после нажатия одной кнопки, и его можно остановить другой кнопкой?
Большое вам спасибо за чтение, и, пожалуйста, помогите мне!
@John Keane, 👍4
2 ответа
Поскольку полный код не опубликован, я не могу предложить вам правильно, но вы должны добавить две кнопки "ПУСК" и "СТОП".
При нажатии кнопки "СТОП" все события (выполняется ваш код) должны перестать работать.
Просто убедитесь, что при программировании для управления джойстиком код кнопок ЗАПУСКА и ОСТАНОВКИ должен попадать в контур управления джойстиком.
if (STOP PRESSED){
}else if(START PRESSED){
//INVOKE THE FUNCTIONS FOR ACTIONS TO BE PERFORMED
}
Хитрость в том, чтобы никогда не использовать цикл while для ожидания чего-то физического. Вместо этого напишите код, который не блокирует выполнение остальной части кода. Напишите свой код так, чтобы вместо того, чтобы сидеть в цикле while, функция полагалась на то, что ее снова и снова вызывают из функции цикла. Позвольте функции цикла выполнить зацикливание.
- Вибрационный геймпад Arduino с силовой обратной связью
- Экспонируйте два устройства HID Joystick с одной платой RP2040 (Waveshare Pi Pico Zero)
- Можно ли использовать Arduino UNO для эмуляции джойстика PS4?
- Переключение между устройствами SPI, когда одно из них является SD-картой
- Библиотека джойстиков Arduino не распознается играми (Steam)
- Как использовать защитный экран USB-хост с различными джойстиками HID
- Проблемы Funduino USB Host Shield
- USB-хост Arduino и SD-карта
Спасибо. Я планировал опубликовать полный код в самом начале, но сайт сказал мне, что у меня нет ограничений, поэтому у меня не было выбора, кроме как опубликовать ту часть, которая мне нужна., @John Keane