Контроллер барабанной игры - Проблема с пьезовходами

В настоящее время я пытаюсь собрать несколько барабанов для игры Clone Hero. Проблема, с которой я столкнулся, заключается в том, что я не могу использовать оба моих пьезовхода, которые я подключил одновременно. У меня есть микро Arduino Pro и я использую эту библиотеку. Это мой код, который у меня есть до сих пор. Я довольно новичок в этом Arduino, так что пока ничего не понимаю.

В любом случае, заранее спасибо. :)

#include <Joystick.h>

const int drum1 = A0;
const int drum2 = A1;
const int drum3 = A2;
const int drum4 = A3;

const int threshold = 100;

int sensorReading = 0;

Joystick_ Joystick;


void setup() {

  // Initialize Joystick Library
  Joystick.begin();
}

// Last state of the button
int lastButtonState = 0;

void loop() {


  sensorReading = analogRead(drum1);

  if (sensorReading >= threshold)
  {
    Joystick.pressButton(0);
    Joystick.releaseButton(0);
  }

  sensorReading = analogRead(drum2);

  if (sensorReading >= threshold)
  {
    Joystick.pressButton(1);
    Joystick.releaseButton(1);

  }
} 

, 👍0

Обсуждение

@Juraj Я могу использовать и то, и другое, но не одновременно., @DuddiSuppe

они не активируются одновременно. они активируются один за другим. вот видео, которое это показывает. https://imgur.com/a/a6quH5d, @DuddiSuppe

Я думаю, судя по вашему описанию, что ваша проблема связана с вашей методологией и тем, чего, по вашему мнению, может достичь ваш код. Код выполняется строго последовательно. Если у вас есть простые конструкции "если это, то то", тогда да, все будет происходить отдельно, независимо от того, насколько близко, по вашему мнению, они находятся во времени. Похоже, вам нужно ввести в свой дизайн концепцию "временных срезов" и "событий". Если эти два события происходят в течение этого предопределенного периода времени, *затем* активируйте *обе* кнопки., @Majenko

Альтернативой является отделение нажатия кнопок от их отпускания. Когда ударит барабан, нажмите кнопку и установите таймер (сохраните метку времени). Когда этот таймер истечет (например, millis() - drum1Time >= 100), отпустите кнопку. Таким образом, вы можете нажать одну кнопку, затем нажать вторую кнопку, и в конечном итоге обе кнопки будут отпущены., @Majenko

Для этого может быть полезно инкапсулировать всю логику и переменные для одного барабана в классе, а затем просто создать несколько экземпляров с различными параметрами для каждой панели барабана и кнопки джойстика., @Majenko


1 ответ


Лучший ответ:

1

Из моей интерпретации вашей проблемы кажется, что вы хотите иметь возможность нажимать две (или более) кнопки джойстика одновременно, ударяя по нескольким барабанам. В нынешнем виде ваш код никогда не сможет этого сделать, так как вы нажимаете, а затем немедленно отпускаете каждую кнопку последовательно.

Самый простой способ обойти это-нажать кнопку только тогда, когда вы ударяете по барабану, а затем отпустить кнопку позже, что дает возможность одновременно нажать другую кнопку. Что это за "позднее время" , вам решать.

Самое простое, что нужно сделать, - это сохранить флажок "этот барабан был поражен" вместе с отметкой времени "этот барабан был поражен" (их можно объединить), оба из которых установлены в момент удара по барабану. Затем позже в своем коде вы проверяете эту метку времени и флаг и отпускаете кнопку (и отключаете флаг), если требуемое время истекло.

Чтобы предотвратить дублирование кода, может быть полезно инкапсулировать переменные логики и состояния для одного барабана в класс, а затем создать несколько экземпляров, по одному для каждой барабанной площадки. Например, вот какой-то непроверенный код, который может работать, а может и не работать:

class Drum {
    private:
        uint32_t _timestamp;
        uint8_t _button;
        uint8_t _channel;
        int16_t _threshold;

    public:
        Drum(uint8_t channel, uint8_t button, int16_t threshold = 100) {
            _channel = channel;
            _button = button;
            _threshold = threshold;
            _timestamp = 0;
        }

        void process() {
            if (_timestamp > 0) { // Has been struck
                if (millis() - _timestamp >= 100) { // 100ms window - adjust as needed
                    Joystick.releaseButton(_button); // Release the button
                    _timestamp = 0; // Set it as not struck
                }
            }

            if (analogRead(_channel) > _threshold) {
                _timestamp = millis(); // Set it as struck now
                Joystick.pressButton(_button); // Press the button
            }
        }
};

Затем вы можете создать несколько экземпляров барабанов:

Drum drum1(A0, 0);
Drum drum2(A1, 1);

Затем в вашем цикле просто:

void loop() {
    drum1.process();
    drum2.process();
}

Еще раз повторяю: этот код непроверен, я даже не знаю, компилируется ли он.

,