スポンサーリンク
Translate

透明で美しいVFD表示管IV-27Mでダイナミック点灯して全ての数字を表示してみました

スポンサーリンク

前回は1桁だけ数字を表示しましたが、今回はダイナミック点灯して全ての桁の数字を表示してみたいと思います。前回の記事はこちらです。

スポンサーリンク

プログラム

#include <SPI.h>
#define SPI_FREQ 3300000
#define STROBE_PIN 5

const int GRID_NUM = 14;
long long IV27DispData[GRID_NUM];

const int GRID[GRID_NUM] = { 0 , 1, 5, 6, 4, 2, 3, 20, 21, 22, 23, 24, 34, 33};

//                    a   b   c   d   e   f   g  dp
const int SEG[8] = { 25, 27, 30, 31, 29, 26, 28, 32};
const int SEG_NUM = 8;

//                            a  b  c  d  e  f  g
const bool CHAR[18][7] =   { {1, 1, 1, 1, 1, 1, 0}, {0, 1, 1, 0, 0, 0, 0}, {1, 1, 0, 1, 1, 0, 1}, {1, 1, 1, 1, 0, 0, 1},
  {0, 1, 1, 0, 0, 1, 1}, {1, 0, 1, 1, 0, 1, 1}, {1, 0, 1, 1, 1, 1, 1}, {1, 1, 1, 0, 0, 0, 0},
  {1, 1, 1, 1, 1, 1, 1}, {1, 1, 1, 1, 0, 1, 1}, {1, 1, 1, 0, 1, 1, 1}, {0, 0, 1, 1, 1, 1, 1},
  {0, 0, 0, 1, 1, 0, 1}, {0, 1, 1, 1, 1, 0, 1}, {1, 0, 0, 1, 1, 1, 1}, {1, 0, 0, 0, 1, 1, 1},
  {0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 1}
};

//Task Handles
TaskHandle_t taskHandle[10];
enum task { dispVFDTask };

void setup() {
  Serial.begin(115200);
  delay(100);
  Serial.println("start");

  initHV5812();

  //DispVFD task start
  xTaskCreatePinnedToCore(dispVFD, "dispVFD", 4096, NULL, 20, &taskHandle[dispVFDTask], 0);

}

void loop() {

  char charMasterData[] = "0123456789ABCDEF";
  char dispData[] = "                    ";
  for ( int j = 0 ; j < sizeof(charMasterData) - 1 ; j++ )
  {
    for ( int i = 0 ; i < sizeof(dispData) - 1 ; i++ )
    {
      dispData[i] = charMasterData[ ( j + i ) % (sizeof(charMasterData) - 1) ];
    }
    setString( dispData, sizeof(dispData) );
    delay(100);
  }

}

//Tasks
void dispVFD( void* arg )
{
  long long data = 0;
  while (1)
  {
    for ( int i = 0 ; i < GRID_NUM ; i++ )
    {
      data = IV27DispData[i];
      data |= (long long)1 << GRID[i];
      sendData(data);
      delay(1);
      data &= ~((long long)1 << GRID[i]);
    }
    sendData(data);
  }
}

//Functions
//set charactor pattern
void setString( char* str , int length )
{
  bool firstDigitFlag = true;
  
  //zero clear
  for ( int i = 0 ; i < GRID_NUM ; i++ )
    IV27DispData[i] = 0;

  int digits = GRID_NUM - 1;
  for ( int j = 0 ; j < length ; j++ )
  {
    int id = 0;
    switch ( str[j] ) {
      case '0':  id = 0; break;
      case '1':  id = 1; break;
      case '2':  id = 2; break;
      case '3':  id = 3; break;
      case '4':  id = 4; break;
      case '5':  id = 5; break;
      case '6':  id = 6; break;
      case '7':  id = 7; break;
      case '8':  id = 8; break;
      case '9':  id = 9; break;
      case 'A':  id = 10; break;
      case 'B':  id = 11; break;
      case 'C':  id = 12; break;
      case 'D':  id = 13; break;
      case 'E':  id = 14; break;
      case 'F':  id = 15; break;
      case ' ':  id = 16; break;
      case '-':  id = 17; break;
      case '.':  id = 18; break;
      default:   id = 16; break;
    }

    Serial.print(str[j]);

    if ( digits == GRID_NUM - 1 )
    {
      if ( id == 17 ) //'-'
        IV27DispData[digits] |= (long long)1 << SEG[6];
      if ( id == 18 ) //'.'
        IV27DispData[digits] |= (long long)1 << SEG[0];
      if( id != 17 && id != 18 )
      {
        firstDigitFlag = false;
      }
      digits--;
    }
    else
    {

      if ( id == 18 ) //'.'
      {
        //'.'
        if ( digits < GRID_NUM - 1 )
        {
          if ( digits == GRID_NUM - 2 && firstDigitFlag == true)
            IV27DispData[digits + 1] |= (long long)1 << SEG[0];
          else
            IV27DispData[digits + 1] |= (long long)1 << SEG[7];
        }
      }
      else
      {
        //number
        if ( digits < 0 )
        {
          Serial.println("");
          break;
        }

        if ( id == 17 && digits == GRID_NUM - 2 && firstDigitFlag == true)  //'-'
        {
            IV27DispData[digits + 1] |= (long long)1 << SEG[6];
        }
        else
        {

          for ( int i = 0 ; i < 7 ; i++ )
          {
            if ( CHAR[id][i] == 1 )
            {
              IV27DispData[digits] |= (long long)1 << SEG[i];
            }
            else
            {
              IV27DispData[digits] &= ~((long long)1 << SEG[i]);
            }
          }
          firstDigitFlag = false;
          digits--;
        }
      }
    }
  }
}
//init HV5812
bool initHV5812()
{ 
  SPI.begin();
  SPI.setFrequency(SPI_FREQ);
  SPI.setDataMode(SPI_MODE0);
  SPI.setBitOrder(MSBFIRST);
  pinMode( STROBE_PIN, OUTPUT );
  digitalWrite( STROBE_PIN, LOW );
  long long data = 0;
  sendData( data );
}
//send data to HV5812
bool sendData( long long data ) 
{
  uint8_t transfarData[5];
  transfarData[0] = ( data & 0x000000FF00000000 ) >> 32;
  transfarData[1] = ( data & 0x00000000FF000000 ) >> 24;
  transfarData[2] = ( data & 0x0000000000FF0000 ) >> 16;
  transfarData[3] = ( data & 0x000000000000FF00 ) >> 8;
  transfarData[4] = ( data & 0x00000000000000FF );
  //  Serial.printf("data:%x %x %x %x %x\n", transfarData[0], transfarData[1], transfarData[2], transfarData[3], transfarData[4]);

  SPI.writeBytes(transfarData, sizeof(transfarData));
  digitalWrite( STROBE_PIN, HIGH );
  delayMicroseconds(1);
  digitalWrite( STROBE_PIN, LOW );
}

表示データをchar配列で指定できるようにしました。文字列ではドット(.)にも対応するようにしました。

ダイナミック点灯の処理はタスクを利用し、コア0を使って自動でダイナミック点灯するようにしてあります。このためコア1で何か処理をしていても、表示は持続されます。

スポンサーリンク

点灯!

全ての桁が表示されるようになりました。

ダイナミック点灯しているので、ちょっと暗くなってしまいました。

これで、IV-27Mに自在に数字を表示できるようになりました。

次回は、カレンダー付きの時計にするためのプログラムを作っていきたいと思います。NTPではなくてリアルタイムクロックICを使ってみたいなぁと考えています。

2021.5.15 追加 つづきはこちらです。

追加終わり