.. note::
こんにちは、SunFounderのRaspberry Pi & Arduino & ESP32愛好家コミュニティへようこそ!Facebook上でRaspberry Pi、Arduino、ESP32についてもっと深く掘り下げ、他の愛好家と交流しましょう。
**参加する理由は?**
- **エキスパートサポート**:コミュニティやチームの助けを借りて、販売後の問題や技術的な課題を解決します。
- **学び&共有**:ヒントやチュートリアルを交換してスキルを向上させましょう。
- **独占的なプレビュー**:新製品の発表や先行プレビューに早期アクセスしましょう。
- **特別割引**:最新製品の独占割引をお楽しみください。
- **祭りのプロモーションとギフト**:ギフトや祝日のプロモーションに参加しましょう。
👉 私たちと一緒に探索し、創造する準備はできていますか?[|link_sf_facebook|]をクリックして今すぐ参加しましょう!
.. _3.1.13_c_pi5:
3.1.13 ゲーム– ノットノット
===========================
はじめに
-------------------
このプロジェクトでは、面白いゲームデバイスを作成し、それを「ノットノット」と呼びます。
ゲーム中、ドットマトリックスはランダムに矢印を更新します。あなたがする必要があることは、矢印と逆方向にボタンを押すことですが、時間内に行わなければなりません。時間切れになるか、矢印と同じ方向にボタンが押されると、あなたはアウトです。
このゲームは本当に逆の思考を鍛えることができ、さあ試してみましょうか?
必要な部品
------------------------------
このプロジェクトでは、以下のコンポーネントが必要です。
.. image:: ../img/list_GAME_14_NotNot.png
:align: center
セットをまとめて購入するのは便利です。以下のリンクから入手できます。
.. list-table::
:widths: 20 20 20
:header-rows: 1
* - 名前
- このキットのアイテム
- リンク
* - Raphael Kit
- 337
- |link_Raphael_kit|
以下のリンクから個別に購入することもできます。
.. list-table::
:widths: 30 20
:header-rows: 1
* - コンポーネントの紹介
- 購入リンク
* - :ref:`cpn_gpio_board`
- |link_gpio_board_buy|
* - :ref:`cpn_breadboard`
- |link_breadboard_buy|
* - :ref:`cpn_wires`
- |link_wires_buy|
* - :ref:`cpn_dot_matrix`
- |link_led_matrix_buy|
* - :ref:`cpn_button`
- |link_button_buy|
回路図
------------------------
============ ======== ======== ====
T-Board Name physical wiringPi BCM
GPIO22 Pin 15 3 22
GPIO23 Pin 16 4 23
SPIMOSI Pin 19 12 MOSI
SPICE0 pin 24 10 CE0
SPISCLK Pin 23 14 SCLK
============ ======== ======== ====
.. image:: ../img/Schematic_notnot.png
:align: center
実験手順
---------------------------------
**ステップ 1**: 回路を組み立てます。
.. image:: ../img/3.1.14game_notnot.png
**ステップ 2**: 実験を開始する前に SPI をオンにしてください。詳細については、:ref:`spi_configuration` を参照してください。
**ステップ 3**: コードのフォルダに移動します。
.. raw:: html
.. code-block::
cd ~/raphael-kit/c/3.1.13/
**ステップ 4**: コードをコンパイルします。
.. raw:: html
.. code-block::
make
**ステップ 5**: 実行可能ファイルを実行します。
.. raw:: html
.. code-block::
sudo ./3.1.13_GAME_NotNot
プログラムが起動すると、ドットマトリックスにランダムで左または右の矢印が表示されます。あなたが行う必要があることは、矢印の反対方向のボタンを押すことで、「√」がドットマトリックスに表示されます。矢印と同じ方向のボタンが押された場合、あなたはアウトとなり、ドットマトリックスに「x」が表示されます。また、新しいボタンを2つ追加するか、ジョイスティックキーと置き換えて上下左右の4方向にすることもでき、ゲームの難易度を上げることができます。
.. note::
実行後に動作しない場合、またはエラーメッセージ「wiringPi.h: No such file or directory」が表示される場合は、 :ref:`install_wiringpi_pi5` を参照してください。
**コード説明**
このCプログラムは、WiringPiライブラリを使用してRaspberry Pi上で動作するよう設計されています。8x8 LEDマトリックスディスプレイをMAX7219ドライバーチップで制御し、ユーザーの操作に2つのボタンを使用します。プログラムはランダムに左または右矢印をLEDマトリックスに表示し、ユーザーは対応するボタンを押す必要があります。正解であればチェックマーク、不正解であればクロスが表示されます。
#. ヘッダーファイル:
* ``wiringPi.h``: WiringPiライブラリを使用してGPIO制御のための関数を提供。
* ``wiringPiSPI.h``: SPI通信のための関数を提供。
* ``stdio.h``: 標準入出力関数( ``printf`` など)。
* ``stdlib.h``: 標準ライブラリ関数( ``rand`` , ``srand`` , ``exit`` など)。
* ``time.h``: 日付と時刻を操作するための関数( ``time`` , ``NULL`` など)。
#. 型定義:
* ``#define uchar unsigned char``: ``uchar`` を ``unsigned char`` の別名として定義。
* ``#define uint unsigned int``: ``uint`` を ``unsigned int`` の別名として定義。
#. 定数とマクロ:
* ``SPI_CHANNEL``: 通信に使用するSPIチャネル(0または1)。
* ``SPI_SPEED``: SPI通信速度を1 MHzに設定。
* ``AButtonPin``: ボタンAのWiringPiピン番号(GPIO 22)。
* ``BButtonPin``: ボタンBのWiringPiピン番号(GPIO 23)。
#. グローバル変数:
* ``int stage = 0;``: ゲームの現在のステージを追跡(矢印の表示または結果の表示)。
#. データ配列:
* ``uchar arrow[2][8]``: LEDマトリックスに表示する右矢印と左矢印の2つの8バイトパターンを含む。
* ``arrow[0]``: 右矢印パターン。
* ``arrow[1]``: 左矢印パターン。
* ``uchar check[2][8]``: 正解(チェックマーク)と不正解(クロス)の2つの8バイトパターンを含む。
* ``check[0]``: 正解記号パターン。
* ``check[1]``: 不正解記号パターン。
#. ``void Delay_xms(uint x)`` 関数:
* WiringPiで提供される ``delay(x)`` のラッパー関数。
* プログラムの実行を ``x`` ミリ秒遅延させる。
#. ``void Write_Max7219_byte(uchar DATA)`` 関数:
* MAX7219に1バイトのデータ( ``DATA`` )をSPI経由で送信。
* ``wiringPiSPIDataRW`` を使用してSPIデータ転送を実行。
* ``DATA``: 送信するデータバイト。
#. ``void Write_Max7219(uchar address1, uchar dat1)`` 関数:
* MAX7219にコマンドとデータを送信。
* ``address1``(レジスタアドレス)と ``dat1`` (データ)をバッファに結合し、SPI経由で送信。
* ``address1``: MAX7219レジスタのアドレス。
* ``dat1``: レジスタに書き込むデータ。
#. ``void Init_MAX7219()`` 関数:
* MAX7219ディスプレイドライバを必要な設定で初期化。
* デコードモード、輝度、スキャンリミット、シャットダウンモード、およびディスプレイテストを設定。
* ディスプレイ上の以前のデータをクリア。
#. ``void Init_WiringPi()`` 関数:
* WiringPiライブラリとSPIインターフェースを初期化。
* ボタンピンを入力として設定し、プルアップ抵抗を使用。
* 初期化が成功したかを確認し、失敗した場合は終了。
#. ``int get_index()`` 関数:
* 左右の矢印を選ぶためのランダムなインデックス(0または1)を生成。
* 戻り値: ``0`` または ``1``。
#. ``int get_key(uint num)`` 関数:
* ユーザーがボタンを押すのを待ち、入力が表示された矢印に一致するかどうかを判断。
* パラメータ:
* ``num``: 表示された矢印のインデックス(右は0、左は1)。
* 戻り値:
* ``1``: ユーザーの入力が正しい場合。
* ``0``: ユーザーの入力が間違っている場合。
* 機能:
* ボタンの状態を確認する無限ループに入り、 ``digitalRead`` でボタン押下(アクティブLOW)を検出。
* ``num`` に基づいて予想される入力と押されたボタンを比較。
#. ``void display(uint index)`` 関数:
* ``stage`` に基づいてLEDマトリックスに矢印または結果記号を表示。
* パラメータ:
* ``index``: ``arrow`` または ``check`` 配列からパターンを選択するためのインデックス。
* 機能:
* ``stage == 0`` の場合、矢印パターンを表示。
* ``stage == 1`` の場合、チェックマークまたはクロス記号を表示。
#. メイン関数:
* **初期化:**
* ``srand((unsigned)time(NULL))`` でランダム数生成器を初期化。
* ``Init_WiringPi()`` を呼び出し、GPIOとSPIを設定。
* ``Init_MAX7219()`` を呼び出し、LEDマトリックスディスプレイを初期化。
* ``Delay_xms(50)`` で短い遅延を挿入。
* **ゲームループ (``while (1)``):**
* **ステージ0 (矢印の表示):**
* ``get_index()`` を呼び出し、ランダムに矢印方向を選択。
* ``display(direction)`` を呼び出し、LEDマトリックスに矢印を表示。
* ``stage = 1`` を設定して次のステージに移行。
* **ステージ1 (ユーザー入力を取得し、結果を表示):**
* ``get_key(direction)`` を呼び出し、ユーザー入力を待機し、正確性を判断。
* ``display(key)`` を呼び出し、結果記号(チェックマークまたはクロス)を表示。
* ``Delay_xms(1000)`` で1秒待機し、ユーザーが結果を確認できるようにする。
* ``stage = 0`` を設定してループを再スタート。
**プログラムフロー概要:**
1. **セットアップ:**
* WiringPiとSPIを初期化。
* ボタンピンとMAX7219の設定を構成。
* ランダム数生成器を初期化。
2. **矢印の表示:**
* 左右の矢印方向をランダムに選択。
* 対応する矢印をLEDマトリックスに表示。
3. **ユーザー操作:**
* ユーザーがボタンAまたはボタンBを押すのを待機。
* 押されたボタンが矢印方向と一致するかを判断。
4. **結果の表示:**
* ユーザーの入力が正しい場合はチェックマークを表示。
* ユーザーの入力が間違っている場合はクロスを表示。
* 次のラウンドまで1秒待機。
5. **繰り返し:**
* 新しい矢印を表示してゲームを続行。