実行例
実行例

【1】はじめに

1年ぶりの記事投稿です。
過去2回の記事では8x8 LEDマトリックスをRaspberry PiのGPIO経由で制御しました。
今回は、新たに秋月電子の「MAX7219使用赤色ドットマトリクスLEDモジュール」を使用します。
これは8x8 LEDマトリックスを4つつなげ8x32 LEDマトリックスにしたもので、マキシム社のLEDディスプレイドライバICであるMAX7219を使用したモジュールになっています。
MAX7219に信号を入力することで個別のLEDの点灯制御ができます。
最終的には漢字のスクロール表示を目指しますが、今回の記事ではシンプルに「////」と「\\\\」を交互に表示することを目指します
また、プログラム言語はC言語(gcc)を使用します。

【2026/03/22補足】現在秋月電子では取り扱っていないようです。他のショップで同様にMAX7219を使用したマトリックスLEDは販売されていますので、そちらを流用してみて下さい。

【2】回路

今回購入したのモジュールは、MAX7219が組み込まれたモジュールになっているため、LEDの各端子を直接制御するのではなく、SPI(Serial Peripheral Interface)という、シリアルインタフェースを使用して制御することになります。
このため、接続に必要な線はわずか5本です。
モジュールに付属しているケーブルで接続できるため、Raspberry Pi側にヘッダピンを立てていれば、ブレッドボードや、半田付けは不要になっています。
接続図を以下に示します。

接続図

SPIはクロックと同期してデータを転送するシリアル規格でありIC間のデータ転送に使われます。
類似の規格であるI2Cにくらべ高速にデータが転送できます。
Raspberry Piのコネクタは、標準ではGPIOとして使用しますが、専用ツールによるモード設定により、一部のピンをSPIインタフェース用の信号線に変更することができます。

【3】Raspberry Piの設定変更(SPI有効設定)

前述の通り、Raspberry PiでSPI接続するためには、設定を変更する必要があります。
/boot/config.txtの設定で変更できますが、直接編集するのではなく、ツールを使用して変更します。
GUI(Grafical User Interface)画面の左上の「メニュー」ボタンをクリックして、リストの中から「設定」→「Raspberry Piの設定」とクリックします。
「インタフェース」タブを選択し、「SPI」を有効に設定します。

Raspberry Piの設定画面

GUIを使えない場合(CLIしか使用できない場合)は、コンソールから「sudo raspi-config」と起動してください。
同様に設定することができます。

【4】SPIライブラリロード

Raspberry PiのSPIには複数のライブラリがあるようですが、ネットで調べたところメジャーなwiringPiを使用することにしました。wiringPi自体はGPIOのライブラリですが、SPIも扱うことができます。
wiringPiの説明によると、予めコンソールで、以下のコマンドを実施する必要があります。

gpio load spi

私の使用した環境(Raspberry Pi Zero WH)では上記コマンドを実施すると以下のようなメッセージが出てきました。

gpio: Unable to load/unload modules as this Pi has the device tree enabled. You need to run the raspi-config program (as root) and select the modules (SPI or I2C) that you wish to load/unload there and reboot.

しかし、実際に後述するプログラムは正常動作したため、環境としてはSPIが使えるようになっていました。
表示内容も「このPiではデバイスツリーが有効になっているため、モジュールをロード/アンロードできない」という内容なので、すでにロード済みで固定していたのかもしれません。

【5】SPIへのデータ形式、LEDマトリックスのデータ形式

SPIは送受信できますが、本記事では送信についてのみ記述します(LEDマトリックス制御は、データ送信のみであり、受信は行わないため)。
SPIは、バイトデータ(8bit)をシリアルデータ(1bitデータ列)に変換して送信します。
1バイトのデータを送付するとき、そのバイトデータからシリアルへの変換はMSB(Most Significant Bit:上位ビット)ファーストになります。
例えば、0x12という16進数のバイトデータは、2進数では、00010010bと表現できますが、SPI上はMSBから、0,0,0,1,0,0,1,0の順に送信されます。

今回使用するLEDマトリックスは、8行x32列となっていますが、8行x8列のLEDマトリックスが4個連結されています。
各LEDマトリックスの1行は、16bit(2byte)で指定します。
   LEDマトリックス(1個)の1行 = ①4bit未使用(0000b) + ②4bitアドレス + ③8bitデータ

    ①は、0を指定します
    ②のアドレスは、行を指定します。
     LEDマトリックスのマニュアルに記載されているアドレスはLSB Firstで表現されていますので
     バイトデータで表現すると以下のようになります。

1行目 1000(D8-D11) → 0001b(D11-D8) → 0x01
2行目 0100(D8-D11) → 0010b(D11-D8) → 0x02
3行目 1100(D8-D11) → 0011b(D11-D8) → 0x03
4行目 0010(D8-D11) → 0100b(D11-D8) → 0x04
5行目 1010(D8-D11) → 0101b(D11-D8) → 0x05
6行目 0110(D8-D11) → 0110b(D11-D8) → 0x06
7行目 1110(D8-D11) → 0111b(D11-D8) → 0x07
8行目 0001(D8-D11) → 1000b(D11-D8) → 0x08

    ③のアドレスは、8bitデータを指定します。LEDマトリックスに表示されるビットパターンはMSB/LSBが逆になります
     例えば、0x11は、00010001bですが、LEDマトリックスには、■□□□■□□□と表示されます(■が点灯)。

LEDマトリックスのマニュアルには以下の記載があります。

1 アドレス+データ信号を4回(4基板分)送り、CS信号をL→Hにする事で1行分(8×4=32ドット)分の表示データがMAX7219に記憶されます。 2 この操作を各行分(合計8回)行う事で、1画面分の表示データが送られます。

