VFD 時計

1. はじめに

2023年1月、シリコンハウスでVFD(蛍光表示管)が4個入り¥350円で売っていたので購入。春休みの工作としてこのVFDを用いた時計を制作しようと思う。

2. 回路設計

2.1 時刻の取得

今回はネットから時刻を取得しそれをVFDで表示させる。ネットへの接続は ESP32 のWiFi機能を使う。この方法により正確な時計ができるがWiFi環境下でないと動かない。
詳しくはこちら⇒ESP32でネットワーク上から現在時刻を取得する(NTP)

2.2 表示器

表示方法だが今回ダイナミック点灯を採用した。 すべてのVFDに一斉にデータを送り、高速で一つずつ順番に点灯させることでいい感じに表示できる。 ただ、写真を撮るとすべての桁でなく一部しか光っていないように見える。これは駅や電車の行き先表示をカメラで撮ると一部しか見えないのと同じ原理だろう。

図1: ダイナミック点灯

表示器は1桁につき7個(今回使う表示管は9個あるが7つしか使わない)のLEDがついておりどれを点灯させるかで0~9の数字を表示させることができる。 ESP32内の10進数の時刻のデータをVFDに表示させる方法だが、 1桁ずつ分解してデータを送信する。 例えば14時50分23秒だと1,4,5,0,2,3という数字を順番に出力する。
  Disp(5, timeInfo.tm_hour / 10 % 10);
Disp(4, timeInfo.tm_hour % 10);
Disp(3, timeInfo.tm_min / 10 % 10);
Disp(2, timeInfo.tm_min % 10);
Disp(1, timeInfo.tm_sec / 10 % 10);
Disp(0, timeInfo.tm_sec % 10);
コード1: 時刻の分解方法

そして0~9の数字と7個のセグメントの光り方のパターンを関連付ける。 例えば「1」は右側の2つのセグメントが光るのでマイコンが出力するデータは「B11111001」となる。 右から順にabc...に対応している(今回は右から順番にデータを送るので)。 すなわちこの場合bとcが点灯する。 シフトレジスタ74hc595についてはここでは特に触れないがマイコンからの入力信号3本で8本の出力を得るために使用している。 動作原理などはこちら(シフトレジスタ (74HC595) と Arduino を使って複数の LED を制御する方法)の記事がわかりやすいと思う。

図2: LD8035データシートより
2月20日

オペアンプを使って3.3Vの信号を12Vにレベルシフトしようとしていたが動作が不安定に感じることがある。 オペアンプの出力電圧が足りないのかもしれない。そこで、単純にトランジスタ2SC1815を使い12Vのオンオフ制御に路線変更しようと思う。

図3: オペアンプを使ったレベルシフト回路
コード2: ソースコード
  #include<WiFi.h>
#include<WiFiServer.h>
const char *ssid = "****";
const char *password = "****";

const byte segment[] = {25, 26, 27, 14, 22, 13}; //各桁カソードピン
const int PIN_CLOCK = 19;   //74HC595(SRCLK) → Pin 10
const int PIN_LATCH = 23;    //74HC595(RCLK) → Pin 9
const int PIN_DATA = 4;     //74HC595(SER) → Pin 8
const byte digit[] =       //7セグLED 点灯パターン
{
  B11000000, //0
  B11111001, //1
  B10100100, //2
  B10110000, //3
  B10011001, //4
  B10010010, //5
  B10000010, //6
  B11111000, //7
  B10000000, //8
  B10010000  //9
};

