初めてのArduino ⑤ UNOボードに表示器をつなぐ(その4 fontを修正)

 前回、LEDマトリクスで8×8文字構成のフォントを表示しました。数字は間が抜けた感じがします。昔、ドット・プリンタが発売されたころ、ANK文字は5×7の構成でした。その後漢字が印字したいので、16×16から24×24の構成になっていきました。

 ここでは、5×8構成の数字を作って表示します。

文字データ

 左が前回のデータで、右が新規に作ったデータです。左1列は空けてあります。


描画ルーチンの修正

 drawString()とdrawSprite()で描画していました。drawString()で横8ドットを扱っていたのを5ドットに変更します。drawSprite()は変更なしです。

 タブfonts.inoのスケッチです。フォントは数字とドットだけを修正しています。アルファベットは削りました。


// This is the font definition. You can use http://gurgleapps.com/tools/matrix to create your own font or sprites.
// If you like the font feel free to use it. I created it myself and donate it to the public domain.
byte font[95][8] = { {0,0,0,0,0,0,0,0}, // SPACE
                     {0x10,0x18,0x18,0x18,0x18,0x00,0x18,0x18}, // EXCL
                     {0x28,0x28,0x08,0x00,0x00,0x00,0x00,0x00}, // QUOT
                     {0x00,0x0a,0x7f,0x14,0x28,0xfe,0x50,0x00}, // #
                     {0x10,0x38,0x54,0x70,0x1c,0x54,0x38,0x10}, // $
                     {0x00,0x60,0x66,0x08,0x10,0x66,0x06,0x00}, // %
                     {0,0,0,0,0,0,0,0}, // &
                     {0x00,0x10,0x18,0x18,0x08,0x00,0x00,0x00}, // '
                     {0x02,0x04,0x08,0x08,0x08,0x08,0x08,0x04}, // (
                     {0x40,0x20,0x10,0x10,0x10,0x10,0x10,0x20}, // )
                     {0x00,0x10,0x54,0x38,0x10,0x38,0x54,0x10}, // *
                     {0x00,0x08,0x08,0x08,0x7f,0x08,0x08,0x08}, // +
                     {0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x08}, // COMMA
                     {0x00,0x00,0x00,0x00,0x7e,0x00,0x00,0x00}, // -
                     {0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x60}, // DOT
                     {0x00,0x04,0x04,0x08,0x10,0x20,0x40,0x40}, // /
                     {0x30,0x48,0x48,0x48,0x48,0x48,0x30,0x00}, // 0
                     {0x20,0x60,0x20,0x20,0x20,0x20,0x70,0x00}, // 1
                     {0x30,0x48,0x08,0x08,0x30,0x40,0x78,0x00}, // 2
                     {0x30,0x48,0x08,0x30,0x08,0x08,0x70,0x00}, // 3
                     {0x10,0x10,0x30,0x50,0x78,0x10,0x10,0x00}, // 4
                     {0x70,0x40,0x40,0x30,0x08,0x08,0x70,0x00}, // 5
                     {0x30,0x40,0x40,0x70,0x48,0x48,0x30,0x00}, // 6
                     {0x78,0x48,0x10,0x20,0x20,0x20,0x20,0x00}, // 7
                     {0x30,0x48,0x48,0x30,0x48,0x48,0x30,0x00}, // 8
                     {0x30,0x48,0x48,0x38,0x08,0x08,0x30,0x00}, // 9
                      // (the font does not contain any lower case letters. you can add your own.)
                  };    // {}, //

/**
 * This function draws a string of the given length to the given position.
 */
void drawString(char* text, int len, int x, int y ){
  for( int idx = 0; idx < len; idx ++ ){
    int c = text[idx] - 32;

    // stop if char is outside visible area
    if( x + idx * 5  > LEDMATRIX_WIDTH )
      return;

    // only draw if char is visible
    if( 4 + x + idx * 4 > 0 )
      drawSprite( font[c], x + idx * 5, y, 5, 8 );
  }
}

/**
 * This draws a sprite to the given position using the width and height supplied (usually 8x8)
 */
void drawSprite( byte* sprite, int x, int y, int width, int height ){
  // The mask is used to get the column bit from the sprite row
  byte mask = B10000000;

  for( int iy = 0; iy < height; iy++ ){
    for( int ix = 0; ix < width; ix++ ){
      lmd.setPixel(x + ix, y + iy, (bool)(sprite[iy] & mask ));

      // shift the mask by one pixel to the right
      mask = mask >> 1;
    }

    // reset column mask
    mask = B10000000;
  }
}

 

メインのタブ

 数字がスリムになったので、表示桁を6に増やしました。drawString(Buf, 6, 0, 0);


