7セグLED表示 その9 4文字-HT16K33③
7セグLED表示の連載では、2回、HT16K33コントローラを使ったLEDを使いました。秋月電子通商でHT16K33ボードを扱っていることがわかったので、同社の大型7セグメントLEDとともに使っていきます。
●大型7セグメントLEDのおもな仕様
- アノード・コモン
- 赤色
- 動作電圧 5V
- エレメントの電流 20もしくは40mAと思われる
- エレメント数 16+ドット
- 形状 約57×32mm
●接続
エレメント数とドットを合わせると2バイトで指定ができないので、上辺と下辺のドットをつないで使います。プリント基板の配線ではすでにショートされていました。7セグメントとして、真ん中の2エレメントショートしたほうが便利です。これもショートしてありました。斜めのエレメントは配線されていなかったので、そのままです。したがって、1バイトで各エレメントが指定できます。
HT16K33は、最大でROW端子は40mA、COM端子は200mAの吸い込みができるので、大型7セグメントLEDは駆動できると思われます。実際に点灯しているとき、ICに触ってみましたが、特別な発熱は感じられませんでした。
利用できる多くのライブラリは、カソード・コモンのLEDを駆動します。ここで利用している7セグメントLEDはアノード・コモンです。COMxで桁(Digit)をROWxでエレメントを駆動していたのを、ROWxで桁をCOMxでエレメントの駆動に変更します。
ROW0(A0)がLED3、ROW1(A1)がLED4、ROW2(A2)がLED5、ROW3(A3)がLED6です。
COM0(C0)がエレメントA ,,, COM6(C6)がエレメントG、 COM7(C7)がDPです。
スレーブ・アドレスはA0、A1、A2で変更ができます。なにも修正せずにI2Cscannerで確認すると0x70でした。
●基板のはんだ付け
大型7セグメントLED(時計用III用 赤色7セグ大型表示器)は、LEDが四つとプリント基板のセットです。はんだ付けして組み立てます。DPがLED4だけしか配線されていないので、LED3、LED5、LED6のDP端子10番を全部ショートします。
時計として利用する予定はなかったので、中央のLEDは取り付けていません。
●ライブラリの修正
ライブラリは、VitconCommonを使います。インストールの方法は、第4回を参照してください。インストールしたライブラリは、C:ドキュメント\Arduino\libraries\VitconCommonに入っています。修正するのは、VitconHT16K33.cppです。
カソード・コモンのデータは、エレメントのaからgの並びをそのまま1バイトのデータに直しただけで表示ができました。ここでは、アノード・コモンに合わせてデータを変換します。その部分は、水野 修さんの作られた変換ルーチンを利用しました。
Send()関数を、下記のプログラムにそっくり入れ替えます。
void HT16K33::Send()
{
// Copyright (c) 2018 Osamu Mizuno
//https://github.com/omzn/y2038_countdown/blob/master/anodecommon_7seg.cpp
uint8_t c[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
// convert displaybuffer(cathode) to new buffer c(anode)
for (uint8_t address = 0; address < DIGITS; address++) {
uint8_t val = mDigits[address] & 0xff;
for (uint8_t i = 0; i < 8; i++) {
if (val >> i & 1) {
c[(address / 8) + i * 2] |= 1 << (address % 8);
}
}
}
Wire.beginTransmission(mAddress);
Wire.write(0x00);
for (uint8_t i = 0; i < 16; i += 2) {
Wire.write(c[i]);
Wire.write(c[i + 1]);
}
Wire.endTransmission();
}
●テスト表示
#include <VitconHT16K33.h>
using namespace vitcon;
HT16K33 fnd;
void setup() {
Serial.begin(9600);
fnd.Init();
delay(1000);
}
void loop(){
fnd.SetBrightness(1);
fnd.Clear(0);
fnd.Minus(0);
fnd.Number(1,2);
fnd.Number(2,5);
fnd.Number(3,6);
fnd.Dot(2);
fnd.Send();
fnd.SetBrightness(10);
delay(1000);
}
実行した様子です。
●数値を表示
#include <VitconHT16K33.h>
using namespace vitcon;
HT16K33 fnd;
void setup() {
Serial.begin(9600);
fnd.Init();
delay(1000);
}
void loop(){
float Temp = 23.6;
if ( Temp<0 ) {
fnd.Minus(0); Temp= -1*Temp;
} else {
fnd.Clear(0);
}
if ( (String(Temp).length()) == 5) {
fnd.Number(1, String(String(Temp).charAt(0)).toInt() );
fnd.Number(2, String(String(Temp).charAt(1)).toInt() );
fnd.Number(3, String(String(Temp).charAt(3)).toInt() );
} else if ( (String(Temp).length() ) == 4) {
fnd.Number(2, String(String(Temp).charAt(0)).toInt() );
fnd.Number(3, String(String(Temp).charAt(2)).toInt() );
}
fnd.Dot(2) ;
fnd.Send();
delay(1000);
}
●温湿度の表示
温湿度センサのSHT31をI2Cでつなぎます。
#include <VitconHT16K33.h>
#include <Wire.h>
#include "SHT31.h"
using namespace vitcon;
HT16K33 fnd;
SHT31 sht31 = SHT31();
void setup() {
Serial.begin(9600);
sht31.begin();
fnd.Init();
}
void loop(){
float temp = sht31.getTemperature();
float hum = sht31.getHumidity();
Serial.print("Temp = "); Serial.println(temp);
Serial.print("Hum = "); Serial.println(hum);
if ( temp<0 ) {
fnd.Minus(0); temp= -1*temp;
} else {
fnd.Clear(0);
}
if ( (String(temp).length()) == 5) {
fnd.Number(1, String(String(temp).charAt(0)).toInt() );
fnd.Number(2, String(String(temp).charAt(1)).toInt() );
fnd.Number(3, String(String(temp).charAt(3)).toInt() );
} else if ( (String(temp).length() ) == 4) {
fnd.Number(2, String(String(temp).charAt(0)).toInt() );
fnd.Number(3, String(String(temp).charAt(2)).toInt() );
}
fnd.Dot(2) ;
fnd.Send();
delay(1000);
fnd.Clear();
fnd.Number(2, String(String(hum).charAt(0)).toInt() );
fnd.Number(3, String(String(hum).charAt(1)).toInt() );
fnd.Dot(3) ;
fnd.Send();
delay(1000);
fnd.Clear();
}
温度を表示しているところです。
湿度を表示しているところです。