void setup ()
{
  // WiFi
  Serial.begin(115200);
  WiFi.mode(WIFI_STA);
  WiFi.disconnect();

  if (WiFi.begin(ssid, password) != WL_DISCONNECTED)
  {
    ESP.restart();
  }
  while (WiFi.status() != WL_CONNECTED)
  {
    delay(1000);
  }

  Serial.println("Connected to the WiFi network!");

  configTime(9 * 3600L, 0, "ntp.nict.jp", "time.google.com");
  //7seg
  for (int i = 0; i < 6; i++) {
    pinMode(segment[i], OUTPUT);
  }
  pinMode(PIN_LATCH, OUTPUT);
  pinMode(PIN_CLOCK, OUTPUT);
  pinMode(PIN_DATA, OUTPUT);
}
struct tm timeInfo;
char s[20];
void loop () {
  // Time
getLocalTime(&timeInfo);
sprintf(s, "%04d/%02d/%02d %02d:%02d:%02d",
        timeInfo.tm_year + 1900, timeInfo.tm_mon + 1,
        timeInfo.tm_mday,timeInfo.tm_hour,
        timeInfo.tm_min, timeInfo.tm_sec);
        Disp(5, timeInfo.tm_hour / 10 % 10);
        Disp(4, timeInfo.tm_hour % 10);
        Disp(3, timeInfo.tm_min / 10 % 10);
        Disp(2, timeInfo.tm_min % 10);
        Disp(1, timeInfo.tm_sec / 10 % 10);
        Disp(0, timeInfo.tm_sec % 10);
        Serial.print("time is ");
}

void Disp(byte keta, byte value) {
  for (byte j = 0; j < 6; j++) {
    digitalWrite(segment[j], LOW); // 全桁LEDをOFF
  }
  digitalWrite(segment[keta], HIGH);
  digitalWrite(PIN_LATCH, LOW);
  shiftOut(PIN_DATA, PIN_CLOCK, MSBFIRST, digit[value]);
  digitalWrite(PIN_LATCH, HIGH);
  delay(4);
  Serial.println(value);
}
2月21日

3.3Vから12Vへ変換する部分を次ような回路に変更しようと思う。 Bは常に抵抗、キャパシタを介して3.3Vに接続されておりEにLOWが入力されるとB-E間に電流が流れコレクタ電圧は約12Vとなる。 HIGHが入力されるとB-E間に電流が流れないので出力は0Vとなる。 こちら(トランジスタによるレベル変換回路とその高速化) のサイトの回路を使いました。

図4: トランジスタを使ったレベルシフト回路
回路とコードが決まった。以下に使う部品をまとめておく。
表1: 使用部品
名前 個数 備考
ESP32 1 WiFi付きマイコン
74HC595 1 シフトレジスタ
2SC1815 14 npnトランジスタ
LD8035E 6 蛍光表示管
4.7k 14 カーボン抵抗
1.8k 14 カーボン抵抗
470 6 カーボン抵抗
0.1uF 15 セラミックコンデンサ

3.組み立て

2月24日

4桁分のはんだ付けが終わった。74hc595が手元にないので点灯試験は後日行う。

2月26日

74hc595を基板に取り付けて起動してみる。 シリアルのモニタを開くとWiFiに接続し時刻の取得ができていることが確認できたが 時刻表示がうまくできていなかった。(全点灯していたり、一部のセグメントがつきっぱなしだったり、数字の表示順がバラバラだったり…) これはコードのピンの割り当ての順番と実際の配線が異なったり、 ベースと3.3Vの配線がはんだ不良が原因であった。ベースに入力がないとずっとONの状態になりつきっぱなしになるのでうまくダイナミック点灯できない。

図5: 表示の不具合

コードでピンの割り当てを変更したり、はんだ付け不良の部分を修正することでうまく表示できた。次は秒数の表示もしたい。

図6: 4桁の時刻表示
2月28日

図7: ユニバーサル基板裏面
残り二桁のVFDが手に入った。さすがに配線が多く追加の配線は大変だった。 コードのほうは2ピン出力を増やし、秒数を表示するコードを追加するだけである。 修正が終わったところで電源を入れてみる。

図8: 6桁の時刻表示
めっちゃかっこいい!
桁数が増え、見栄えがかなりよくなった
3月4日

最後にケース作りをする。Fusoin360でモデリングし、光造形機で3Dプリントした。 二次硬化し塗装ができたら完成。

図9: 3Dデータ 図10: 造形物 図11: 塗装したもの

以上、VFD時計を作ってみたという話でした。 レポート風のブログなのか、ブログっぽいレポートなのかよくわからなくなった。