フォト
2024年9月
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30          
無料ブログはココログ

« MSX用カートリッジ 「Mapper Megaram」を入手しました | トップページ | FUSION-C、MSXの開発環境? »

2019年1月20日 (日)

4連8x8ドットLEDマトリックスを試してみる 続々編

4連8x8ドットLEDマトリックスを試してみる 続編」で質問があり、
前回のプログラムを少し修正して、4連8x8ドットLEDマトリックスモジュール
3連結、4連結をやってみました。

今回は、手持ちのSDカードシールド(SDカード・ロガーシールド)を利用しました。
前回のバージョンで未対応だった、16ドット以外のフォント、半角フォントに対応しました。

3連結 (24ドットフォントで表示)

Dscn9456

4連結(24ドットフォントで表示)

Dscn9460

4連結の2x2バージョン (16ドットフォントで表示)

Dscn9449

3連結 バージョンの動いている様子(動画)



4連結 2x2バージョンの動いている様子(動画)



実際の利用では、モジュールをキッチリと並べる必要があります。
それと、4連結 2x2の場合、横に結合する必要があるのですが、
私の所有しているものは、隙間が空きます。結合のために加工が必要そうです。


今回作成したスケッチ(プログラム)  ダウンロード max7219_test4.zip (6.5K)

いくつかのファイルに別れますが、取りあえずメイン部はこんな感じです。
コンパイルには別途、下記の必要です。
  ・sdfonts : Arduino用漢字フォントライブラリ SDカード版
    https://github.com/Tamakichi/Arduino-KanjiFont-Library-SD
   (SDカードには上記サイトに記載のフォントファイルを入れておく必要があります)

// max7219_test4.ino
// MAX7179ドライバーライブラリ動作チェック 4連マトリックスx最大4連結対応
// 2019/01/20 たま吉さん

#include <string.h>
#include <sdfonts.h>

#include "MAX7219_matrix.h"
#include "libmatrix.h"

// MAX7219接続
#define MAX7219_DIN   2 // DIN
#define MAX7219_CLK   4 // CLK
#define MAX7219_LOAD  3 // LOAD(CS)

// SDカード接続
#define MOSI_SD   11    // SDカードのMOISへ接続
#define MISO_SD   12    // SDカードのMISOへ接続
#define CLK_SD    13    // SDカードのCLKへ接続
#define CS_SD     10    // SDカードモジュールCSへ接続

// LEDマトリックスの定義(下記のうちとれか1つを1にして選択)
#define MODULE1x2  1    // 4連モジュール 横1x縦2 (横32x16ドット)
#define MODULE1x3  0    // 4連モジュール 横1x縦3 (横32x24ドット)
#define MODULE1x4  0    // 4連モジュール 横1x縦4 (横32x32ドット)
#define MODULE2x2  0    // 4連モジュール 横2x縦2 (横64x16ドット)

#if MODULE1x2 
#define   SCREENS   8   // MAX7219カスケード接続数
#define  SC_WIDTH  32   // マトリック表示横ドット数
#define  SC_HIGHT  16   // マトリック表示縦ドット数
#elif MODULE1x3
#define  SCREENS   12    // MAX7219カスケード接続数
#define  SC_WIDTH  32   // マトリック表示横ドット数
#define  SC_HIGHT  24   // マトリック表示縦ドット数
#elif MODULE1x4
#define  SCREENS   16    // MAX7219カスケード接続数
#define  SC_WIDTH  32   // マトリック表示横ドット数
#define  SC_HIGHT  32   // マトリック表示縦ドット数
#elif MODULE2x2
#define  SCREENS   16   // MAX7219カスケード接続数
#define  SC_WIDTH  64   // マトリック表示横ドット数
#define  SC_HIGHT  16   // マトリック表示縦ドット数
#endif

// 表示設定
#define  BRT       1    // LEDの輝度(0~7)
#define Y_POS      0    // フォント表示開始ライン(0~SC_HIGHT)

uint8_t fbuf[SC_WIDTH*SC_HIGHT/8];  // 表示用バッファ

// 表示用バッファを表示
void update_screen() {
  uint8_t* ptr = MAX7219_getBuffer(); 

#if MODULE1x2 || MODULE1x3 || MODULE1x4
  for (uint8_t i=0; i < 8; i++) { // 1個あたりのマトリックスの縦ライン数分のループ
    for (uint8_t j=0; j < SC_HIGHT/8; j++) {
      memcpy(&ptr[i*SCREENS+4*j], &fbuf[i*4+32*(SC_HIGHT/8-j-1)], 4);  
    }
  }
#elif MODULE2x2
  for (uint8_t i=0; i < 8; i++) { // 1個あたりの4連マトリックスの縦ライン数分のループ
    memcpy(&ptr[i*SCREENS+0], &fbuf[i*8+64], 8);
    memcpy(&ptr[i*SCREENS+8], &fbuf[i*8],    8);
  }
#endif
  MAX7219_update();  
}

