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

« HT16K33を使った8x16 LEDドットマトリックスの表示 | トップページ | IchigoJamのファームウェアを0.91に更新しました »

2015年1月18日 (日)

HT16K33を2つ使ってLEDドットマトリックスを制御してみた

前回の続きです。

HT16K33を2つ使用して4つの8x8LEDドットマトリックスの表示を試してみました。

Dscn3524

配線がちょと大変でしたが、結論としては、全く問題無しです。
表示遅れやパターンの波うち等は無いです。
I2C接続なのでArduinoとの接続は4線のみです。
MAX7219よりも使いやすいです。

さらに、データーシートでは5V駆動なのですが、3.3Vでも全く問題無く動きました。
輝度の指定はコマンドで設定するのですが、最低にしても明るいです。

複数利用について
HT16K33(28 SOP-A版)は、個々にI2Cアドレスの設定が出来ます。
下図のように抵抗とダイオードでアドレス設定します。
ダイオードは手持ちの1N4148を利用しました。抵抗は39KΩを持っていなかったので
51KΩを利用しましたが、問題なく動作しました。

01
3ビット分のアドレス領域があるので同時に8個の利用が可能です。
今回使った2つのうち、1つはアドレス指定なし、もう一つはA0に抵抗を接続して
異なるアドレスとしました。

動作の様子



スケッチ

#include <Wire.h>

// アドレス
#define HT_I2C_ADDRESS 0x70

// コマンド
#define HT_CMS_DATA       0x00
#define HT_CMD_SYSSET     0x20
#define HT_CMD_BLINK      0x80
#define HT_CMD_BRIGHTNESS 0xE0

// System Setup レジスタ設定値
#define HT_SYSSET_OSC_ON  1

// Display setup 設定値
#define HT_BLINK_DISPLAY_ON B00000001
#define HT_BLINK_OFF        B00000000
#define HT_BLINK_2HZ        B00000010
#define HT_BLINK_1HZ        B00000100
#define HT_BLINK_05HZ       B00000110

// 表示パターン用バッファ(R16xC8)
uint32_t buff[8];  
uint8_t raw[32];

// テスト用パターン('さ','い','た','ま')
uint8_t font[4][8] = {
  {0x08,0x08,0x7E,0x04,0x24,0x40,0x3C,0x00},  // さ
  {0x00,0x88,0x84,0x82,0x82,0x50,0x20,0x00},  // い
  {0x20,0xF0,0x2E,0x40,0x48,0x50,0x8E,0x00},  // た
  {0x08,0x7E,0x08,0x7E,0x08,0x7C,0x7A,0x00}   // ま
};

// HT16K33の初期化
void ht_init() {
  Wire.begin();

  // #1
  ht_system_Seup(HT_I2C_ADDRESS, HT_SYSSET_OSC_ON);  // システムオシレータをONにする
  ht_display_setup(HT_I2C_ADDRESS,HT_BLINK_OFF) ;    // 点滅表示周期の設定
  ht_setBrightness(HT_I2C_ADDRESS,1);                // 明るさの設定

  // #2
  ht_system_Seup(HT_I2C_ADDRESS+1, HT_SYSSET_OSC_ON);  // システムオシレータをONにする
  ht_display_setup(HT_I2C_ADDRESS+1,HT_BLINK_OFF) ;    // 点滅表示周期の設定
  ht_setBrightness(HT_I2C_ADDRESS+1,1);                // 明るさの設定
}

// SystemSetup Registerの設定
// (システムオシレータのモード設定)
void ht_system_Seup(uint8_t addr, uint8_t p) {
  Wire.beginTransmission(addr);
  Wire.write(HT_CMD_SYSSET | p);
  Wire.endTransmission(); 
} 

// 明るさの設定
void  ht_setBrightness(uint8_t addr, uint8_t p) {
  if (p > 15) p = 15;
  Wire.beginTransmission(addr);
  Wire.write(HT_CMD_BRIGHTNESS | p);
  Wire.endTransmission(); 
}

// Display setup(点滅周期の設定)
void ht_display_setup(uint8_t addr, uint8_t p) {
  if (p > 3) p = 0;
  Wire.beginTransmission(addr);  
  Wire.write(HT_CMD_BLINK | HT_BLINK_DISPLAY_ON | p); 
  Wire.endTransmission();
}

