ドットマトリクスの制御はダイナミック接続の7セグと同じで、8本のカソードのピンでどのラインに表示するかをえらんで、8本のアノードで横1列のどのドットを光らすかを指定する。

dot-matrix

使った部品はOSL641501-ARAというもの。 ピンの説明は第5回 ドットマトリクスLED 第4章 – ダイナミック点灯の仕組みの理解 | Arduino & Android 入門講座、配線は第5回 ドットマトリクスLED 第5章 – 配線図の説明 | Arduino & Android 入門講座に書いてある。

なにをさせようかと、とりあえず電光掲示板でスクロールするもの。フォントは美咲フォントを使ってます。配布しているPC-E500 SCRNJPN.FNT 形式とかX11 BDF 形式、TrueType、Ruputer ELISAR10.FNT、FONTX2のフォーマットをまるで知らなかったため、PNGファイルを2値のバイナリデータに変換してソースに埋め込んだ。

メモリが少ないので、あまり長い文章は出せなかった。フォントも使う文字だけ切り出してる。小さい画面でも美咲フォントは結構読みやすいけど、それは前後のつながりから文字を推測しているからであって、スクロールしてる状態だとちと辛いね…。

ソース:
/*
  8x8 Dot matrix
 */

const uint8_t cathode_pin = 2;
const uint8_t anode_pin = 10;

void clearAnodes() {
  for (uint8_t i = 0; i < 8; ++i) {
    digitalWrite(anode_pin + i, LOW);
  }
}

void showMatrix(const uint8_t* matrix) {
  for (uint8_t i = 0; i < 8; ++i) {
    uint8_t v = *matrix++;
    for (uint8_t j = 0; j < 8; ++j) {
      digitalWrite(anode_pin + j, (v & 1) ? HIGH : LOW);
      v >>= 1;
    }
    digitalWrite(cathode_pin + i, LOW);
    delayMicroseconds(100);

    digitalWrite(cathode_pin + i, HIGH);
    //clearAnodes();
  }
}

uint8_t buffer[8];
const uint8_t* pattern = buffer;

void setPattern(const uint8_t* p) {
  pattern = p;
}

ISR(TIMER2_COMPA_vect) {
  showMatrix(pattern);
}

void setup() {
  for (int i = 0; i < 8; ++i) {
    pinMode(anode_pin + i, OUTPUT);
    pinMode(cathode_pin + i, OUTPUT);
  }

  // f = クロック周波数 / ( 2 * 分周比 * ( 1 + 比較レジスタの値))
  // 分周比=32, 比較レジスタの1値=255 -> f = 16000000 / (2 * 32 * 256) = 976 Hz
  OCR2A = 255; // 255クロックごとに割り込みをかける
  TCCR2B = 0b100; // 分周比を32に設定する
  bitWrite(TIMSK2, OCIE2A, 1); // TIMER2を
}