// デモ
void demo(char *str, uint16_t font_size, uint8_t ypos) {
  uint8_t font[MAXFONTLEN];
  if(SDfonts.open()) {            // フォントのオープン
     Serial.println("Cannot open font's file");
  }
  SDfonts.setFontSize(font_size);    // フォントサイズの設定

  MAX7219_clear();
  while(1) {
    str = SDfonts.getFontData(font, str);  // フォントデータの取得
    if (!str)
      break;
    scrollInFont(fbuf, font, SDfonts.getWidth(), SDfonts.getHeight(),ypos, 30);
  }
  SDfonts.close(); 
}

// 1文字分スクロール挿入表示
void scrollInFont(uint8_t*ptr, uint8_t *fnt, uint8_t fw, uint8_t fh, uint8_t ypos, uint16_t dt) {
  for (int8_t t = 0; t < fw; t++) {
    scrollBitmap(ptr, SC_WIDTH, SC_HIGHT, B0001); // 左スクロール
    clearBitmapAt(ptr, SC_WIDTH, SC_HIGHT, SC_WIDTH-t-1, 0, fw, fh);
    setBitmapAt(ptr, SC_WIDTH, SC_HIGHT, SC_WIDTH-t-1, ypos, fnt, fw, fh);
    update_screen();
    delay(dt);
  }  
}

void setup() {
  Serial.begin(115200);
  if(SDfonts.init(CS_SD)) {     // フォント管理の初期化
     Serial.println("Cannot initialize SDfont library.");
  } else {
     Serial.println("Start.");
  }
  
  // マトリック表示ドライバの初期化
  MAX7219_init(MAX7219_DIN, MAX7219_CLK, MAX7219_LOAD, SCREENS, BRT);
}

void loop() {
  Serial.println("Now looping.");
  MAX7219_clear(); 
  // 文字列, フォントサイズ, フォント縦表示開始位置
#if MODULE1x2||MODULE2x2
  demo("16ドットフォント Saitama! こんにちは埼玉県!熱いぞ!埼玉県!",16, 0); 
  //demo("14ドットフォント Saitama! こんにちは埼玉県!熱いぞ!埼玉県!",14, 1); 
#elif MODULE1x3
  demo("24ドットフォント Saitama! こんにちは埼玉県!熱いぞ!埼玉県!",24, 0);  
#elif MODULE1x4
  demo("24ドットフォント Saitama! こんにちは埼玉県!熱いぞ!埼玉県!",24, 4);  
#endif
  delay(1000);
}

次の定義の変更することで、2連結、3連結、4連結、4連結2x2に対応出来ます

// LEDマトリックスの定義(下記のうちとれか1つを1にして選択)
#define MODULE1x2  1    // 4連モジュール 横1x縦2 (横32x16ドット)
#define MODULE1x3  0    // 4連モジュール 横1x縦3 (横32x24ドット)
#define MODULE1x4  0    // 4連モジュール 横1x縦4 (横32x32ドット)
#define MODULE2x2  0    // 4連モジュール 横2x縦2 (横64x16ドット)

また、demo()関数の引数で表示する文字列、フォントサイズ、フォントの縦位置を指定出来ます。
SDカードからフォント読み出しが若干遅い影響で、スクロールにおいてカクカク感があります。
SDfatに変更、フォントライブラリをフラシュメモリ版に変更で改善は出来るとは思いますが、
とりあえず、これで良しとします。

fbufは単純な表示用バッファで、バッファ更新後にupdate_screen()関数を呼び出すことで 表示に反映されます。
Adafruit_GFX_Libraryを使って派生クラスを実装すれば、比較的簡単に
グラフィック描画処理も追加出来ると思います。

この続編で、Arduino用Bitmap画像ロードライブラリsdbitmap を使って、
SDカードに保存したWindowsビットマップファイルを表示なんかも試してみたいと思います。

色々と試しましたが、縦に2個連結がちょうど良い感じです。


関連記事
・4連8x8ドットLEDマトリックスを試してみる 続々編 (この記事です)
4連8x8ドットLEDマトリックスを試してみる 続編
4連8x8ドットLEDマトリックスを試してみる

« MSX用カートリッジ 「Mapper Megaram」を入手しました | トップページ | FUSION-C、MSXの開発環境? »

arduino」カテゴリの記事

表示器制御関連」カテゴリの記事

コメント

最大で何個まで連結できるなどといった上限はありますでしょうか?

かまぞうさん

ブログのサンプルプログラムでは、4個(16個のLEDマトリックス)ですが、
LEDマトリックスを制御するMAX7279的には連結の制約は無いと思われます。

現実的な制約としては、
1)表示更新時間の遅さをどこまで許容するか
2)電源供給をどこまで準備出来るか
とおもわれます。

