.. note::

    こんにちは、SunFounderのRaspberry Pi & Arduino & ESP32愛好家コミュニティへようこそ！Facebook上でRaspberry Pi、Arduino、ESP32についてもっと深く掘り下げ、他の愛好家と交流しましょう。

    **参加する理由は？**

    - **エキスパートサポート**：コミュニティやチームの助けを借りて、販売後の問題や技術的な課題を解決します。
    - **学び＆共有**：ヒントやチュートリアルを交換してスキルを向上させましょう。
    - **独占的なプレビュー**：新製品の発表や先行プレビューに早期アクセスしましょう。
    - **特別割引**：最新製品の独占割引をお楽しみください。
    - **祭りのプロモーションとギフト**：ギフトや祝日のプロモーションに参加しましょう。

    👉 私たちと一緒に探索し、創造する準備はできていますか？[|link_sf_facebook|]をクリックして今すぐ参加しましょう！

.. _py_74hc_788bs:

5.4 8x8ピクセルグラフィックス
=============================

LEDマトリクスは、低解像度のドットマトリクスディスプレイです。これは、模様表示のためにピクセルとして発光ダイオードの配列を使用しています。

これらは、屋外の日光でも見えるほど明るく、一部の店舗、広告板、サイン、および可変メッセージディスプレイ（公共交通機関の車両など）で見ることができます。

このキットで使用されているのは、16ピンを持つ8x8ドットマトリクスです。アノードは行に、カソードは列に接続されています（回路レベルで）、これにより、これら64個のLEDがまとめて制御されます。

最初のLEDを点灯させるには、Row1に高レベルを、Col1に低レベルを供給する必要があります。2番目のLEDを点灯させるには、Row1に高レベル、Col2に低レベルを供給する必要があります。それ以降も同様です。
各行と列のペアを通る電流を制御することで、各LEDを個々に制御して文字や画像を表示できます。

* :ref:`cpn_dot_matrix`
* :ref:`cpn_74hc595`

**必要なコンポーネント**

このプロジェクトでは、以下のコンポーネントが必要です。

全体のキットを購入するのが便利です。リンクは以下です：

.. list-table::
    :widths: 20 20 20
    :header-rows: 1

    *   - 名前	
        - このキットに含まれるアイテム
        - リンク
    *   - ケプラーキット	
        - 450+
        - |link_kepler_kit|

以下のリンクから個別に購入することもできます。

.. list-table::
    :widths: 5 20 5 20
    :header-rows: 1

    *   - SN
        - コンポーネント	
        - 数量
        - リンク
    *   - 1
        - :ref:`cpn_pico_w`
        - 1
        - |link_picow_buy|
    *   - 2
        - Micro USBケーブル
        - 1
        - 
    *   - 3
        - :ref:`cpn_breadboard`
        - 1
        - |link_breadboard_buy|
    *   - 4
        - :ref:`cpn_wire`
        - 数本
        - |link_wires_buy|
    *   - 5
        - :ref:`cpn_dot_matrix`
        - 1
        - 
    *   - 6
        - :ref:`cpn_74hc595`
        - 2
        - |link_74hc595_buy|

**回路図**

|sch_ledmatrix|

8x8ドットマトリクスは、2つの74HC595チップによって制御されています。一方が行を制御し、もう一方が列を制御しています。これら2つのチップはG18〜G20を共有しており、これによりPico WボードのI/Oポートを大幅に節約できます。

Pico Wは一度に16ビットのバイナリ数を出力する必要があります。最初の8ビットは行を制御する74HC595に与えられ、残りの8ビットは列を制御する75HC595に与えられます。これにより、ドットマトリクスが特定のパターンを表示できます。

Q7': 一連の出力ピンで、複数の74HC595を一列に接続するために、別の74HC595のDSに接続されます。


**配線**

回路を組み立てます。配線が複雑なので、ステップバイステップで進めましょう。

**ステップ1:** まず、ブレッドボードにPico W、LEDドットマトリクス、および2つの74HC595チップを挿入します。Pico Wの3.3VとGNDをボードの両側の穴に接続し、次に、2つの74HC595チップのピン16と10をVCCに、ピン13とピン8をGNDに接続します。

.. note::
   上記のFritzing画像では、ラベルがある側が下になっています。

|wiring_ledmatrix_4|

**ステップ2:** 2つの74HC595のピン11を一緒に接続し、次にGP20に接続します。次に、2つのチップのピン12をGP19に、次に、左側の74HC595のピン14をGP18に、ピン9を2番目の74HC595のピン14に接続します。

|wiring_ledmatrix_3|

**ステップ3:** 右側の74HC595は、LEDドットマトリクスの列を制御するためのものです。以下の表でマッピングを参照してください。したがって、74HC595のQ0-Q7ピンは、それぞれピン13、3、4、10、6、11、15、および16にマッピングされています。

+--------------------+--------+--------+--------+--------+--------+--------+--------+--------+
| **74HC595**        | **Q0** | **Q1** | **Q2** | **Q3** | **Q4** | **Q5** | **Q6** | **Q7** |
+--------------------+--------+--------+--------+--------+--------+--------+--------+--------+
| **LED Dot Matrix** | **13** | **3**  | **4**  | **10** | **6**  | **11** | **15** | **16** |
+--------------------+--------+--------+--------+--------+--------+--------+--------+--------+

|wiring_ledmatrix_2|

