PR

ドットマトリクス(MAX7219)に日本語を表示してみよう【Arduino使用】

Raspberry Pi/電子工作
スポンサーリンク

こんにちは、あろっちです。

8×8ドットマトリクス(MAX7219)に日本語フォント(美咲ゴシック第2)を表示してみます。

本記事では、Arduinoの開発環境がすでに整っていることを前提としています。

参考URL:

8×8ドット日本語フォント「美咲フォント」
スポンサーリンク

準備

使用するもの

  • マイコン (本記事ではSeeed Studio XIAOシリーズ(※)を使用します)
  • ドットマトリクス(MAX7219) LEDディスプレイモジュール
  • ブレッドボード
  • ジャンパーワイヤー

※XIAO RP2040/RP2350/ESP32 C3/ESP32 C6で動作確認しています。

配線について

マトリクス (MAX7219)マイコン (XIAOシリーズ)備考
VCC5V
GNDGND
DIND10デフォルトSPI MOSI
CSD7
CLKD8デフォルトSPI SCK

プログラム (Arduinoスケッチ)

ライブラリのインストール

MAX7219制御ライブラリ

  • MD_MAX72XX
  • MD_Parola

ライブラリマネージャーからインストールできます。

misaki

今回、Arduino環境向けに「美咲ゴシック第2フォント」を収録した日本語フォントライブラリ「misaki」を作成しました。

本記事のプログラムでは、このライブラリを使用します。

以下の記事を参考にArduino環境にインストールしてください。

メッセージを表示する

マトリクスにメッセージ「こんにちは」を表示します。

#include <MD_MAX72xx.h>
#include <MD_Parola.h>
#include <misaki.hpp>

// MAX7219の設定
#define HARDWARE_TYPE MD_MAX72XX::FC16_HW
#define MAX_DEVICES 4

// CSピンの設定
#define CS_PIN D7

// スクロールする文字列の最大長
#define MAX_LENGTH 256

// スクロールする文字列をMD_Parolaに登録するための変数
char messageCode[MAX_LENGTH];

// MD_Parolaに登録するフォントデータを格納するための配列
uint8_t rotatedFontData[9 * MAX_LENGTH];  // 90度回転したフォントデータを格納する領域

// MD_Parolaオブジェクトの作成
MD_Parola parola = MD_Parola(HARDWARE_TYPE, CS_PIN, MAX_DEVICES);

// Parolaに指定した文字列(text)のフォントデータを登録する関数
void addFontToParola(const char* text) {
  uint16_t charIndex = 1;  // 文字列の先頭を1として順番にインデックスを割り当てる
  uint8_t charWidth;

  while (*text && charIndex < MAX_LENGTH) {
    // UTF-8をUnicodeに変換し、文字幅を取得
    uint16_t unicode = utf8ToUnicode(text, &charWidth);

    // フォントデータを取得
    const uint8_t* fontData = getFontData(unicode);

    // フォントデータを90度回転して格納
    // フォントデータの1バイト目は文字幅を格納する
    rotatedFontData[(charIndex - 1) * 9] = charWidth;
    // フォントデータの2バイト目以降は回転したデータを格納する
    for (uint8_t col = 0; col < 8; col++) {  // 8列分のデータを処理
      uint8_t rotatedByte = 0;
      for (uint8_t row = 0; row < 8; row++) {    // 8行分のデータを処理
        if (fontData[row] & (1 << (7 - col))) {  // 元データのビットを確認
          rotatedByte |= (1 << row);             // 回転後の位置にビットをセット
        }
      }
      rotatedFontData[(charIndex - 1) * 9 + col + 1] = rotatedByte;  // 回転したデータを格納
    }

    // MD_Parolaにフォントを登録
    parola.addChar(charIndex, &rotatedFontData[(charIndex - 1) * 9]);
    // フォントデータのインデックスを増加
    messageCode[charIndex - 1] = charIndex;
    charIndex++;  // 次の文字のインデックスを増加
  }
  // 文字列の終端を設定
  messageCode[charIndex - 1] = '\0';
}

