プロジェクト 9: 8*16 表情 LED ドットマトリクス

(1)概要:

ロボットに表情ボードを追加したら楽しいと思いませんか?Keyestudio の 8*16 LED ドットマトリクスがその役割を果たします。これを使えば、表情・画像・パターンなど様々なディスプレイを自分でデザインすることができます。

8*16 LED ボードには 128 個の LED が搭載されています。マイクロプロセッサ(Arduino)のデータは、2線式バスインターフェースを介して AiP1640 と通信します。これにより、モジュール上の 128 個の LED のオン・オフを制御し、モジュール上のドットマトリクスに必要なパターンを表示することができます。配線の便宜のために HX-2.54 4Pin ケーブルが付属しています。

(2)仕様:

  • 動作電圧: DC 3.3-5V

  • 消費電力: 400mW

  • 発振周波数: 450KHz

  • 駆動電流: 200mA

  • 動作温度: -40~80℃

  • 通信方式: 2線式バス

(3)知識:

8*16 LED ドットマトリクスの原理

816 ドットマトリクスの各 LED をどのように制御するのでしょうか?1バイトは 8ビットで構成され、各ビットは 0 または 1 です。0 のとき LED は消灯し、1 のとき LED は点灯します。1バイトで LED の1列を制御でき、自然に 16バイトで 16列の LED を制御できます。これが 816 ドットマトリクスの仕組みです。

ピンの説明と通信プロトコル

マイクロプロセッサ(Arduino)のデータは、2線式バスケーブルを介して AiP1640 と通信します。

通信プロトコルの図は以下の通りです(SCLK)は SCL、(DIN)は SDA です。

①データ入力の開始条件: SCL がハイレベルで SDA がハイからローに変化する。

②データコマンドの設定については、以下の図に示す方法があります。

サンプルプログラムではアドレスに自動的に1を加算する方式を選択しており、2進数値は 0100 0000 で対応する16進数値は 0x40 です。

③アドレスコマンドの設定については、以下のようにアドレスを選択できます。

サンプルプログラムでは最初の 00H を選択しており、2進数 1100 0000 は16進数 0xc0 に対応します。

④データ入力の要件として、SCL がハイレベルのときにデータを入力する場合、SDA の信号は変化してはなりません。SCL のクロック信号がローレベルのときのみ、SDA の信号を変化させることができます。データの入力は下位ビットが先で、上位ビットが後になります。

⑤データ送信終了の条件は、SCL がローレベル、SDA がローレベルで SCL がハイレベルになったとき、SDA のレベルがハイになることです。

⑥表示制御として、異なるパルス幅を設定します。パルス幅は以下の図のように選択できます。サンプルでは、パルス幅は 4/16 で、1000 1010 に対応する16進数は 0x8A です。

モジュールツールの使用手順

ドットマトリクスツールはオンライン版を使用し、リンクは次の通りです: http://dotmatrixtool.com/#

①リンクにアクセスすると、以下のようなページが表示されます。

②ドットマトリクスは 8*16 なので、高さを 8、幅を 16 に調整します(下図参照)。

③パターンから16進数データを生成する

以下の図に示すように、マウスの左ボタンを押して選択し、右クリックでキャンセルします。希望のパターンを描き、Generate をクリックすると、必要な16進数データが生成されます。

(4)接続図:

8x16 LED ライトボードの GND、VCC、SDA、SCL は、それぞれ Keyestudio センサー拡張ボードの -(GND)、+(VCC)、A4、A5 に接続し、2線式シリアル通信を行います。

(注意: Arduino の IIC ピンに接続されていますが、このモジュールは IIC 通信用ではありません。ここでの IO ポートは I2C 通信をシミュレートするためのもので、任意の2つのピンに接続することができます。)

(5)テストコード:

笑顔を表示するコード

(注意: コードをアップロードする前に Bluetooth モジュールを接続しないでください。コードのアップロードにもシリアル通信を使用するため、Bluetooth シリアル通信と競合し、アップロードが失敗する可能性があります。)

