SSブログ

16x8マトリックスLED 第二弾 その1 [Arduino]

あけましておめでとうございます。

昨年末には、Arduino 1.0 が登場したようですが、、
http://arduino.cc/en/Main/Software

ATtinyを使った開発を続けたいので、いまだに Arduino 0021 を使っています。

今回もATtiny2313を使います。
以前に 8x8 マトリックスLEDを2個使った電光掲示板を作成しましたが、これをATtiny2313でやってみました。

前回苦労した配線にすこしアイデアを加えてみました。

aitendo@shopping~楽しい電子工作を提案する
http://www.aitendo.co.jp/

こちらでは、同じサイズ、色でアノードコモンとカソードコモンをペアでそろえることができるタイプがあります。
今回は一番お値打ちな、0.8インチ角、赤でそろえてみました。
ペアで使用すると、それぞれのLEDの同じピン同士を接続するだけでよく、配線が見やすくなるという算段です。

ATtiny2313は足の配置がよく、マトリックスLEDを使うのに非常に適した感じです。I/Oピンは17本あり残りの1本はデータの入力に使います。残念なことにシリアル入力ピンを残したかったので、すこしだけ配線が遠回りになりました。
電源の確保や、ATtiny2313自体のプログラミング、今後のシリアル通信のことも考え、シールド仕立てにしました。

new_matrix_fig.png
new_matrix_front.jpg
new_matrix_back.jpg

LEDマトリックスのソケットは、ピンソケットではゆるゆるになるので、IC用の丸ピンソケットにしました。
またATtiny2313は、高さや、取り外しの問題もあるので直付けにしました。
今後のシリアル入力については、ArduinoについているFT232RLからの出力をATtiny2313に入力するか、ATmega328からの出力をATtiny2313に入力するかの選択用のジャンパピンもつけました。
Arduinoのデジタル10~13の真横にATtiny2313のプログラミングのためのソケットをつけました。プログラミング時には、まず、ArduinoにArduinoISPのスケッチを描き込み、ライターにします。続いて、シールドのデジタル10~13ピンをそれぞれ真横のソケットにワイヤーで接続します。

new_matrix_on.jpg
いつもの、、

Areduino IDEで ATtiny/ATmega 開発環境を作る
http://www.geocities.jp/arduino_diecimila/use/arduino_dev.html

の通りに、ATtiny2313に書き込みを行います。
サンプルスケッチは次の通りです。
// 電光掲示板(心電図っぽいもの)
  // ATtiny2313 のピンとマトリックスLEDの対応配列(0xD0 なら ポートはPD0ということにした)
    // ATtiny2313の足の配置からは、PD0をマトリックスLEDの1番ピンにするといいけど
    // PD0 をシリアル受信用に使う予定のため、PD6をマトリックスLEDの1番ピンにしてみた。
const byte pin_matrixCol[8] = { 0xB4, 0xA1, 0xA0, 0xB1, 0xD3, 0xB2, 0xB6, 0xB7};  // Matrxの列のポート
const byte pin_matrixRow[8] = { 0xB0, 0xB5, 0xD5, 0xB3, 0xD6, 0xD4, 0xD1, 0xD2};  // Matrxの行のポート
byte matrixImage[16] = {        // イメージの配列(心電図)
  0b00100000,  0b00010000,  0b00100000,  0b01000000,  0b00111100,  0b00001111,  0b01110000,  0b10000000,
  0b01100000,  0b00100000,  0b00010000,  0b00100000,  0b00100000,  0b00100000,  0b00100000,  0b00100000};
byte matrixIndex;               // イメージの表示開始位置
byte pulseRate = 60;            // 脈拍数
long previousMillis = 0;

void setup() {
}

void loop() {
  byte x, y;
  for( x = 0; x < 8; x++ ) {
    for( y = 0; y < 8; y++ ) {
      if ( matrixImage[ ( x     + matrixIndex ) % 16 ] & (1 << y) ) setPixelTn2313( pin_matrixCol[x], pin_matrixRow[y]);
      else setMatrixAllOffTn2313();
      if ( matrixImage[ ( x + 8 + matrixIndex ) % 16 ] & (1 << y) ) setPixelTn2313( pin_matrixRow[y], pin_matrixCol[x]);
      else setMatrixAllOffTn2313();
    }
  }
  setMatrixAllOffTn2313();
  unsigned long currentMillis = millis();
  if(currentMillis - previousMillis > 60000 / pulseRate / 16) {
    previousMillis = currentMillis;
    matrixIndex++;
    matrixIndex %= 16;
  }
}

void setMatrixAllOffTn2313() {    // Tiny2313をすべて入力に(ハイ・インピーダンスに)
  DDRA = B00000000;  PORTA  = B00000000;
  DDRB = B00000000;  PORTB  = B00000000;
  DDRD = B00000000;  PORTD &= B00000001;  // PD0 は RXD (シリアル受信用なので触らず)
}

void setPixelTn2313(byte pin_H, byte pin_L) {  // High と Low のピンを指定することで1ドット点灯
  setMatrixAllOffTn2313();
  switch (pin_H & 0xF0) {
    case 0xA0: DDRA  = 1 << (pin_H & 0x0F);  PORTA  = 1 << (pin_H & 0x0F);  break;
    case 0xB0: DDRB  = 1 << (pin_H & 0x0F);  PORTB  = 1 << (pin_H & 0x0F);  break;
    case 0xD0: DDRD  = 1 << (pin_H & 0x0F);  PORTD |= 1 << (pin_H & 0x0F);  break;
  }
  switch (pin_L & 0xF0) {
    case 0xA0: DDRA |= 1 << (pin_L & 0x0F);  break;
    case 0xB0: DDRB |= 1 << (pin_L & 0x0F);  break;
    case 0xD0: DDRD |= 1 << (pin_L & 0x0F);  break;
  }  
}

高速化のためポート直接操作をしています。また、プログラムの簡便化+明るさの均一化のため、1ドットずつのダイナミック点灯としているのでやや暗めになります。暗くなるので、電流制限抵抗も不要(というか、これ以上暗くなると困る、、)。


しかし、配線をわかりやすくしたとはいえ、1.27mmピッチ基板の配線は2.54mmのものと比べてとっても大変でした。

この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。