void setup() {

  Serial.begin(115200);
  // while (!Serial) delay(10);  // シリアルモニタの準備を待つ

  // MD_Parolaの初期化
  parola.begin();
  parola.displayClear();

  // マトリクスに表示するメッセージ
  const char* message = "こんにちは";

  // フォントデータを登録
  addFontToParola(message);

  // メッセージを設定してスクロール開始
  parola.displayScroll(messageCode, PA_LEFT, PA_SCROLL_LEFT, 50);
}

void loop() {
  // アニメーションを更新
  if (parola.displayAnimate()) {
    parola.displayReset();
    delay(1500);
  }
}

シリアルから入力された文字列を表示する

シリアルモニターから入力した文字列が、マトリクスにスクロール表示されます。

#include <MD_MAX72xx.h>
#include <MD_Parola.h>
#include <misaki.hpp>

// MAX7219の設定
#define HARDWARE_TYPE MD_MAX72XX::FC16_HW
#define MAX_DEVICES 4

// CSピンの設定
#define CS_PIN D7

// スクロールする文字列の最大長
#define MAX_LENGTH 256

// スクロールする文字列をMD_Parolaに登録するための変数
char messageCode[MAX_LENGTH];

// MD_Parolaに登録するフォントデータを格納するための配列
uint8_t rotatedFontData[9 * MAX_LENGTH];  // 90度回転したフォントデータを格納する領域

// MD_Parolaオブジェクトの作成
MD_Parola parola = MD_Parola(HARDWARE_TYPE, CS_PIN, MAX_DEVICES);

// Parolaに指定した文字列(text)のフォントデータを登録する関数
void addFontToParola(const char* text) {
  uint16_t charIndex = 1;  // 文字列の先頭を1として順番にインデックスを割り当てる
  uint8_t charWidth;

  while (*text && charIndex < MAX_LENGTH) {
    // UTF-8をUnicodeに変換し、文字幅を取得
    uint16_t unicode = utf8ToUnicode(text, &charWidth);

    // フォントデータを取得
    const uint8_t* fontData = getFontData(unicode);

    // フォントデータを90度回転して格納
    // フォントデータの1バイト目は文字幅を格納する
    rotatedFontData[(charIndex - 1) * 9] = charWidth;
    // フォントデータの2バイト目以降は回転したデータを格納する
    for (uint8_t col = 0; col < 8; col++) {  // 8列分のデータを処理
      uint8_t rotatedByte = 0;
      for (uint8_t row = 0; row < 8; row++) {    // 8行分のデータを処理
        if (fontData[row] & (1 << (7 - col))) {  // 元データのビットを確認
          rotatedByte |= (1 << row);             // 回転後の位置にビットをセット
        }
      }
      rotatedFontData[(charIndex - 1) * 9 + col + 1] = rotatedByte;  // 回転したデータを格納
    }

    // MD_Parolaにフォントを登録
    parola.addChar(charIndex, &rotatedFontData[(charIndex - 1) * 9]);
    // フォントデータのインデックスを増加
    messageCode[charIndex - 1] = charIndex;
    charIndex++;  // 次の文字のインデックスを増加
  }
  // 文字列の終端を設定
  messageCode[charIndex - 1] = '\0';
}

void setup() {
  Serial.begin(115200);
  // while (!Serial) delay(10);  // シリアルモニタの準備を待つ

  // MD_Parolaの初期化
  parola.begin();
  parola.displayClear();
}

void loop() {
  static String message;

  // アニメーションを更新
  if (parola.displayAnimate()) {
    // アニメーションがない場合シリアルからの入力を待つ
    if (Serial.available()) {
      // シリアルからの入力を読み取る
      message = Serial.readStringUntil('\n');

      // シリアルから入力された文字列をMD_Parolaに登録する
      addFontToParola(message.c_str());

      // メッセージを設定してスクロール開始 messageCodeにはaddFontToParolaで登録した文字列のMD_Parolaのコード(先頭から順番に1,2,3...が入っている)が入っており、それを渡す
      parola.displayScroll(messageCode, PA_LEFT, PA_SCROLL_LEFT, 50);
    }
  }
}

まとめ

ドットマトリクスに日本語を表示するのは、ずっと挑戦してみたかったことでしたが、既存のArduinoライブラリを活かす形で実現することができました。

関連記事

当ブログのマイコン記事です。ぜひご覧ください。

コメント

タイトルとURLをコピーしました