フルカラー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です。少し高価なのが気になります。