Контекст
Контекст проблемы в том, что я сейчас пишу небольшую библиотеку для использования с Arduino, чтобы действовать в качестве игрового контроллера.Однако проблема, с которой я сталкиваюсь, больше связана с C ++, чем с чем-то специфичным для Arduino.
Я включил заголовок библиотеки и исходный код ниже, а затем код Arduino.Я обрезал его там, где это возможно.
Проблема
Короче говоря, только последний переключатель / действие, которое я определил, на самом деле правильно обрабатывается.
Этидействия определяются в функции настройки Arduino.Например:
controller.addSwitchContinuous(10, 0); // Pin 10; btn index 0
означает, что контакт 10 привязан к кнопке 0. Когда контакт 10 замкнут, это рассматривается как нажатие кнопки.Это прекрасно работает для одного действия, но когда я начинаю добавлять больше, только последнее действие действительно работает.Таким образом, в следующем примере распознается только вывод 9:
controller.addSwitchContinuous(10, 0); // <-- Doesn't work
controller.addSwitchContinuous(9, 1); // <-- Works
Это относится к любому произвольному числу действий:
controller.addSwitchContinuous(10, 0); // <-- Doesn't work
controller.addSwitchContinuous(9, 1); // <-- Doesn't work
controller.addSwitchContinuous(8, 2); // <-- Doesn't work
controller.addSwitchContinuous(7, 3); // <-- Works
Потенциальные причины
Я довольно новичок в C ++, поэтому я подозреваю, что что-то не так с указателями.Более конкретно, что-то не так с передачей экземпляра Joystick_
.
Я возился с конструктором и пытался использовать ссылки вместо указателей, но я не смог заставить его работать должным образом.
Я могу подтвердить, что итерация в цикле JFSF :: выполняет итерацию по всем действиям, если я изменяю ее с помощью:
void JFSF::loop()
{
for (int n = 0; n < _nextActionIndex; n++)
{
if (_actions[n])
{
_actions[n]->loop();
_joystick->setButton(n, PRESSED); // Debug: Set button pressed, regardless of switch.
}
}
if (_doSendState)
{
_joystick->sendState();
}
}
, тогда кнопки от 0 до n нажимаются, как и ожидалось.Возможно, что loop () не вызывается должным образом, но я ожидаю, что в этом случае он также потерпит неудачу для случая N = 1.Более того, тот факт, что последнее действие всегда завершается успешно, указывает на то, что итерация в порядке.
Полный код
// JFSF.h
#ifndef JFSF_h
#define JFSF_h
// ... include for Arduino.h and Joystick.h; bunch of defines
namespace JFSF_PRIV
{
class AbstractAction
{
public:
virtual void loop();
};
/* A Switch that essentially acts as a push button. */
class SwitchContinuousAction : public AbstractAction
{
public:
SwitchContinuousAction(Joystick_ *joystick, int pin, int btnIndex);
void loop();
private:
Joystick_ *_joystick;
int _pin;
int _btnIndex;
};
} // namespace JFSF_PRIV
class JFSF
{
public:
JFSF(Joystick_ *joystick, bool doSendState); // doSendState should be true if Joystick_ does not auto send state.
void loop();
void addSwitchContinuous(int inputPin, int btnIndex);
private:
Joystick_ *_joystick;
JFSF_PRIV::AbstractAction *_actions[MAX_ACTIONS];
int _nextActionIndex;
bool _doSendState;
};
#endif
Исходный файл (обрезан):
// JFSF.cpp
#include "Arduino.h"
#include "Joystick.h"
#include "JFSF.h"
#define PRESSED 1
#define RELEASED 0
// Private classes
namespace JFSF_PRIV
{
SwitchContinuousAction::SwitchContinuousAction(Joystick_ *joystick, int pin, int btnIndex)
{
_joystick = joystick;
_pin = pin;
_btnIndex = btnIndex;
pinMode(_pin, INPUT_PULLUP);
}
void SwitchContinuousAction::loop()
{
int _state = digitalRead(_pin) == LOW ? PRESSED : RELEASED;
_joystick->setButton(_btnIndex, _state);
}
} // namespace JFSF_PRIV
JFSF::JFSF(Joystick_ *joystick, bool doSendState)
{
_joystick = joystick;
_nextActionIndex = 0;
_doSendState = doSendState;
}
void JFSF::addSwitchContinuous(int inputPin, int btnIndex)
{
JFSF_PRIV::SwitchContinuousAction newBtnAction(_joystick, inputPin, btnIndex);
_actions[_nextActionIndex++] = &newBtnAction;
}
void JFSF::loop()
{
for (int n = 0; n < _nextActionIndex; n++)
{
if (_actions[n])
{
_actions[n]->loop();
}
}
if (_doSendState)
{
_joystick->sendState();
}
}
Для полноты картины, это код для Arduino, но это всего лишь объявления:
#include <JFSF.h>
// ... A bunch of const declarations used below. These are pretty self explanatory.
// See: https://github.com/MHeironimus/ArduinoJoystickLibrary#joystick-library-api
Joystick_ joystick(HID_REPORT_ID,
JOYSTICK_TYPE_JOYSTICK, // _JOYSTICK, _GAMEPAD or _MULTI_AXIS
BTN_COUNT, HAT_SWITCH_COUNT,
INCLUDE_X_AXIS, INCLUDE_Y_AXIS, INCLUDE_Z_AXIS,
INCLUDE_RX_AXIS, INCLUDE_RY_AXIS, INCLUDE_RZ_AXIS,
INCLUDE_RUDDER, INCLUDE_THROTTLE,
INCLUDE_ACCELERATOR, INCLUDE_BRAKE, INCLUDE_STEERING);
JFSF controller(&joystick, !DO_AUTO_SEND_STATE);
void setup() {
joystick.begin(DO_AUTO_SEND_STATE);
controller.addSwitchContinuous(10, 0); // <-- Doesn't work
controller.addSwitchContinuous(9, 1); // <-- Works
}
void loop() {
controller.loop();
}
Ссылки
ArduinoJoystickLibrary (Источник для Joystick_) можно найти здесь: https://github.com/MHeironimus/ArduinoJoystickLibrary#joystick-library-api