**ステップ4:** それでは、LEDドットマトリクスのROWを接続しましょう。左側の74HC595は、LEDドットマトリクスのROWを制御します。以下の表でマッピングを参照してください。見ての通り、左側の74HC595のQ0-Q7は、それぞれピン9、14、8、12、1、7、2、および5にマッピングされています。

+--------------------+--------+--------+--------+--------+--------+--------+--------+--------+
| **74HC595**        | **Q0** | **Q1** | **Q2** | **Q3** | **Q4** | **Q5** | **Q6** | **Q7** |
+--------------------+--------+--------+--------+--------+--------+--------+--------+--------+
| **LED Dot Matrix** | **9**  | **14** | **8**  | **12** | **1**  | **7**  | **2**  | **5**  |
+--------------------+--------+--------+--------+--------+--------+--------+--------+--------+

|wiring_ledmatrix_1|

**コード**

.. note::

    * ``kepler-kit-main/micropython`` のパスの下で ``5.4_8x8_pixel_graphics.py`` ファイルを開くか、このコードをThonnyにコピーして、"Run Current Script"をクリックするか、F5キーを押すだけで実行できます。

    * 右下の"MicroPython (Raspberry Pi Pico)"インタプリタをクリックするのを忘れないでください。

    * 詳しいチュートリアルは、 :ref:`open_run_code_py` を参照してください。


.. code-block:: python

    import machine
    import time

    sdi = machine.Pin(18,machine.Pin.OUT)
    rclk = machine.Pin(19,machine.Pin.OUT)
    srclk = machine.Pin(20,machine.Pin.OUT)

    glyph = [0xFF,0xBB,0xD7,0xEF,0xD7,0xBB,0xFF,0xFF]

    # 74HC595にデータをシフト
    def hc595_in(dat):
        for bit in range(7,-1, -1):
            srclk.low()
            time.sleep_us(30)
            sdi.value(1 & (dat >> bit))
            time.sleep_us(30)
            srclk.high()

    def hc595_out():
        rclk.high()
        time.sleep_us(200)
        rclk.low()

    while True:
        for i in range(0,8):
            hc595_in(glyph[i])
            hc595_in(0x80>>i)
            hc595_out()

プログラムを実行すると、8x8ドットマトリクスに **x** グラフィックが表示されます。

**動作原理は？**

ここでは、ドットマトリクスの行と列の信号を提供するために、2つの74HC595を使用しています。
信号を供給する方法は、前の章の ``hc595_shift(dat)`` と同じですが、違いはここでは一度に16ビットのバイナリ数を書き込む必要があることです。
したがって、 ``hc595_shift(dat)`` を二つの関数、 ``hc595_in(dat)`` と ``hc595_out()`` に分割しました。

.. code-block:: python

    def hc595_in(dat):
        for bit in range(7,-1, -1):
            srclk.low()
            time.sleep_us(30)
            sdi.value(1 & (dat >> bit))
            time.sleep_us(30)
            srclk.high()

    def hc595_out():
        rclk.high()
        time.sleep_us(200)
        rclk.low()

次に、メインループで ``hc595_in(dat)`` を二回呼び出し、二つの8ビットのバイナリ数を書き込み、その後 ``hc595_out()`` を呼び出して、ドットマトリクスに特定のパターンを表示します。

ただし、ドットマトリクスのLEDは共通の極を使用しているため、同時に複数の行/複数の列を制御すると、お互いに干渉します（例えば、(1,1)と(2,2)を同時に点灯すると、(1,2)と(2,1)が必然的に一緒に点灯します）。
したがって、一度に一つの列（または一つの行）を活性化し、8回サイクルさせ、残像の原理を使用して、人の目で8つのパターンを統合し、8x8の情報量を含む一対のパターンを得る必要があります。

.. code-block:: python

    while True:
        for i in range(0,8):
            hc595_in(glyph[i])
            hc595_in(0x80>>i)
            hc595_out()

この例では、メイン関数は ``for`` ループをネストしており、 ``i`` が1のとき、最初の行だけが活性化される（制御線のチップが値 ``0x80`` を取得する）と、最初の行の画像が書き込まれる。 
``i`` が2のとき、2行目が活性化され（制御線のチップが値 ``0x40`` を取得する）と、2行目の画像が書き込まれる。そして、8つの出力を完了します。

ちなみに、4桁の7セグメントディスプレイのように、人の目によるちらつきを防ぐために、更新レートを維持する必要があります。そのため、メインループでの余分な ``sleep()`` はできるだけ避けるべきです。

**もっと学ぶ**

``glyph`` を以下の配列に置き換えて、何が表示されるか確認してみてください！

.. code-block:: python

    glyph1 = [0xFF,0xEF,0xC7,0xAB,0xEF,0xEF,0xEF,0xFF]
    glyph2 = [0xFF,0xEF,0xEF,0xEF,0xAB,0xC7,0xEF,0xFF]
    glyph3 = [0xFF,0xEF,0xDF,0x81,0xDF,0xEF,0xFF,0xFF]
    glyph4 = [0xFF,0xF7,0xFB,0x81,0xFB,0xF7,0xFF,0xFF]
    glyph5 = [0xFF,0xBB,0xD7,0xEF,0xD7,0xBB,0xFF,0xFF]
    glyph6 = [0xFF,0xFF,0xF7,0xEB,0xDF,0xBF,0xFF,0xFF]

もしくは、独自のグラフィックを描いてみてください。