const uint8_t Font[] = {
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,  // \0
  0x00,0x00,0x00,0x92,0x00,0x00,0x00,0x00,  // …
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,  //  
  0x00,0x00,0x00,0x00,0x00,0x80,0x40,0x00,  // 、
  0x00,0x00,0x00,0x00,0x40,0xa0,0x40,0x00,  // 。
  0x20,0x7c,0x20,0x3c,0x6a,0xb2,0x64,0x00,  // あ
  0x00,0x88,0x84,0x82,0x82,0x50,0x20,0x00,  // い
  0x3c,0x00,0x3c,0x42,0x02,0x04,0x38,0x00,  // う
  0x2a,0x20,0xf4,0x2a,0x4a,0x48,0xb0,0x00,  // が
  0x88,0x88,0xbe,0x88,0x88,0x88,0x10,0x00,  // け
  0x08,0x08,0x7e,0x04,0x24,0x40,0x3c,0x00,  // さ
  0x20,0x20,0x20,0x20,0x20,0x22,0x1c,0x00,  // し
  0x08,0xfe,0x18,0x28,0x18,0x08,0x10,0x00,  // す
  0x24,0x24,0xfe,0x24,0x2c,0x20,0x1e,0x00,  // せ
  0x2a,0xf0,0x2e,0x40,0x48,0x50,0x8e,0x00,  // だ
  0x08,0x7e,0x10,0x1c,0x22,0x02,0x1c,0x00,  // ち
  0x00,0x00,0x00,0x18,0x64,0x04,0x18,0x00,  // っ
  0x0e,0x74,0x08,0x10,0x10,0x08,0x06,0x00,  // て
  0x0e,0x74,0x0a,0x10,0x10,0x08,0x06,0x00,  // で
  0x20,0x20,0x26,0x18,0x20,0x40,0x3e,0x00,  // と
  0x2a,0x20,0x26,0x18,0x20,0x40,0x3e,0x00,  // ど
  0x20,0xf4,0x22,0x44,0x9c,0x26,0x18,0x00,  // な
  0x20,0x2c,0xf2,0x22,0x66,0xaa,0x24,0x00,  // ね
  0x00,0x38,0x54,0x92,0xa2,0x44,0x18,0x00,  // の
  0x84,0x84,0xbe,0x84,0x9c,0xa4,0x9a,0x00,  // は
  0x08,0x7e,0x08,0x7e,0x08,0x7c,0x7a,0x00,  // ま
  0x70,0x10,0x24,0x7c,0xa6,0xc4,0x18,0x00,  // み
  0x10,0x7c,0x20,0x7c,0x22,0x22,0x1c,0x00,  // も
  0x48,0x5c,0xe2,0x24,0x20,0x10,0x10,0x00,  // や
  0x58,0x64,0x44,0x44,0x04,0x08,0x30,0x00,  // り
  0x3c,0x08,0x10,0x3c,0x42,0x32,0x3c,0x00,  // る
  0x10,0x7c,0x20,0x76,0x98,0x28,0x1e,0x00,  // を
  0x10,0x10,0x20,0x20,0x50,0x52,0x8c,0x00,  // ん
  0x00,0x00,0x08,0x7c,0x18,0x68,0x18,0x00,  // ォ
  0x10,0x1e,0x22,0x42,0x04,0x08,0x30,0x00,  // ク
  0x00,0x7c,0x04,0x08,0x08,0x34,0xc2,0x00,  // ス
  0x00,0x00,0x00,0x54,0x54,0x08,0x30,0x00,  // ッ
  0x20,0x20,0x20,0x38,0x24,0x20,0x20,0x00,  // ト
  0x2a,0x20,0x20,0x38,0x24,0x20,0x20,0x00,  // ド
  0x00,0x7e,0x02,0x02,0x04,0x08,0x30,0x00,  // フ
  0x00,0xfe,0x02,0x04,0x28,0x10,0x08,0x00,  // マ
  0x04,0x04,0x74,0x08,0x14,0x24,0xc0,0x00,  // メ
  0x3c,0x10,0x10,0x7e,0x10,0x10,0x0e,0x00,  // モ
  0x44,0x44,0x44,0x44,0x04,0x08,0x30,0x00,  // リ
  0x08,0x28,0x28,0x28,0x2a,0x4c,0x88,0x00,  // ル
  0x00,0x7e,0x42,0x42,0x42,0x42,0x7e,0x00,  // ロ
  0x40,0x20,0x02,0x02,0x04,0x08,0x70,0x00,  // ン
  0x00,0x00,0x80,0x7e,0x00,0x00,0x00,0x00,  // ー
  0x28,0x7e,0xda,0x5e,0x78,0x48,0x76,0x00,  // 使
  0x10,0x54,0x54,0x7c,0x92,0x92,0xfe,0x00,  // 出
  0x5e,0x4a,0xea,0x4a,0x4a,0x6a,0x16,0x00,  // 切
  0x14,0xe0,0xbe,0xa8,0xfe,0x08,0x36,0x00,  // 咲
  0x10,0xfe,0xba,0x08,0xfe,0x10,0x30,0x00,  // 字
  0x10,0x10,0x54,0x52,0x92,0x10,0x30,0x00,  // 小
  0x10,0x54,0x52,0x90,0x34,0x18,0xe0,0x00,  // 少
  0x54,0xf6,0x50,0x74,0x56,0xc8,0xba,0x00,  // 態
  0x10,0xfe,0x28,0x28,0x10,0x28,0xc6,0x00,  // 文
  0x54,0xfe,0x54,0xfe,0xdc,0x7e,0x54,0x00,  // 構
  0x4a,0x48,0xfe,0x48,0xc8,0x54,0x62,0x00,  // 状
  0xfe,0x10,0xba,0xba,0xba,0x82,0xfe,0x00,  // 画
  0x7c,0x00,0xfe,0x10,0x54,0x92,0x30,0x00,  // 示
  0x10,0x7c,0x28,0xfe,0x44,0xfe,0x10,0x00,  // 章
  0x48,0xbe,0x48,0x9c,0x40,0xdc,0x5c,0x00,  // 結
  0x24,0xfe,0x7c,0x10,0xfe,0x10,0xee,0x00,  // 美
  0x10,0x7c,0x10,0xfc,0x2a,0xe4,0x32,0x00,  // 表
  0x48,0xfe,0x08,0xbe,0x22,0xd4,0xe6,0x00,  // 読
  0x10,0x7c,0x28,0xfe,0x10,0x7c,0x10,0x00,  // 辛
  0x3c,0x20,0x38,0x20,0xfe,0x28,0x76,0x00,  // 長
  0xfe,0x10,0xfe,0xaa,0xba,0xaa,0xfe,0x00,  // 面
  0x3c,0x42,0x42,0x3c,0x42,0x42,0x3c,0x00,  // 8
  0x00,0x00,0x44,0x28,0x10,0x28,0x44,0x00,  // x
};

const uint8_t Text[] = {
  69,70,69,38,36,37,40,37,43,34,35,18,56,52,64,60,2,
  39,33,46,37,24,63,51,39,33,46,37,31,48,16,17,25,12,4,2,
  41,42,43,8,54,21,6,23,18,3,5,25,29,67,6,56,61,24,49,13,25,13,32,4,2,
  39,33,46,37,27,3,48,7,56,52,14,9,50,29,49,11,17,25,12,4,2,
  53,10,6,59,68,18,27,63,51,39,33,46,37,24,62,57,65,26,28,12,6,9,20,3,
  35,34,45,47,44,11,17,30,58,55,14,19,15,19,66,6,22,1,2,
  0
};

void scrollDown(uint8_t* buffer, uint8_t pat) {
  memmove(&buffer[1], &buffer[0], 7);
  buffer[0] = pat;
}

uint8_t sliceFontPattern(const uint8_t* font, uint8_t bit) {
  uint8_t pat = 0;
  for (uint8_t i = 0; i < 8; ++i) {
    pat = (pat << 1) | ((font[i] >> bit) & 1);
  }
  return pat;
}

const uint8_t* pstr = Text;
int chr = 0;
uint8_t bit = 0;

void loop() {
  uint8_t pat = 0;
  if (*pstr != 0) {
    uint8_t c = *pstr;
    if (0 <= c && c < sizeof(Font)/8) {
      pat = sliceFontPattern(&Font[c * 8], 7 - bit);
    }
    if (++bit >= 8) {
      bit = 0;
      ++pstr;
      if (*pstr == 0) {
        pstr = Text;
      }
    }
  }
  scrollDown(buffer, pat);
  setPattern(buffer);
  delay(100);
}