8x8 BiColor LED Matrix

使用デバイス

今回はAdafruitの8x8 BiColor LED Matrix(https://www.adafruit.com/product/902)の制御を行ってみます。

https://learn.adafruit.com/adafruit-led-backpack/bi-color-8x8-matrix

デバイスとPSoC 5LPの接続

以下のようにI2C_0ポートを拡張し接続しました。

ピン接続

デバイスの制御

Adafruitのサンプルコードはこちら。https://github.com/adafruit/Adafruit_LED_Backpack

Displayのメモリについては少しトリッキーです。

上記表の意味をサンプルを例に説明します。これは、Addressの0x00はgreenのLEDマトリクスの1列目、Addressの0x01はredのLEDマトリクスの1列名を表します。

従って、Address 0x00から次のようなデータを16バイト書き込むと、全てグリーンになります。

0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00

全てをレッドにするためには次のようにAddress 0x00から16バイトを書き込みます。

0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF

次のものは、1列目をGreenに点灯します。

0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00

LED8x8bi.c

#define LED_ON 1

#define LED_OFF 0

#define LED_RED 1

#define LED_YELLOW 2

#define LED_GREEN 3

#define HT16K33_BLINK_CMD 0x80

#define HT16K33_BLINK_DISPLAYON 0x01

#define HT16K33_BLINK_OFF 0

#define HT16K33_BLINK_2HZ 1

#define HT16K33_BLINK_1HZ 2

#define HT16K33_BLINK_HALFHZ 3

#define HT16K33_CMD_BRIGHTNESS 0xE0

#define SEVENSEG_DIGITS 5

#define ADAFRUIT_LEDBACKPACK_DEFAULT_ADDR 0x70 //b'1110000

uint8_t LED8x8bi_i2c_addr = ADAFRUIT_LEDBACKPACK_DEFAULT_ADDR;

uint16_t LED8x8bi_displaybuffer[8];

uint8_t LED8x8bi_rotation = 1;

#define swap(a, b) { int16_t t = a; a = b; b = t; }

#define _BV(bit) (1<<(bit))

void LED8x8bi_setBrightness(uint8_t b)

{

if (b > 15) b = 15;

I2CDev_writeCommand(LED8x8bi_i2c_addr, HT16K33_CMD_BRIGHTNESS | b);

}

void LED8x8bi_blinkRate(uint8_t b)

{

if (b > 3) b = 0; // turn off if not sure

I2CDev_writeCommand(LED8x8bi_i2c_addr, HT16K33_BLINK_CMD | HT16K33_BLINK_DISPLAYON | (b << 1));

}

void LED8x8bi_begin(uint8_t _addr)

{

LED8x8bi_i2c_addr = _addr;

I2CDev_writeCommand(LED8x8bi_i2c_addr, 0x21); // turn on oscillator

LED8x8bi_blinkRate(HT16K33_BLINK_OFF);

LED8x8bi_setBrightness(15); // max brightness

}

void LED8x8bi_writeDisplay(void)

{

uint8_t buffer[16];

uint8_t i,j;

j=0;

for (i=0;i<8;i++)

{

buffer[j++] = LED8x8bi_displaybuffer[i] & 0xFF;

buffer[j++] = (LED8x8bi_displaybuffer[i & 0xF] >> 8) & 0xFF;

}

I2CDev_writeBytes(LED8x8bi_i2c_addr, 0, buffer, 16);

}

void LED8x8bi_clear(void)

{

for (uint8_t i=0; i<8; i++) {

LED8x8bi_displaybuffer[i] = 0;

}

}

void LED8x8bi_all_yellow(void)

{

for (uint8_t i=0; i<8; i++) {

LED8x8bi_displaybuffer[i] = 0xFFFF;

}

}

void LED8x8bi_all_yellow_1(void)

{

for (uint8_t i=0; i<8; i++) {

LED8x8bi_displaybuffer[i] = 0x0101;

}

}

void LED8x8bi_all_red(void)

{

for (uint8_t i=0; i<8; i++) {

LED8x8bi_displaybuffer[i] = 0xFF00;

}

}

void LED8x8bi_all_red_1(void)

{

for (uint8_t i=0; i<8; i++) {

LED8x8bi_displaybuffer[i] = 0x0100;

}

}

void LED8x8bi_all_green(void)

{

for (uint8_t i=0; i<8; i++) {

LED8x8bi_displaybuffer[i] = 0x00FF;

}

}

void LED8x8bi_all_green_1(void)

{

for (uint8_t i=0; i<8; i++) {

LED8x8bi_displaybuffer[i] = 0x0001;

}

}

uint8_t LED8x8bi_getRotation(void)

{

return LED8x8bi_rotation;

}

void LED8x8bi_drawPixel(int16_t x, int16_t y, uint16_t color)

{

if ((y < 0) || (y >= 8)) return;

if ((x < 0) || (x >= 8)) return;

switch (LED8x8bi_getRotation()) {

case 1:

swap(x, y);

x = 8 - x - 1;

break;

case 2:

x = 8 - x - 1;

y = 8 - y - 1;

break;

case 3:

swap(x, y);

y = 8 - y - 1;

break;

}

if (color == LED_GREEN) {

// Turn on green LED.

LED8x8bi_displaybuffer[y] |= 1 << x;

// Turn off red LED.

LED8x8bi_displaybuffer[y] &= ~(1 << (x+8));

} else if (color == LED_RED) {

// Turn on red LED.

LED8x8bi_displaybuffer[y] |= 1 << (x+8);

// Turn off green LED.

LED8x8bi_displaybuffer[y] &= ~(1 << x);

} else if (color == LED_YELLOW) {

// Turn on green and red LED.

LED8x8bi_displaybuffer[y] |= (1 << (x+8)) | (1 << x);

} else if (color == LED_OFF) {

// Turn off green and red LED.

LED8x8bi_displaybuffer[y] &= ~(1 << x) & ~(1 << (x+8));

}

}