Проверьте, нажаты ли несколько кнопок Windows IoT с Raspberry PI 3B

В настоящее время я работаю с Raspberry PI 3 с Windows 10 IoT и пытаюсь создать игру «Саймон говорит» в Visual Studio 2015.

Все подключено следующим образом: Fritzing image

У меня работают светодиоды, но я не могу понять, как определить, когда кнопка нажата.

Части исходного кода:

Переменные

    private const int BTNRED = 5;
    private const int BTNBLUE = 6;
    private const int BTNYELLOW = 13;
    private const int BTNGREEN = 19;

    private GpioPin _btnRed;
    private GpioPin _btnBlue;
    private GpioPin _btnYellow;
    private GpioPin _btnGreen;

    private Random rnd;
    private static GpioController _gpioController;

Метод распознавания нажатия кнопки.

    public static IList<Step> PressedButtons
    {
        get
        {
            List<Step> returnVal = new List<Step>();

            if (GetMap._btnBlue.Read() == GpioPinValue.High)
            { returnVal.Add(Step.Blue); }
            if (GetMap._btnGreen.Read() == GpioPinValue.High)
            { returnVal.Add(Step.Green); }
            if (GetMap._btnRed.Read() == GpioPinValue.High)
            { returnVal.Add(Step.Red); }
            if (GetMap._btnYellow.Read() == GpioPinValue.High)
            { returnVal.Add(Step.Yellow); }

            return returnVal;
        }
    }

    /// <summary>
    /// Checks if any of the 4 buttons is pressed.
    /// </summary>
    /// <returns>Returns false if no button is pressed.</returns>
    public static bool isButtonPressed
    {
        get
        {
            if (GetMap._btnBlue.Read() == GpioPinValue.Low)
            { return true; }
            if (GetMap._btnGreen.Read() == GpioPinValue.Low)
            { return true; }
            if (GetMap._btnRed.Read() == GpioPinValue.Low)
            { return true; }
            if (GetMap._btnYellow.Read() == GpioPinValue.Low)
            { return true; ; }

            return false;
        }
    }

Назначение правильных контактов на GPIO соответствующим переменным

    private GPIOMap()
    {
        rnd = new Random();
        _gpioController = GpioController.GetDefault();
        if (_gpioController == null) { return; }

        _ledRed = _gpioController.OpenPin(LEDRED);
        _ledRed.SetDriveMode(GpioPinDriveMode.Output);
        _ledYellow = _gpioController.OpenPin(LEDYELLOW);
        _ledYellow.SetDriveMode(GpioPinDriveMode.Output);
        _ledGreen = _gpioController.OpenPin(LEDGREEN);
        _ledGreen.SetDriveMode(GpioPinDriveMode.Output);
        _ledBlue = _gpioController.OpenPin(LEDBLUE);
        _ledBlue.SetDriveMode(GpioPinDriveMode.Output);

        _btnBlue = _gpioController.OpenPin(BTNBLUE);
        _btnGreen = _gpioController.OpenPin(BTNGREEN);
        _btnRed = _gpioController.OpenPin(BTNRED);
        _btnYellow = _gpioController.OpenPin(BTNYELLOW);

    }
    private static GPIOMap GPIOMapInstance;
    public static GPIOMap GetMap
    {
        get
        {
            if (GPIOMapInstance == null || _gpioController == null)
            { GPIOMapInstance = new GPIOMap(); }
            return GPIOMapInstance;
        }
    }

Запустите игру, где, как вы видите, она должна приводить меня в состояние 2 всякий раз, когда нажимается кнопка. Однако это не совсем так, так как анимация простоя продолжается.

    private void RunGame()
    {
        while (_isRunning)
        {
            switch (_state)
            {
                //Idle state
                case (0x01):
                    //If any button is pressed, start the game.
                    if (GPIOMap.isButtonPressed)
                    {
                        _state = 0x02;
                        Task.Delay(500).Wait();
                        GPIOMap.PlayStartAnimation();
                        Task.Delay(1000).Wait();
                        break;
                    }

                    //If nothing happens, continue playing the idle animation.
                    GPIOMap.PlayIdleAnimationOnce();

                    break;

                //Playback state
                case (0x02):
                   //Play all the currently existing steps.
                    for (int i = 0; i <= _gameInstance.TotalSteps; i++)
                    { GPIOMap.BlinkLight(_gameInstance.GetNextStep(), 500); }

                    //Generate and play a new step.
                    GPIOMap.BlinkLight(_gameInstance.GetNextStep(), 500);

                    //Switch to the input state.
                    _state = 0x03;
                    //Set the start time for the input.
                    _answerPending = DateTime.UtcNow;
                    break;

                //Input state
                case (0x03):

                    if(_gameInstance.CurrentStep > MAXSTEPS)
                    {
                        //Win Game
                        ResetGame();
                        break;
                    }

                    //If the player waits too long before answering, lose the game.
                    if ((DateTime.UtcNow - _answerPending) > _timeout)
                    {
                        GPIOMap.ConfirmWrongAnswer();
                        ResetGame();
                        break;
                    }

                    //If there are no more steps to re-trace, go back to playback state.
                    if (_gameInstance.CurrentStep > _gameInstance.TotalSteps)
                    { _gameInstance.ResetSteps(); _state = 0x02; break; }

                    //If no buttons are pressed, keep polling.
                    if (!GPIOMap.isButtonPressed) { break; }

                    IList<Step> pressedButtons = GPIOMap.PressedButtons;
                    //If anything but one button is pressed, lose the game.
                    if (pressedButtons.Count != 1)
                    {
                        GPIOMap.ConfirmWrongAnswer();
                        ResetGame();
                        break;
                    }

                    if (_gameInstance.VerifyStep(pressedButtons[0]))
                    {
                        GPIOMap.BlinkLight(pressedButtons[0], 500);
                    }
                    else//Wrong step, end game
                    {
                        GPIOMap.ConfirmWrongAnswer();
                        ResetGame();
                        break;
                    }
                    break;
            }
        }
    }

Как я могу заставить свой исходный код распознавать нажатие кнопки, чтобы я мог перейти к следующему состоянию, которое включает в себя ввод данных пользователем на кнопках.


person imsohateful    schedule 30.11.2016    source источник


Ответы (1)


Вы можете использовать GPIO ValueChanged для перехвата события нажатия кнопки следующим образом:

    _btnBlue = _gpioController.OpenPin(BTNBLUE);
    _btnBlue.ValueChanged += btnValueChanged;

    public void btnValueChanged(GpioPin pin, GpioPinValueChangedEventArgs e)
    {
        if (_btnBlue.Read() == GpioPinValue.Low)
        {
            isBlueButtonPressed = true;
        }
    }
person Rita Han    schedule 01.12.2016