Raspberry Piは、CE信号(LEDマトリックス側のCS信号)が通常Hになっており、送信中(write中)のみLになります。
このため、特に意識して制御を行わなくても自動的に上記1に記載されている「CS信号をL→Hにする」を行うことになります。
ただし、送信(write)のたびにCE信号が、H→L→Hと遷移するため、1行x4回分(16bitx4)を一度にwriteする必要があります。

【6】LEDマトリックスの初期化

LEDマトリックスのマニュアルには以下のように記載されおり、事前にMAX7219の初期設定をする必要があることがわかります。

アドレス9~Fは、制御レジスタのアドレスです。 表示データを送る前に、制御データを制御レジスタに、送る必要があります。 制御レジスタのデータ内容は、MAX7219の資料をご覧ください。

具体的な設定方法について、MAX7219のデータシートを見てもイメージがつかめないため、秋月電子HPにあるArduinoボード用のサンプルソースを参考にします。
サンプルソースコードを読み解くと、以下の初期化処理をしていることが分かりました。今回、同じ初期化処理を行うことにします。

(1)アドレス0x09 Data=0x00を送信 (2)アドレス0x0a Data=0x04を送信 (3)アドレス0x0b Data=0x07を送信 (4)アドレス0x0c Data=0x01を送信 (5)アドレス0x0f Data=0x00を送信 (6)アドレス0x00 Data=0x00を送信 (shift data) (7)アドレス0x00 Data=0x00を送信 (shift data) (8)アドレス0x00 Data=0x00を送信 (shift data) (9)delay(100) - (1)は「データシート表4」参照:No decode for digits 7-0 - (2)は「データシート表7」参照:輝度 15/32 - (3)は「データシート表8」参照:Display digits 0 1 2 3 4 5 6 7 - (4)は「データシート表3」参照:Normal Operation - (5)は「データシート表10」参照:Normal Operation

【7】ソースコード

test1.c

#include <stdio.h> #include <string.h> #include <wiringPi.h> #include <wiringPiSPI.h> #include <stdint.h> typedef struct { unsigned char adr; unsigned char dat; } _send_data; int main(void) { int fd; static _send_data data[8]; static unsigned char set_data[2]; /* Setup SPI libraly */ wiringPiSetup(); if((fd = wiringPiSPISetup(0,500000)) < 0){ printf("SPI initialize error\n"); return -1; } /* Initialize MAX7219 */ memset((void *)data,0,sizeof(data)); set_data[0] = 0x09, set_data[1] = 0x00; wiringPiSPIDataRW(0,set_data,2); set_data[0] = 0x0a, set_data[1] = 0x04; wiringPiSPIDataRW(0,set_data,2); set_data[0] = 0x0b, set_data[1] = 0x07; wiringPiSPIDataRW(0,set_data,2); set_data[0] = 0x0c, set_data[1] = 0x01; wiringPiSPIDataRW(0,set_data,2); set_data[0] = 0x0f, set_data[1] = 0x00; wiringPiSPIDataRW(0,set_data,2); set_data[0] = 0x00, set_data[1] = 0x00; wiringPiSPIDataRW(0,set_data,2); set_data[0] = 0x00, set_data[1] = 0x00; wiringPiSPIDataRW(0,set_data,2); set_data[0] = 0x00, set_data[1] = 0x00; wiringPiSPIDataRW(0,set_data,2); delay(100); /* Draw LED matrix */ int i,j; loop: for(i=1; i<=8; i++){ for(j=0; j<4; j++){ data[j].adr = i; data[j].dat = 1 << (i-1); } wiringPiSPIDataRW(0,(unsigned char *)data,8); } delay(1000); for(i=1; i<=8; i++){ for(j=0; j<4; j++){ data[j].adr = i; data[j].dat = 0x80 >> (i-1); } wiringPiSPIDataRW(0,(unsigned char *)data,8); } delay(1000); goto loop; }

赤文字部分が、ライブラリのwiringPiを初期化する箇所です。
wiringPiSPISetup ()は、SPIセットアップを行う関数です。
第1引数は、チャネル番号で、第2引数は、転送レートを指定します。
青部分が、LEDマトリックス(のMAX7219)初期化部分です。
内容は、【6】を参照してください。
緑部分が、LEDマトリックスの描画部分になります。
i=1~8は、アドレス(行)を指しています。
j=0~4は、4個あるLEDマトリックスを指しています。LEDdata[j].datは、各LEDマトリックスの1行分のデータを表しています。
wiringPiSPIDataRW()は、送信、受信を行う関数です。
前述のとおり、送信(write)のたびにCE信号が、H→L→Hと遷移するため、1行x4回分(16bitx4)を一度にwriteしています。
緑部分の処理で、「////」と「\\\\」を交互に表示されることになります。

【8】コンパイルと実行

本項では、ソースコードのコンパイルと実行について記載します。
まずは、【7】のソースコードをtest1.cとして保存してください。
次に、同じディレクトリに、以下のMakefileを保存してください。

test1: test1.c gcc -o test1 -lwiringPi test1.c

※「-lwiringPi」が、wiringPiライブラリをリンクする指定になります。

lsコマンドで、Makefileとtest1.cがあることを確認してください。

ls Makefile test1.c

次にmakeコマンドで、コンパイルを実施してください。

make gcc -o test1 -lwiringPi test1.c

lsコマンドで、test1(実行ファイルが)が作成されたことを確認してください。

ls Makefile test1 test1.c

実行は以下のように入力してください。

sudo ./test1

実行を止めるときは、[CTRL]+[C]キーを押してください。


【参考】

秋月電子通商
Wiring Pi


【改訂記録】
2019/06/02版:公開
2026/03/22版:リンク切れ修正、補足追加、レスポンシブ対応

[ホームへ戻る]