はじめに
リレー80個で構成したデコーダ回路でニキシー管の表示を制御する「リレーデコーダ式ニキシー管時計」を作りました。
だいたいの仕様はこちらです。
- ニキシー管IN-14を8つ並べ、8桁の時計としました。
- 表示モードは3種類あり、
時刻モード(hh.mm.ss)、
日付モード(yyyymmdd)、
そして某アニメで登場したダイバージェンス風モード(1.048596)としました。
また、モードの切替は側面のスイッチで切り替えるようにしました。 - ESP8266のWROOM-02を使用しました。これは、Wi-Fi接続が可能であるためインターネットに接続しNTPサーバーから時刻を取得した。
※180 V近くの高電圧を扱うため、取り扱いには十分に注意しましょう。感電注意!
以前にYouTubeとニコニコ動画に投稿した解説動画を元に記述しています。画像などはそのまま流用しています。
使用部品
2019年11月でのものであるため、販売が終了している部品もあります
部品名 | 型番/容量 | 秋月通販番号 | 個数 |
---|---|---|---|
ニキシー管 | IN-14 | eBayで購入 | 8 |
抵抗 | 1/4W 680Ω | R-25681 | 1 |
1/4W 1kΩ | R-25102 | 2 | |
1/4W 2.2kΩ | R-25222 | 1 | |
1/4W 470kΩ | R-25474 | 1 | |
0805 10kΩ | 千石電商で購入 | 5 | |
0805 22kΩ | 千石電商で購入 | 8 | |
0.15Ω | 千石電商で購入 | 1 | |
コンデンサ | 400 V 100μF | P-10604 | 1 |
400 V 4.7μF | P-10600 | 1 | |
0805 0.1μF | P-13372 | 2 | |
0805 330pF | 千石電商で購入 | 1 | |
0603 0.1μF | P-12928 | 30 | |
ダイオード | 1N4148 | I-00941 | 1 |
UF2010 | I-00124 | 1 | |
GS1010FL | I-06014 | 80 | |
インダクタ | 220μH | P-03059 | 1 |
トランジスタ | 2SA1015 | I-06734 | 1 |
TBD62783 | I-11082 | 4 | |
FET | 2SK3234 | I-00244 | 1 |
リレー | 941H2C12D | P-01228 | 80 |
IC | NJM2360 | I-12365 | 1 |
74HC595 | I-10077 | 4 | |
ピンヘッダ | 両端ロング2x40 | C-12180 | 2 |
2x40 | C-00082 | 2 | |
ピンソケット | 2x20 | C-00085 | 6 |
連結2x20 | C-02485 | 4 | |
足長10 mm 1x10 | C-07199 | 4 | |
丸ピンICソケット 1ピンSMD | P-12368 | 744 | |
スイッチ | 縦タクト | P-08077 | 3 |
横スライド | P-08789 | 2 | |
その他 | WROOM-02 | K-13646 | 1 |
DCジャック | C-06568 | 1 | |
3.3 VDCDCコンバータ | K-09980 | 1 | |
USBシリアル変換 | M-08461 | 1 |
回路
ブロック図
簡単に示したブロック図はこちらです。
ACアダプタから12Vの電源を供給し、そのままの電圧でリレーに、180Vまで昇圧してニキシー管に、3.3Vまで降圧してWROOM-02にそれぞれ供給します。
ここからは、電源(昇圧、降圧回路)、制御、リレーロジック回路について解説をします。
昇圧,降圧回路
昇圧回路の回路図はこちらです。
NJM2360を使用したチョッパ方式の回路を作りました。
出力付近の2kΩの可変抵抗を操作することで出力の調節が可能です。
この回路の入出力の関係(計算値)は以下の表になります。
入力電圧 | 12 V |
---|---|
出力電圧 | 180 V |
出力電流 | 13.9 mA |
ニキシー管は1つあたり1~2 mA程度の電流があれば十分ですが、8桁全てを同時に点灯させるスタティック点灯にしたかったため出力電流を13.9 mAと多めに取りました。
降圧回路は秋月電子のLXDC55を使用した3.3 V出力のキットを使用しました。
制御
メインの制御にはWROOM-02を使用しました。
これはArduinoIDEで開発ができWi-Fiが使えて安価(秋月でDIP変換版が650円)なマイコンです。
駆動には3.3 V電源が必要なため、降圧回路を用意しました。
マイコンからは、シフトレジスタ74HC595へ信号を送信し、トランジスタアレイTBD62783で信号のレベルを変換してリレーへ送ります。
信号は4ビットがニキシー管の1桁に対応しており、後述するリレーで構成されたデコーダ回路を通して変換されます。
WROOM-02への書き込みは、秋月電子のUSBシリアル変換モジュールを使ってPCからUSB接続で行います。
モード変換の際に使用するタクトスイッチを3つ用意し、それぞれでプルダウンしました。
制御部分の回路図はこちらです。
リレーロジック
リレーとは?
今回の回路で最も規模の大きい部分がこのリレーロジック回路です。
リレーとは、コイルを用いて電気信号を機械的な動きに変換し接点を物理的に開閉する部品です。
また、接点が移動する際に「カチッ」という音が鳴るため、今回のような時計に用いると秒針のような音が再現できます。
下の図はリレーの動作を表しており、矢印で示したコイルに電流を流すと接点が移動し赤色の接点同士が導通します。
今回は、C接点2回路の941H-2C-12Dを使用しました。
C接点とは、先程の図のようにコイルがOFFで導通する接点とONで導通する接点の2種類がある形式です。これが2つあるため、C接点2回路のリレーと呼ばれています。
また、このリレーはコイルが12 Vで駆動するため「制御」でトランジスタアレイを通して3.3 V出力のシフトレジスタの出力を12 Vに変換しました。
ニキシー管を扱う際にはリレーを使わずにドライバICを使う方法もありますし、こちらのほうが主流です。
わざわざリレーでロジック回路を組むには以下のようなデメリットがあると考えます。
-
物理的に接点が移動するため動作に時間がかかる
-
音が鳴る
-
ハンダ付けの箇所が多い(ICをが16箇所なのに対して、ほぼ同じ動作をするデコーダ回路は合計で80箇所)
-
サージ保護のダイオードが必要
しかし、リレーを使って回路を組むことのメリットとして、 -
ロマンがある
-
音も見方を変えれば大きなメリット
があると考えています。
サージとは、リレーへの入力をONからOFFにした際にリレーに入っているコイルから発生する逆起電圧のことであり、高電圧なため半導体素子などを壊してしまう恐れがあります。
そのため、回路をサージから保護するために並列でダイオードを接続するなどの対策が必要になります。
リレーで論理ゲート
今回のリレーでは、NOTゲートとANDゲートを簡単に作ることが出来ます。
NOTゲート
コイルを入力、コイルOFFで導通する接点を出力とするとNOTゲートを作ることが出来ます。
ANDゲート
コイル部分を入力A、その他のリレー端子を入力B、出力とします。
図のように、入力A(コイル)と入力Bが同時にONになった時のみ出力に電流が流れます。
NOTゲートとANDゲートを組み合わせることでNANDゲートが作れますので、理論上ではあらゆるロジック回路を組むことが出来ます。
ニキシー管IN-14
今回使用したニキシー管IN-14は、入力電圧が180 Vのアノードコモンです。そのため、デコーダ回路は表示したいピンをGNDに落とすことで制御します。
また、0~9の表示の他に左右にドットがありこちらも制御できるようにします。
リレーでデコーダ回路
真理値表
論理回路を設計するにあたって、まずは真理値表を書いてどのような動作にするのかを決定しておきましょう。
入力をD,C,B,Aの4ビット、出力を1つとしたときのデコーダ回路の真理値表を以下に示します。
D | C | B | A | 出力 |
---|---|---|---|---|
0 | 0 | 0 | 0 | 0 |
0 | 0 | 0 | 1 | 1 |
0 | 0 | 1 | 0 | 2 |
0 | 0 | 1 | 1 | 3 |
0 | 1 | 0 | 0 | 4 |
0 | 1 | 0 | 1 | 5 |
0 | 1 | 1 | 0 | 6 |
0 | 1 | 1 | 1 | 7 |
1 | 0 | 0 | 0 | 8 |
1 | 0 | 0 | 1 | 9 |
1 | 0 | 1 | 0 | ドット左 |
1 | 0 | 1 | 1 | ドット右 |
1 | 1 | - | - | 消灯 |
このとき、「-」はドントケアとしました。
この表から直接リレーの回路を考えようとしても、ちょっと難しいです。
そこで、表を図のようにDC,BAで分割し同じ入力の組で色分けをしてみました。
分割した表を元に、それぞれのグループの動作をするロジック回路を構成します。
リレーロジックその1
DCグループでの動作をするリレー回路を図に示します。
BAグループにおいても、「12 V」の部分をGNDに置き換えたのみで全く同じです。
リレーロジックその2
DCグループの回路とBAグループの回路を分割した真理値表を元に組み合わせることで各入力に対する出力を決定します。
例を挙げると、入力が[0,1,1,0]のときDCグループの[0,1]の出力とBAグループの[1,0]の出力をANDゲートで組み合わせることで、[5]の出力が得られるようにします。
こうして作成したデコーダ回路は以下の図の動作をします。
このデコーダ回路をニキシー管の桁数分用意しました。
デコーダ回路1つでリレーが10個、デコーダ回路を8つ作ったので全部で使用したリレーは80個です。
プログラム
プログラムの全体の流れは[起動]→[Wi-Fiに接続]→[NTPサーバーで時間取得]→[シフトレジスタに送信]となります。
以下にプログラムを示しますが、あくまで手元の環境で探り探りで動けばいいやといった感じなので記述やアルゴリズムがめちゃくちゃだったりします。
ニキシー管時計のプログラム
#include <ESP8266WiFi.h>
#include <time.h>
#include <Arduino.h>
#include <Ticker.h>
#include <FS.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
#include <ESP8266mDNS.h>
#define JST 3600*9 //標準時設定
Ticker ticker1; //割り込み設定
Ticker ticker2;
int latchPin = 13; // SRCLK
int clockPin = 12; // RCLK
int dataPin = 14; // SER
int sec0 = 0;
int sec1 = 0;
int sec2 = 0;
int min0 = 0;
int min1 = 0;
int min2 = 0;
int hour0 = 0;
int hour1 = 0;
int hour2 = 0;
int year=0;
int mon = 0;
int day=0;
int year1=0;
int year2=0;
int year3=0;
int year4=0;
int mon1=0;
int mon2=0;
int day1=0;
int day2=0;
int ran =0;
int ranstart = 0;
int rancheck=0;
bool btnflg=false;
int nixienum=0;
int delaytime[20]={198,165,137,114,95,79,66,55,50,50,50,50,50,50,50,50,50,50,50,50};
time_t t;
struct tm *tm;
const char *ssid = "SSID"; //接続するWi-FiのSSID
const char *password = "PASSWORD"; //接続するWi-Fiのパスワード
void myshift(int bit,unsigned long val ){ //シフトレジスタ用
for( int i = 0; i < bit; i++ )
{
if((val>>(bit-1-i))&1){
digitalWrite(dataPin,HIGH);
}else{
digitalWrite(dataPin,LOW);
}
digitalWrite(latchPin,HIGH);
digitalWrite(latchPin,LOW);
}
}
void myclock(){
if(!btnflg){
if(nixienum==0){
t = time(NULL);
tm = localtime(&t); //時間取得
sec0 = tm->tm_sec;
sec1 = sec0%10;
sec2 = sec0/10;
min0 = tm->tm_min;
min1 = min0%10;;
min2 = min0/10;
hour0 = tm->tm_hour;
hour1 = hour0%10;
hour2 = hour0/10;
Serial.print(hour2);
Serial.print(hour1);
Serial.print(".");
Serial.print(min2);
Serial.print(min1);
Serial.print(".");
Serial.print(sec2);
Serial.println(sec1);
digitalWrite(clockPin,HIGH);
myshift(4,hour2);
myshift(4,hour1);
myshift(4,10);
myshift(4,min2);
myshift(4,min1);
myshift(4,10);
myshift(4,sec2);
myshift(4,sec1);
digitalWrite(clockPin,LOW);
}else if(nixienum==1){
t = time(NULL);
tm = localtime(&t); //時間取得
year=1900+tm->tm_year;
mon=tm->tm_mon+1;
day=tm->tm_mday;
year1=year/1000;
year2=(year-year1*1000)/100;
year3=(year-year1*1000-year2*100)/10;
year4=year%10;
mon1=mon/10;
mon2=mon%10;
day1=day/10;
day2=day%10;
digitalWrite(clockPin,HIGH);
myshift(4,year1);
myshift(4,year2);
myshift(4,year3);
myshift(4,year4);
myshift(4,mon1);
myshift(4,mon2);
myshift(4,day1);
myshift(4,day2);
digitalWrite(clockPin,LOW);
}else if(nixienum==2){
digitalWrite(clockPin,HIGH);
myshift(4,1);
myshift(4,10);
myshift(4,0);
myshift(4,4);
myshift(4,8);
myshift(4,5);
myshift(4,9);
myshift(4,6);
digitalWrite(clockPin,LOW);
}
}
}
void randomout(){
for(int i=0;i<20;i++){
digitalWrite(clockPin,HIGH);
myshift(4,random(0, 9));
myshift(4,random(0, 9));
myshift(4,random(0, 9));
myshift(4,random(0, 6));
myshift(4,random(0, 9));
myshift(4,random(0, 9));
myshift(4,random(0, 9));
myshift(4,random(0, 9));
digitalWrite(clockPin,LOW);
delay(delaytime[i]);
}
}
void numwrite(int num){
digitalWrite(clockPin,HIGH);
for(int i=0;i<8;i++){
myshift(4,num);
}
digitalWrite(clockPin,LOW);
}
void setup() {
//SPIFFS.begin(); //SPIFFSを開始
Serial.begin(115200);
delay(10);
pinMode(latchPin, OUTPUT);
pinMode(clockPin, OUTPUT);
pinMode(dataPin, OUTPUT);
// prepare GPIO2
pinMode(16, INPUT);
pinMode(5, INPUT);
pinMode(4, INPUT);
//digitalWrite(16, HIGH);
//ticker2.attach_ms(200, randomout);
numwrite(0);
//ここからテンプレ
Serial.println();
Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
Serial.println(WiFi.localIP());
//ここまでテンプレ
Serial.println("getTime");
configTime( JST, 0, "ntp.nict.jp", "ntp.jst.mfeed.ad.jp");//ntpサバにアクセス
delay(1000);
myclock();
Serial.println("WriteTime");
//ticker2.detach();
ticker1.attach_ms(100, myclock); //1秒毎に時間取得(ntpには1時間に1回(?))
}
void loop() {
if(digitalRead(16)==HIGH){
if(nixienum!=0&&!btnflg){
btnflg=true;
randomout();
}
nixienum=0;
myclock();
}
if(digitalRead(5)==HIGH){
if(nixienum!=1&&!btnflg){
btnflg=true;
randomout();
}
nixienum=1;
myclock();
}
if(digitalRead(4)==HIGH){
if(nixienum!=2&&!btnflg){
btnflg=true;
randomout();
}
nixienum=2;
myclock();
}
btnflg=false;
delay(10);
}
モード切り替えのボタンは側面に配置し、それぞれのボタンを各モードに対応させました。
モードを切り替える際に、グラフのようにニキシー管のランダム表示の時間を変化させ段々と早くなるようにしました。
基板発注~組み立て
今回、回路図をKicadで作成したのでそのままPCBの設計に移りました。
基板をリレーロジック回路の層、電源&制御の層、ニキシー管を並べる層の3つに分けました。
発注先はFusionPCBで、$112ほどお金がかかりました。
基板が到着するまで10日ほどかかりました。
これらを組み合わせることでニキシー管時計の完成です。
動作している動画はこちらです。
https://youtu.be/xO3bj8Syb4U
あとがき
このニキシー管時計は構想から完成まで1年ほどかかり、PICマイコンでの制御やRTCモジュールを使用した回路を考えてみたりと試行錯誤の繰り返しでした。完成は1年以上前ですが、まだまだ沢山の人に見てもらいたくこの記事を書くことにしました。
こういった解説記事を書くことは初めてなので分かりづらい部分が多いと思いますが見つけ次第適宜修正していきたいと思います。
-
reiuniv
さんが
2020/12/30
に
編集
をしました。
(メッセージ: 初版)
-
reiuniv
さんが
2020/12/30
に
編集
をしました。
-
reiuniv
さんが
2020/12/30
に
編集
をしました。
-
reiuniv
さんが
2020/12/30
に
編集
をしました。
-
reiuniv
さんが
2020/12/30
に
編集
をしました。
Opening
3duilab
2021/01/17
ログインしてコメントを投稿する一個一個は簡単でもまとめて設計して組み立てるのは難しいし技術力が必要、デザインもいいです。リレーの音が時計っぽくていいです