フォト
2019年7月
  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 31      
無料ブログはココログ

« 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マトリックスや、設定輝度により最大個数は変わるので
実測しないとわかりません。




コメントを書く

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

トラックバック


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

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