// 表示パターンの送信
void ht_write(void) {
  uint8_t d;
  uint32_t msk;
  uint8_t t;

  // バッファデータを表示用生データに変換する
  msk = 0x00000001;
  t = 0;  
  for (uint8_t x=0; x <32; x++) {
   d = 0;
    for (uint8_t y=0; y < 8; y++) {
      if (msk & buff[y]) {
        d |= _BV(y);
      }
    }
    raw[t] = d;
    msk <<=1;
    t++;
  } 
  
  // HT16K33 #1 にデータ転送
  Wire.beginTransmission(HT_I2C_ADDRESS);
  Wire.write(HT_CMS_DATA);
  for (uint8_t i=0; i<8; i++) {
    Wire.write(raw[i+24]);    
    Wire.write(raw[i+16]);    
  }
  Wire.endTransmission();  

  // HT16K33 #2 にデータ転送
  Wire.beginTransmission(HT_I2C_ADDRESS+1);
  Wire.write(HT_CMS_DATA);
  for (uint8_t i=0; i<8; i++) {
    Wire.write(raw[i+8]);    
    Wire.write(raw[i]);    
  }
  Wire.endTransmission();  
}

// バッファのクリア
void ht_clear_buffer() {
    for (uint8_t i=0; i <8; i++) 
      buff[i] = 0;
}

// 表示のクリア
void ht_clear() {
  ht_clear_buffer();
  ht_write();
}

// バッファの指定座標のON/OFF
void ht_set_dot_buffer(uint8_t x, uint8_t y, uint8_t d) {
  if (d) {
    buff[y] |= 0x80000000 >> x;
  } else {
    buff[y] &= ~(0x80000000 >>x);
  }   
}

// バッファ上の指定座標に8x8パターンをセット
void write_bufat(uint8_t* fptr, uint8_t x, uint8_t y) {
  if (x>32 || y >7)
    return ;     
  for (byte j=y,i=0; i < 8; j++,i++)
    buff[j] |= (((uint32_t)(fptr[i]))<<24) >>x;
}

// バッファ上の指定座標に8x8パターンをセット(負座標指定可能)
void write_bufat2(uint8_t* fptr, int8_t x, int8_t y) {
  if (x>31 || y >7 || x < -7 || y <-7)
    return ;
  for (int8_t i=0,j=y; i < 8; i++,j++) {
    if (j>=0) {
      if (x>=0)
        buff[j] |= (((uint32_t)(fptr[i]))<<24) >>x;
      else 
        buff[j] |= (((uint32_t)(fptr[i]))<<24) <<(-x);      
    }
  }
}

// バッファ左スクロール
void scroll() {
   for (uint8_t i=0; i < 8; i++) {
      buff[i]<<=1;  // 各行を左にシフトする
   }
}

void setup() {
   ht_init();
   ht_clear();
}

void demo_test() {
  ht_clear();
  
  // バッファに"さいたま"のパターンを書き込む
  for (uint8_t i=0; i <4; i++) {
    write_bufat(font[i],i<<3, 0);
  }
    
  ht_write(); // バッファの内容を表示
  delay(500);
  
  // スクロール
  for (uint8_t i=0; i < 32; i++) {
    scroll();    // バッファ内を1ドット左にシフト
    ht_write();  // バッファの内容を表示
    delay(100);
  }  
}

// 指定座標へのパターン書込み
void demo_test2() {
  for (int8_t y=-7; y<8; y++) {
    for (int8_t x=-7; x<32; x++) {
     ht_clear_buffer();
     write_bufat2(font[0],x, y);
     ht_write();  // バッファの内容を表示
     delay(100);
    }
  }  
}  
  
void loop() {
 demo_test();
 delay(1000);  
 demo_test2();
 delay(1000);  
}

回路図は、データーシートのApplication Circuitのまんまなので作ってません。
8x8LEDマトリックス(HSN-0788UR)とHT16K33との配線接続表を作成して
配線しました。

01_2

色々と使えそうです。表示器をモジュール化してみようと思います。

« HT16K33を使った8x16 LEDドットマトリックスの表示 | トップページ | IchigoJamのファームウェアを0.91に更新しました »

arduino」カテゴリの記事

AVR」カテゴリの記事

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

コメント

コメントを書く

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

トラックバック


この記事へのトラックバック一覧です: HT16K33を2つ使ってLEDドットマトリックスを制御してみた:

« HT16K33を使った8x16 LEDドットマトリックスの表示 | トップページ | IchigoJamのファームウェアを0.91に更新しました »