TM1637のArduinoライブラリを6桁7セグに対応させる

TM1637は思った以上に便利で簡単に7セグを動かすことが出来ました。
7セグ+DPの6桁をこのIC1つで動かせるなんてすごい!と思っていたのですが、紹介したArduinoのライブラリでは4桁までしか対応できないことがわかりました。

また、DPを点灯させるのもちょっと苦労したのでそれらに対応できるように改造してみました。

スポンサーリンク

showNumberDec(num, leading_zesro, length, pos)という関数で数字を簡単に表示できるのですが、引数のnumがint型ですので必然的に32767までになってしまいます。
また、lengthという引数にはデフォルトで4が入るようになっていて、中の信号を送る部分も最大4回になっていますので5桁以上に対応することがそのままでは不可能になっています。
というわけで引数をlongにして、中の信号送信の繰り返しを6回にすると6桁に対応できます。

わからなくてもとりあえずTM1637Display.cppのshowNumberDec関数を次のように変えます。

void TM1637Display::showNumberDec(long num, bool leading_zero, uint8_t length, uint8_t pos)
{
	uint8_t digits[6];
	const static long divisors[] = { 1, 10, 100, 1000, 10000, 100000 };
	bool leading = true;
	
	for(int8_t k = 0; k < 6; k++) {
	    long divisor = divisors[6 - 1 - k];
		int d = num / divisor;
		
		if (d == 0) {
		  if (leading_zero || !leading || (k == 5))
		    digits[k] = encodeDigit(d);
	      else
		    digits[k] = 0;
		}
		else {
			digits[k] = encodeDigit(d);
			num -= d * divisor;
			leading = false;
		}
	}
	
	setSegments(digits + (6 - length), length, pos);
}

さらにこの中で使われているsetSegmentsという関数も次のように変更する必要があります。
showNumberDec関数のすぐ上に記述されています。

void TM1637Display::setSegments(const uint8_t segments[], uint8_t length, uint8_t pos)
{
    // Write COMM1
	start();
	writeByte(TM1637_I2C_COMM1);
	stop();
	
	// Write COMM2 + first digit address
	start();
	writeByte(TM1637_I2C_COMM2 + (pos & 0x05));
	
	// Write the data bytes
	for (uint8_t k=0; k < length; k++) 
	  writeByte(segments[k]);
	  
	stop();

	// Write COMM3 + brightness
	start();
	writeByte(TM1637_I2C_COMM3 + (m_brightness & 0x0f));
	stop();
}

またヘッダファイル(TM1637Display.h)内のプロトタイプ宣言も該当する関数を変更する必要があります。

void setSegments(const uint8_t segments[], uint8_t length = 6, uint8_t pos = 0);
void showNumberDec(long num, bool leading_zero = false, uint8_t length = 6, uint8_t pos = 0);

setSegments関数は引数のデフォルト値を変えるだけですので、6桁と毎回明示したい場合は書き換えなくてもいいです。

これで6桁に対応できました。
TM1637 6桁7セグ駆動
同じアノードコモンの7セグが手持ちになかったのでなんだかつぎはぎな感じですが。

DPの表示はencodeDigitという関数で表示数値のバイナリを呼び出して、DPのビットを”1″にしたらいいので、0x80でマスクするだけでいいですね。

data = display.encodeDigit(1) | 0x80;

まぁ1桁ずつ設定していく必要がありますけどね・・・

小数に対応できたらもっといいかもしれませんが、それは文字列に直して分割して・・・と結構面倒くさそうなのでとりあえず保留です。
そんなに需要がなそうですしねwww


これでTM1637をちゃんと使えるようになりました。
48個のLEDが本当に自由に制御できるようになりましたね。
MAX7219も1回試してみたいものです。

スポンサーリンク

Leave a Comment