フルカラー7セグメントLEDの点灯②数値を表示

 前回、フルカラー7セグメントLEDを5桁つないで点灯しました。ここでは、温度や電圧などの数値があれば、それを表示できるスケッチを作ります。

エレメントの対応

 一つの7セグメントLEDには、8個のエレメントがあります。

  pixels.setPixelColor(i, pixels.Color(100, 100, 100));

の記述で、そのエレメントに対して輝度情報を設定します。iは、0から始まるエレメントのアドレスを指定します。最初の7セグが078からは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);
}



 実行例です。

  ビデオ.movをダウンロード

 通常は緑色で表示をし、設定値を超えたら赤色に表示色を変えるような利用事例があれば、使いやすい7セグメントLEDです。少し高価なのが気になります。

前へ

フルカラー7セグメントLEDの点灯①接続

次へ

M5Stackで始めるセンサ・インターフェーシング(8) 気圧センサLPS25HBを利用