#include <LEDMatrixDriver.hpp>

int8_t LEDMATRIX_CS_PIN  = 10;
int8_t LEDMATRIX_SEGMENTS = 4;
int8_t LEDMATRIX_WIDTH  =  LEDMATRIX_SEGMENTS * 8;
int8_t sensorPin = A0;
float Vcc = 4.38;
int16_t sensorValue;
float analogSensorData;

LEDMatrixDriver lmd(LEDMATRIX_SEGMENTS, LEDMATRIX_CS_PIN);

void setup() {
  // init the display
  lmd.setEnabled(true);
  lmd.setIntensity(2);   // 0 = low, 10 = high
}

void loop(){
	sensorValue = analogRead(sensorPin);
  analogSensorData = Vcc * sensorValue / 1024.0;
  
  String sensorValueSTR = String(analogSensorData, DEC);
  char Buf[10]="6.78901";
  sensorValueSTR.toCharArray(Buf, 10);
	drawString(Buf, 6, 0, 0);

	lmd.display();

  delay(1000);
}

A-Dコンバータ

 A-Dコンバータは、アナログ入力をディジタル・データに変換する際、基準電圧と比較をします。今回、何も設定しないと電源電圧が基準電圧になります。LEDマトリクスの消費電流が多いのと、点灯するLEDの数が変化するので、電流が大きく変わり、電源電圧は変動します。5VはUSBケーブルからの電圧です。

 したがって、表示される電圧はふらふらと変化します。

 Arduino UNOで使われているマイコンのA-Dコンバータは、外部基準電圧、内部基準電圧の2通りが選択できます。

 Arduino UNOボード上では、外部電源もしくはUSB電源から3端子レギュレータを通して3.3Vの電圧を作っています。そこそこ安定です。

 そこで、3.3V端子をAREFにつなぎます。A0端子には2.48Vの実験用電源の出力をつなぎます。ボード上の3.3Vを測ると3.30Vでした。

 メインのスケッチです。setup()内で、analogReference(EXTERNAL);とAREF端子につながっている外部電源を使うように指示します。アナログ入力端子に入力できる電圧は、0~3.3Vになります。


#include <LEDMatrixDriver.hpp>

int8_t LEDMATRIX_CS_PIN  = 10;
int8_t LEDMATRIX_SEGMENTS = 4;
int8_t LEDMATRIX_WIDTH  =  LEDMATRIX_SEGMENTS * 8;
int8_t sensorPin = A0;
float Vcc = 3.3;
int16_t sensorValue;
float analogSensorData;

LEDMatrixDriver lmd(LEDMATRIX_SEGMENTS, LEDMATRIX_CS_PIN);

void setup() {
  // init the display
  lmd.setEnabled(true);
  lmd.setIntensity(2);   // 0 = low, 10 = high
  analogReference(EXTERNAL);
}

void loop(){
	sensorValue = analogRead(sensorPin);
  analogSensorData = Vcc * sensorValue / 1024.0;
  
  String sensorValueSTR = String(analogSensorData, DEC);
  char Buf[10]="6.78901";
  sensorValueSTR.toCharArray(Buf, 10);
	drawString(Buf, 6, 0, 0);

	lmd.display();

  delay(1000);
}

 表示はぴたっと止まっています。時々最後の2桁が変化します。

 基準電圧が3.30Vなので、1LSBは3.22mVです。2.4878Vで1LSB増えると計算上2.4910Vになります。じっと観察していると2.4911Vの表示になることがあります。

ドットの前後を詰める

 小数点のある数値があまりかっこよくないです。ドットが間延びして表示されるからです。小数点が出てくるまでは右に、小数点が出た後は左に少し詰めるようにスケッチを変更しました。修正したのはdrawString()関数だけです。


void drawString(char* text, int len, int x, int y ){
  Serial.println("---");
  int flag=0;
  for( int idx = 0; idx < len; idx ++ ){
    int c = text[idx] - 32;
    
    // stop if char is outside visible area
    if( x + idx * 5  > LEDMATRIX_WIDTH )
      return;

    // only draw if char is visible
    if( 4 + x + idx * 4 > 0 )
      if (!flag) 
        drawSprite( font[c], x+1 + idx * 5, y, 5, 8 );
      else  {
        drawSprite( font[c], x-1 + idx * 5, y, 5, 8 );
        flag = 1;}

      if (c==14) flag = 1;
  }
}

前へ

初めてのArduino ④ UNOボードに表示器をつなぐ(その3 電圧を表示)

次へ

初めてのArduino ⑥ UNOボードで温度を測る(その1 LM35DZ)