1)の関連するパラメタを
・人間が表示更新時間にちらつきを感じる限界を1/60秒
・MAX7279の最大データ転送速度は10Mビット/秒 Arduinoの能力的に 2Mビット/秒
・1個当たりのLEDマトリックスのデータ量 64ビット

とすると

表示可能個数 = 2Mビット/秒 × 1/60 秒 ÷ 64 = 520 個
となります。 このあたりの個数が限界だと思います。

2)電源については、1個あたりの消費電力を測定し、
Arduinoから直接取得できる容量に耐えられる個数、
外部電源を確保した場合の容量に耐えられる個数、
までとなると思います。
利用しているLEDマトリックスや、設定輝度により最大個数は変わるので
実測しないとわかりません。




たま吉さん、こんにちは。 素人のわたしが探していた内容の記事を掲載いただきありがとうございます。 max7219_test4.ino を試してみました。 SDfonts.open のところと、SDfonts.init のところで、NG時のシリアルコメント出力のところが逆になっていたようなので、変更のうえ、 MODUL1x2 と  MODUL2x2 について試してみました。 MODUL1x2のほうは完璧に動作しており感激しました。 MODUL2x2のほうは、うまくいかないようです。 右端一文字分は初めに正しく表示されるのですが、上段8x16ドット(縦x横)の文字分だけ左にスクロールするときにフォントが化けてコピーされているようで、正しく表示されません。 もし修正する方法などお教えいただければ幸いです。 いろいろ試してみましたがうまくいきませんでした。 以上です。

HulkNakamuraさん

ご連絡、ありがとうございます。
私も素人です。最初は1つのLEDの点灯すら制御出来なかったですね~(電流制御抵抗って何?)

フォントが化ける件はもう少し状況を分析し、原因を追究しないと、修正対策が行いないです。
利用しているSDカード、SDカードモジュール、電力不足、ソフトウェア以外の原因も考えられます。

不具合切り分けの、フォントが正しく読めているかどうかの判定について、こちらで方法を調べてみます。

たま吉さん、ご返信いただきありがとうございます。 私の場合 Arduinoって何?から始まり、 Arduino Micro から始め、Webの記事で最も多く使われている Unoとのピン番号の相関などに悩み、遠回りをして今回正規版のUnoを使用してみました。 SDカードからの読み出しについては、MODULE1x2 で正常に表示されているので、正常に読み出しているようですが、MODULE2x2でいきずまりました。 大変お手数でもし分けないのですが、どうぞよろしくお願いいたします。
ちなみに、IDEは1.8.13を使用しており、SDカードリーダーはHiLetgoのMicroSD TFカードメモリシールドモジュールを使用して、SDカードは、MicroSDHC8GB(FAT32でフォーマット)でsdfontsの指示通りにフォントファイルを書き込みました。  カードリーダーの電源は、Unoの5V電源を使用し、LEDモジュール(Max7219)の5V電源は電力不足を恐れて別電源で供給しています。

たま吉さん、とても面白くためになる記事を投稿して頂きありがとうございます。
私も埼玉県在住なのでとても親近感を感じます。
私は、今 Raspberry Pi Pico と、MAX7219 8x8 LEDマトリックス(32x16) を買いまして、 MicroPython で、この記事のことを出来ないものか、ネットを巡っています。
C言語は昔かじっただけで、今は Pythonを勉強しながら仕事しています。

たま吉さんの見解を聞かせて頂きたいのですが。Python でこの記事のコードを書き換えるのは、簡単ですか?、それとも冗長になったり不都合なことがあると考えますか?

ジョンブロさん

Raspberry Pi PicoのMicroPythonにて、16x16ドットマトリックスのNeoPixcelで文字表示をやってみた感じでは、
そんなに難しくないと思います。処理速度、メモリ容量と問題ないと思います。

MAX7219の制御は、ざっと調べると下記の記事が参考になるかもしれません。
・MAX7219 LED Dot Matrix Display with Raspberry Pi Pico
https://microcontrollerslab.com/max7219-led-dot-matrix-display-raspberry-pi-pico/

漢字フォントは私が以前作成したライブラリが使えるかもしれません

・ Raspberry Pi Pico MicroPython用のマルチフォントライブラリ
https://nuneno.cocolog-nifty.com/blog/2023/02/post-730291.html

・Neopixel 16x16ドットマトリックス マルチフォントライブラリ テスト表示デモプログラム
https://github.com/Tamakichi/pico_MicroPython_Multiifont/blob/main/sample_mfont_neopixel.py

コメントを書く

(ウェブ上には掲載しません)

トラックバック


この記事へのトラックバック一覧です: 4連8x8ドットLEDマトリックスを試してみる 続々編:

« MSX用カートリッジ 「Mapper Megaram」を入手しました | トップページ | FUSION-C、MSXの開発環境? »