フルカラー7セグメントLEDの点灯②数値を表示
前回、フルカラー7セグメントLEDを5桁つないで点灯しました。ここでは、温度や電圧などの数値があれば、それを表示できるスケッチを作ります。
●エレメントの対応
一つの7セグメントLEDには、8個のエレメントがあります。
pixels.setPixelColor(i, pixels.Color(100, 100, 100));
の記述で、そのエレメントに対して輝度情報を設定します。iは、0から始まるエレメントのアドレスを指定します。最初の7セグが0~7、8からは2個目の7セグになります。最後5桁目のドットが39です。
7セグメントLEDを利用すためにシフトレジスタを使ったデバイスでは、送るデータが桁ごとにずれていくようなプログラムを組みましたが、このデバイスは、絶対アドレスが振られていると解釈できます。
具体的に、2番目の7セグLEDに'E'を表示します。色は黄色です。
// (c) 2013 Shae Erisson.GPLv3 license Adafruit NeoPixel library
#include <Adafruit_NeoPixel.h>
#define PIN 6 // 470ohrm
Adafruit_NeoPixel pixels(8*5, PIN, NEO_GRB + NEO_KHZ800);
void setup() {
pixels.begin(); // INITIALIZE NeoPixel strip object (REQUIRED)
}
void loop() {
pixels.clear(); // Set all pixel colors to 'off'
pixels.setPixelColor(8, pixels.Color(50, 50, 0));
pixels.setPixelColor(9, pixels.Color(0, 0, 0));
pixels.setPixelColor(10, pixels.Color(0, 0, 0));
pixels.setPixelColor(11, pixels.Color(50, 50, 0));
pixels.setPixelColor(12, pixels.Color(50, 50, 0));
pixels.setPixelColor(13, pixels.Color(50, 50, 0));
pixels.setPixelColor(14, pixels.Color(50, 50, 0));
pixels.show();
delay(5000);
}
実行しました。
●simpleを改造して数値を表示
前回動作確認に使ったサンプルsimpleをベースに、スケッチを修正します。
数字の0から9のデータmoji[]は、エレメントの点灯を’1’で表し、7~0の順で並んでいます。
表示関数dispElement(String n)は、5文字の文字列を引数にしています。addressが各エレメントの絶対アドレスで、0~39の範囲のデータです。forループは二重で、内側は1桁の7セグを描画します。外側ループは、ここでは5個7セグLEDがあるので、5回回ります。
n.charAt(i)は、"42917"という文字列から1文字ずつ取り出します。取り出したのは文字なので、整数に変換します。
moji[String((n.charAt(i))).toInt()]は、最初の'4'であれば、配列moji[4]の中身B01100110を得ます。
bitRead(moji[String((n.charAt(i))).toInt()], c)は、1ビットずつチェックします。'1'であれば、
pixels.setPixelColor(address, pixels.Color(50, 50, 50)); で光らせ、'0'ならば、
pixels.setPixelColor(address, pixels.Color(0, 0, 0)); 消灯します。
// (c) 2013 Shae Erisson.GPLv3 license Adafruit NeoPixel library
#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h> // Required for 16 MHz Adafruit Trinket
#endif
#define PIN 6 // 470ohrm
#define elements 8
#define segments 5
char moji[16]{
B00111111, // 0
B00000110, // 1
B01011011, // 2
B01001111, // 3
B01100110, // 4
B01101101, // 5
B01111101, // 6
B00000111, // 7
B01111111, // 8
B01100111, // 9
B01011111, // a donot display
B01111100, // b
B01011000, // c
B01011110, // d
B01111001, // e
B01110001 // f
};
Adafruit_NeoPixel pixels(elements*segments, PIN, NEO_GRB + NEO_KHZ800);
void setup() {
// These lines are specifically to support the Adafruit Trinket 5V 16 MHz.
// Any other board, you can remove this part (but no harm leaving it):
#if defined(__AVR_ATtiny85__) && (F_CPU == 16000000)
clock_prescale_set(clock_div_1);
#endif
// END of Trinket-specific code.
pixels.begin(); // INITIALIZE NeoPixel strip object (REQUIRED)
Serial.begin (9600);
}
void dispElement(String n){
int address = 0;
for (int i=0; i<segments; i++) { //
for (int c=0; c<elements; c++) {
// Serial.print(" c=");Serial.print(c);
// Serial.print(" i=");Serial.print(i);
// Serial.print(" address=");Serial.print(address);
// Serial.print(" moji=");Serial.print(n.charAt(i));
// Serial.print(" =");Serial.println(moji[String((n.charAt(i)) ).toInt()],BIN);
// Serial.print(bitRead(moji[String((n.charAt(i)) ).toInt()], c));
if (bitRead(moji[String((n.charAt(i))).toInt()], c)) {pixels.setPixelColor(address, pixels.Color(50, 50, 50));}
else {pixels.setPixelColor(address, pixels.Color(0, 0, 0));}
address +=1;
}
}
pixels.show(); // Send the updated pixel colors to the hardware.
}
void loop() {
pixels.clear(); // Set all pixel colors to 'off'
float temp = 42.9178;
String data = String(temp,4);Serial.println(temp,3);
int findDot = data.indexOf(".");
Serial.println(findDot);
String integer ; //seisuubu
for(byte i=0; i<findDot; i++) integer= integer+data.charAt(i);
Serial.println(integer);
String decimal = data.substring(findDot+1);
Serial.println(decimal);
String newData = integer + decimal;
Serial.println(newData);
dispElement(newData);
pixels.setPixelColor(findDot*8-1, pixels.Color(50, 50, 50)); // dot
pixels.show();
delay(5000);
}
loop()内では、温度データと想定したtemp = 42.9178から一度文字列dataに変換し、ドットを取り除いた文字列newDataを作成します。
その文字列を引数に、dispElement(newData);を呼び出し、数字を表示します。
pixels.setPixelColor(findDot*8-1, pixels.Color(50, 50, 50));
pixels.show();
は、小数点のドットを描画します。
●色を変える
サンプルにstrandtestがあって、rainbow()関数でエレメントの色を変更するデモがあります。このルーチンを強引に組み入れました。
// (c) 2013 Shae Erisson.GPLv3 license Adafruit NeoPixel library
#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h> // Required for 16 MHz Adafruit Trinket
#endif
#define PIN 6 // 470ohrm
#define elements 8
#define segments 5
char moji[10]{
B00111111, // 0
B00000110, // 1
B01011011, // 2
B01001111, // 3
B01100110, // 4
B01101101, // 5
B01111101, // 6
B00000111, // 7
B01111111, // 8
B01100111, // 9
};
Adafruit_NeoPixel pixels(elements*segments, PIN, NEO_GRB + NEO_KHZ800);
void setup() {
// These lines are specifically to support the Adafruit Trinket 5V 16 MHz.
// Any other board, you can remove this part (but no harm leaving it):
#if defined(__AVR_ATtiny85__) && (F_CPU == 16000000)
clock_prescale_set(clock_div_1);
#endif
// END of Trinket-specific code.
pixels.begin(); // INITIALIZE NeoPixel strip object (REQUIRED)
Serial.begin (9600);
}
void dispElement(String n){
int address = 0;
for (int i=0; i<segments; i++) { //
for (int c=0; c<elements; c++) {
if (bitRead(moji[String((n.charAt(i))).toInt()], c)) {
for(long firstPixelHue = 0; firstPixelHue < 5*65536/16; firstPixelHue += 256) {
for(int i=0; i<pixels.numPixels(); i++) { // For each pixel in strip...
int pixelHue = firstPixelHue + (i * 65536L/16 / pixels.numPixels());
pixels.setPixelColor(address, pixels.gamma32(pixels.ColorHSV(pixelHue)));
}
pixels.show(); // Update strip with new contents
delay(10); // Pause for a moment
}
}
else {pixels.setPixelColor(address, pixels.Color(0, 0, 0));}
address +=1;
}
}
pixels.show(); // Send the updated pixel colors to the hardware.
}
void loop() {
pixels.clear(); // Set all pixel colors to 'off'
float temp = 32.9178;
String data = String(temp,4);Serial.println(temp,3);
int findDot = data.indexOf(".");
String integer ;
for(byte i=0; i<findDot; i++) integer= integer+data.charAt(i);
String decimal = data.substring(findDot+1);
String newData = integer + decimal;
dispElement(newData);
pixels.setPixelColor(findDot*8-1, pixels.Color(0, 50, 50)); // dot
pixels.show();
delay(5000);
}
実行例です。
通常は緑色で表示をし、設定値を超えたら赤色に表示色を変えるような利用事例があれば、使いやすい7セグメントLEDです。少し高価なのが気になります。