/*
  Keyestudio Mini Tank Robot V3 (Popular Edition)
  lesson 9.1
  Matrix face
  http://www.keyestudio.com
*/
// モジュールツールから笑顔画像のデータを取得する
unsigned char smile[] = {0x00, 0x00, 0x1c, 0x02, 0x02, 0x02, 0x5c, 0x40, 0x40, 0x5c, 0x02, 0x02, 0x02, 0x1c, 0x00, 0x00};

#define SCL_Pin  A5  // クロックのピンを A5 に設定する
#define SDA_Pin  A4  // データピンを A4 に設定する

void setup() {
  // ピンを OUTPUT に設定する
  pinMode(SCL_Pin, OUTPUT);
  pinMode(SDA_Pin, OUTPUT);
  // 画面をクリアする
  //matrix_display(clear);
}
void loop() {
  matrix_display(smile);  // 笑顔画像を表示する
}
// この関数はドットマトリクスの表示に使用される
void matrix_display(unsigned char matrix_value[])
{
  IIC_start();  // データ送信を開始する関数を使用する
  IIC_send(0xc0);  // アドレスを選択する

  for (int i = 0; i < 16; i++) // 画像データは16文字ある
  {
    IIC_send(matrix_value[i]); // 画像を送信するデータ
  }

  IIC_end();   // 画像のデータ送信を終了する

  IIC_start();
  IIC_send(0x8A);  // 表示制御でパルス幅 4/16 を選択する
  IIC_end();
}

// データ送信開始の条件
void IIC_start()
{
  digitalWrite(SDA_Pin, HIGH);
  digitalWrite(SCL_Pin, HIGH);
  delayMicroseconds(3);
  digitalWrite(SDA_Pin, LOW);
  delayMicroseconds(3);
  digitalWrite(SCL_Pin, LOW);
}

// データ送信終了のサイン
void IIC_end()
{
  digitalWrite(SCL_Pin, LOW);
  digitalWrite(SDA_Pin, LOW);
  delayMicroseconds(3);
  digitalWrite(SCL_Pin, HIGH);
  delayMicroseconds(3);
  digitalWrite(SDA_Pin, HIGH);
  delayMicroseconds(3);
}

// データを送信する
void IIC_send(unsigned char send_data)
{
  for (byte mask = 0x01; mask != 0; mask <<= 1) // 各文字は8桁あり、1つずつ検出される
  {
    if (send_data & mask) { // 各ビット(0 または 1)に応じてハイまたはローレベルを設定する
      digitalWrite(SDA_Pin, HIGH);
    } else {
      digitalWrite(SDA_Pin, LOW);
    }
    delayMicroseconds(3);
    digitalWrite(SCL_Pin, HIGH); // クロックピン SCL_Pin をプルアップしてデータ送信を終了する
    delayMicroseconds(3);
    digitalWrite(SCL_Pin, LOW); // クロックピン SCL_Pin をプルダウンして SDA の信号を変化させる
  }
}

(6)テスト結果:

テストコードのアップロードに成功し、配線図に従って接続し、DIP スイッチを右端に切り替えて電源を入れると、ドットマトリクスに笑顔のパターンが表示されます。

(7)応用プロジェクト:

先ほど学んだモジュールツール http://dotmatrixtool.com/# を使って、ドットマトリクスにスタート、前進、停止のパターンを順番に表示させ、その後パターンをクリアします。時間間隔は 2000 ms です。

モジュールツールから取得したコード:

スタートパターンのコード:

0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80,0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01

前進パターンのコード:

0x00,0x00,0x00,0x00,0x00,0x24,0x12,0x09,0x12,0x24,0x00,0x00,0x00,0x00,0x00,0x00

後退パターンのコード:

0x00,0x00,0x00,0x00,0x00,0x24,0x48,0x90,0x48,0x24,0x00,0x00,0x00,0x00,0x00,0x00

左折パターンのコード:

0x00,0x00,0x00,0x00,0x00,0x00,0x44,0x28,0x10,0x44,0x28,0x10,0x44,0x28,0x10,0x00

右折パターンのコード:

0x00,0x10,0x28,0x44,0x10,0x28,0x44,0x10,0x28,0x44,0x00,0x00,0x00,0x00,0x00,0x00

停止パターンのコード:

0x2E,0x2A,0x3A,0x00,0x02,0x3E,0x02,0x00,0x3E,0x22,0x3E,0x00,0x3E,0x0A,0x0E,0x00

