かみやんの技術者ブログ

主にプログラムの話です

.net frameworkで、ジョイパッド入力

次に、ジョイパッドの情報を取り込む機能を追加した。
このページを参考にした。というかコピペ。

        //ジョイパッドの初期化
        private void InitializeJoypad()
        {
            foreach ( DeviceInstance di in
                Manager.GetDevices( DeviceClass.GameControl, EnumDevicesFlags.AttachedOnly))
            {//ジョイパッドを列挙して最初のジョイパッドのインスタンスを作る
                joypad = new Device(di.InstanceGuid);
                break;
            }
            if (joypad == null)
            {//みつからないとき
                AppendText("No joypad found.\n");
                return;
            }
            foreach (DeviceObjectInstance doi in joypad.Objects)
            {//ジョイパッドの軸の範囲の設定
                if ((doi.ObjectId & (int)DeviceObjectTypeFlags.Axis) != 0)
                {//軸のある入力のとき
                    joypad.Properties.SetRange(
                        ParameterHow.ById,
                        doi.ObjectId,
                        new InputRange(-100, 100));
                }
            }
            joypad.Properties.AxisModeAbsolute = true;//絶対値
            joypad.SetCooperativeLevel( this, CooperativeLevelFlags.NonExclusive |
                CooperativeLevelFlags.Background);//協調レベルは非排他
            joypad.Acquire(); //補足開始
            joypadTimer.Start();
        }

        //ジョイパッド:タイマーイベント
        private void joypadTimer_Tick(object sender, EventArgs e)
        {
            try
            {
                JoystickState state = joypad.CurrentJoystickState;
                byte[] buttons = state.GetButtons();
                int[] pov = state.GetPointOfView();
                StringBuilder sb = new StringBuilder(20);
                for (int i = 0; i < Math.Min(buttons.GetLength(0), 12); i++)
                {//ボタンのON/OFFを文字列化
                    if (buttons[i] != 0)
                    {
                        sb.Append("O");
                    }
                    else
                    {
                        sb.Append("-");
                    }
                }
                lblJoypad.Text = "Joypad:Lx=" + state.X + " Ly=" + state.Y
                    + " Rx=" + state.Z + " Ry=" + state.Rz
                    + " pov=" + pov[0] + " " + sb;
                if (isMicroComputerRunning)
                {//マイコンのプログラムが走っているとき
                    SendJoypad(state.X, state.Y);
                }
            }
            catch (InputLostException)
            {
                AppendText("Error:Joypad lost.\n");
                joypad = null;
                joypadTimer.Stop();
            }
            catch (Exception ex)
            {
                AppendText("Error:" + ex.Message+"\n");
                joypad = null;
                joypadTimer.Stop();
            }
        }


つながっているジョイパッドを列挙して、最初のジョイパッドをインスタンス化。
あとは、50msごとに呼ばれるタイマーイベントで、値の取得。
取得した値は、ステータスバーのラベルに表示。

次は、マイコン側のプログラムで、シリアル受信モジュールを書いて、ジョイパッドの指示に従ってモータを回す処理かな。シリアル受信モジュールもライブラリを持ってないから超低レベルから書かないといけないから、ちょっと面倒そう。
プロトコルとしては、PCからマイコンへの送信は、バイナリは確定。マイコンからPCへの送信は、テキストにするか、バイナリにするか、迷い中。