この記事は、MIDI&Audioをは無関係です。
Adafruit 8x8 Bi-Color LED MatrixをRaspberry Pi Zeroに接続し、 WiringPiライブラリを使って動作させます。Bi-Colorは、2色(赤と緑)を意味しています。 HT16K33 はLEDのドライバのチップの名前です。
HT16K33は緑を点灯させるレジスターと、赤を点灯させるレジスターがあります。 それぞれのレジスタは、8x8bit、すなわち8byteです。 1行が1byteに相当します。 点灯させたい時は、そのビットを1に設定し、消灯はゼロとします。 オレンジを点灯させたい時は、緑と赤を両方とも1に設定します。 例えばGndDotとRndDotをそれぞれ8x8bitのメモリとします。
uint8_t GndDot[8]; //緑の設定レジスタ uint8_t RedDot[8]; //赤の設定レジスタ
HT16K33のレジスタ(0x00 - 0x10)に対して、緑と赤のレジスタの値を1行づつを交互に書き込んています。
void Wiringpi_HT16K33::DisplayOutput(uint8_t *GndDot, uint8_t *RndDot) { uint8_t i,j; for(i=0,j=0; i<16; i+=2,j++){ write8(i, GndDot[j]); write8(i+1, RndDot[j]); } }
下のように点灯させたいとします。これを図1とします。
図1:目的の点灯図
この場合、図1を見ながらGndDotとRedDotを次のように設定するとします。
uint8_t GrnON[8]={ 0b00000000, 0b01111110, 0b01000000, 0b01000000, 0b01000000, 0b01000000, 0b01111110, 0b00000000 }; uint8_t RedON[8]={ 0b00000000, 0b01000000, 0b00100000, 0b00010000, 0b00001000, 0b00000100, 0b00000010, 0b00000000 };
GrnON、RedONを上の関数で書き込むと以下のように目的の絵を180度回転させた絵になってしまいます。
図2:実際の点灯
目的の図1のように点灯させるには、図1の絵を180度回転してGndDotとRedDotを設定します。 (180度回しておけば、レジスタに書き込んだ時180度まわしてれるので元に戻ります。)
図3:図1を180度回転
uint8_t GrnON2[8]={ 0b00000000, 0b01000010, 0b01000010, 0b01000010, 0b01000010, 0b01000010, 0b01111110, 0b00000000 }; uint8_t RedON2[8]={ 0b00000000, 0b01000000, 0b00100000, 0b00010000, 0b00001000, 0b00000100, 0b00000010, 0b00000000 };
GrnON2、RedON2を上の関数で書き込むと以下のように図1を得ることができます。
図4:GrnON2、RedON2を表示した結果
// main.cpp // 赤 → 緑 → オレンジ → 消灯 // の順に点灯します。 #include <stdio.h> #include <stdint.h> #include <wiringPi.h> #include <wiringPiI2C.h> #include "Wiringpi_HT16K33.h" int main() { Wiringpi_HT16K33 ht16k33(5); while(1){ ht16k33.allRed(); delay(2000); ht16k33.allGreen(); delay(2000); ht16k33.allOrange(); delay(2000); ht16k33.allClear(); delay(2000); } }
/* * Wiringpi_HT16K33.h * HT16k33 for using WiringPi * by MikataHara * 2024.10.26 */ #ifndef _WIRINGPI_HT16K33_H #define _WIRINGPI_HT16K33_H #include <wiringPiI2C.h> #define HT16K33_I2CADDR_DEFAULT 0x70 ///< I2C address /* Class for Adafruit HT16K33 bi-Color */ class Wiringpi_HT16K33 { public: Wiringpi_HT16K33(uint8_t val); void write(uint8_t val); void write8(uint8_t reg, uint8_t val); uint8_t read8(uint8_t reg); void allClear(); void allGreen(); void allRed(); void allOrange(); private: uint8_t _i2caddr; };
/* * Wiringpi_HT16K33.cpp * Modified for Trinket 0by MikataHara * 2024.10.26 */ #include <stdint.h> #include <stdio.h> #include "Wiringpi_HT16K33.h" /* val : 輝度(0x0〜0xF) */ Wiringpi_HT16K33::Wiringpi_HT16K33(uint8_t val) { _i2caddr = wiringPiI2CSetup(HT16K33_I2CADDR_DEFAULT); // オシレータを有効化 wiringPiI2CWrite(_i2caddr, 0x21); // 0x21: システムオシレータON // 表示点灯 wiringPiI2CWrite(_i2caddr, 0x81); // 0x81: 表示ON、ブリンクなし // 輝度設定 wiringPiI2CWrite(_i2caddr, 0xE0 | val); // 0xE0 + 輝度(0x0〜0xF) } void Wiringpi_HT16K33::write(uint8_t val) { wiringPiI2CWrite(_i2caddr, val); } void Wiringpi_HT16K33::write8(uint8_t reg, uint8_t val) { wiringPiI2CWriteReg8(_i2caddr, reg, val); } uint8_t Wiringpi_HT16K33::read8(uint8_t reg) { uint16_t result = wiringPiI2CReadReg8(_i2caddr, reg); return result; } void Wiringpi_HT16K33::allClear() { for(uint8_t i=0; i<16; i+=2){ write8(i, 0x00); write8(i+1, 0x00); } } void Wiringpi_HT16K33::allRed() { for(uint8_t i=0; i<16; i+=2){ write8(i, 0x00); write8(i+1, 0xFF); } } void Wiringpi_HT16K33::allGreen() { for(uint8_t i=0; i<16; i+=2){ write8(i, 0xFF); write8(i+1, 0x00); } } void Wiringpi_HT16K33::allOrange() { for(uint8_t i=0; i<16; i+=2){ write8(i, 0xFF); write8(i+1, 0xFF); } }
DEMOプログラムをGithubに置きました。