画面クリアのコード:

0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00

テストコード

(注意: コードをアップロードする前に Bluetooth モジュールを接続しないでください。コードのアップロードにもシリアル通信を使用するため、Bluetooth シリアル通信と競合し、アップロードが失敗する可能性があります。)

/*
  keyestudio Mini Tank Robot V3 (Popular Edition)
  lesson 9.2
  Matrix face
  http://www.keyestudio.com
*/

// 配列:画像のデータを保存するために使用。自分で計算するかモジュールツールから取得できる
unsigned char start01[] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01};
unsigned char front[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x12, 0x09, 0x12, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
unsigned char back[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x48, 0x90, 0x48, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
unsigned char left[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x28, 0x10, 0x44, 0x28, 0x10, 0x44, 0x28, 0x10, 0x00};
unsigned char right[] = {0x00, 0x10, 0x28, 0x44, 0x10, 0x28, 0x44, 0x10, 0x28, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
unsigned char STOP01[] = {0x2E, 0x2A, 0x3A, 0x00, 0x02, 0x3E, 0x02, 0x00, 0x3E, 0x22, 0x3E, 0x00, 0x3E, 0x0A, 0x0E, 0x00};
unsigned char clear[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};

#define SCL_Pin  A5  // クロックのピンを A5 に設定する
#define SDA_Pin  A4  // データピンを A4 に設定する

void setup() {
  // ピンを OUTPUT に設定する
  pinMode(SCL_Pin, OUTPUT);
  pinMode(SDA_Pin, OUTPUT);
  // 画面をクリアする
  matrix_display(clear);
}
void loop() {
  matrix_display(start01);  // "Start" 画像を表示する
  delay(2000);
  matrix_display(front);    // "front" 画像を表示する
  delay(2000);
  matrix_display(STOP01);   // "STOP01" 画像を表示する
  delay(2000);
  matrix_display(clear);    // "clear" 画像を表示する
  delay(2000);
}
// この関数はドットマトリクスの表示に使用される
void matrix_display(unsigned char matrix_value[])
{
  IIC_start();  // データ送信を開始する関数を使用する
  IIC_send(0xc0);  // アドレスを選択する

  for (int i = 0; i < 16; i++) // 画像データは16文字ある
  {
    IIC_send(matrix_value[i]); // 画像を送信するデータ
  }

  IIC_end();   // 画像のデータ送信を終了する

  IIC_start();
  IIC_send(0x8A);  // 表示制御でパルス幅 4/16 を選択する
  IIC_end();
}

// データ送信開始の条件
void IIC_start()
{
  digitalWrite(SDA_Pin, HIGH);
  digitalWrite(SCL_Pin, HIGH);
  delayMicroseconds(3);
  digitalWrite(SDA_Pin, LOW);
  delayMicroseconds(3);
  digitalWrite(SCL_Pin, LOW);
}

// データ送信終了のサイン
void IIC_end()
{
  digitalWrite(SCL_Pin, LOW);
  digitalWrite(SDA_Pin, LOW);
  delayMicroseconds(3);
  digitalWrite(SCL_Pin, HIGH);
  delayMicroseconds(3);
  digitalWrite(SDA_Pin, HIGH);
  delayMicroseconds(3);
}

// データを送信する
void IIC_send(unsigned char send_data)
{
  for (byte mask = 0x01; mask != 0; mask <<= 1) // 各文字は8桁あり、1つずつ検出される
  {
    if (send_data & mask) { // 各ビット(0 または 1)に応じてハイまたはローレベルを設定する
      digitalWrite(SDA_Pin, HIGH);
    } else {
      digitalWrite(SDA_Pin, LOW);
    }
    delayMicroseconds(3);
    digitalWrite(SCL_Pin, HIGH); // クロックピン SCL_Pin をプルアップしてデータ送信を終了する
    delayMicroseconds(3);
    digitalWrite(SCL_Pin, LOW); // クロックピン SCL_Pin をプルダウンして SDA の信号を変化させる
  }
}

テストコードのアップロード後、表情ボードにはこれらのパターンが順番に表示され、このシーケンスが繰り返されます。