« 【MMD】リベルニア鉄道の進捗。その4 | トップページ

2021年10月27日 (水)

蛍光表示管(VFD)で、表示器を作ってみた

 蛍光表示管(VFD)。ニキシー管などの、今はほぼ絶滅してしまった表示器とは異なり、いまだ現役の表示器である。
これを使って、8桁7セグメントLEDモジュールとインターフェース互換の表示モジュールを考えた。

上:VFD管(※ロシア製、IV-18) 下:8桁7セグメントLEDモジュール(74HC595使用、SPIモジュール)2

全てロジックIC(とドライバIC)のみで構成。とりあえず、基板形状はこんな感じに。
Vfd
この計画図は、今年(2021年)2月頃のもの。その後、ICの部品調達が厳しい事が判明し、この当時とは異なる部品を採用。

基板が届いたのが9月。(ICは裏面に搭載)
Vfd2
この時点でもまだ、部品が1点、届いていなかった。とりあえず組み立てる。Vfd2_20211026195101

基板の各部の寸法は問題なさそうだ。
残りの1点、とりあえず無くても表示可能な事に気付き(表示ムラが出るかも程度)、全て半田付けを終える。
早速、電源投入。(製作したのは黒い基板の部分、下の基板は市販の時計キット
Vfd11 Vfd21

問題なく表示された。
このように、既存モジュール互換にしておくと、表示系を別途用意せずともテストできて便利(ぉぃ

写真でジャンパー線が飛んでいる箇所は、発振回路。何故か正しく発振せず、強引な方法で動かしている。
この部分は後で直して、Rev.2版を作る(かもしれない)

原理上、表示ムラが起こりそうなものだが(左が明るく、右が暗くなる)、あまり気にならない。
届いていないICは無くても大丈夫そう…後日届いて、実装してみたが、違いは分からず。

これだけだと、ただの時計。せっかくなので、色々表示させてみたい。
というワケで、いつかは手を出さねば、と思ってたラズパイを購入、ケーブルを製作して接続してみた。
Spi2 2_20211026201201

Raspberry Pi の拡張コネクタ接続箇所は以下の通り。
Gpiopinoutdiagram2a

Pythonというものに触れたのも初めてだが、何だか簡単ですなコレ。昔のBASIC言語を思い出した。
で、なんやかんやプログラムしているうちに…あぁ、作ってもーた、ダイバージェンスメーター表示器…
動作させている動画を、ニコ動にUPしております。

この動画の冒頭で、タイマーっぽい事をしています。
この部分のソースコードを公開します。


  1. # coding: UTF-8
  2.  
  3. import spidev
  4. import time
  5. import datetime
  6. from dateutil.relativedelta import relativedelta
  7.  
  8.  
  9. #SPI設定
  10. spi = spidev.SpiDev()
  11. spi.open(0,0)
  12. spi.max_speed_hz = 1000000
  13.  
  14.  
  15. #表示データ(数値)定義
  16. disp_7seg_num = [0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90]
  17.  
  18.  
  19. #表示データ変換
  20. def cnv_to_7seg(chr):
  21.    ret = ""
  22.    if   chr == ".":
  23.       ret = 0x7F
  24.    elif chr == "-":
  25.       ret = 0xBF
  26.    elif chr == " ":
  27.       ret = 0xFF
  28.    else:
  29.       ret = disp_7seg_num[int(chr)]
  30.  
  31.    return ret
  32.  
  33.  
  34. #7セグ表示(STAT=0:数値として表示、STAT=1:時計用区切りドットあり表示)
  35. def send_data(data_chr, stat):
  36.    output_data = []
  37.    for x in data_chr:
  38.       Converted_data = cnv_to_7seg(x)
  39.       output_data.append(Converted_data)
  40.  
  41.    #区切りドット挿入
  42.    if stat == 1:
  43.       output_data[1] &= 0x7f
  44.       output_data[3] &= 0x7f
  45.       output_data[5] &= 0x7f
  46.  
  47.    #反転(表示器の仕様)
  48.    output_data.reverse()
  49.  
  50.    #表示
  51.    spi.xfer2(output_data)
  52.  
  53.  
  54. #3分タイマーメイン
  55. set_time = 180
  56. now_time = set_time * 1000000
  57. while True:
  58.  
  59.    time_str = "{0.hours:02}{0.minutes:02}{0.seconds:02}{0.microseconds:02}".format(relativedelta(microseconds=now_time))
  60.    send_data(time_str,1)
  61.    time.sleep(0.0093)
  62.    now_time -= 10000
  63.  
  64.    if now_time<0:
  65.       break
  66.  
  67.  

このプログラムを使用するには、いくつか準備が必要です。
まず、SPI通信を有効にします。設定変更したら再起動しましょう。

次に、PythonのSPIライブラリをインストールします。

$ sudo apt-get install python-pip
$ sudo pip3 install spidev

あと、上記プログラムは、数値を時刻に変換する際に dateutil ライブラリを使用していますので、それもインストールします。

$ pip install dateutils

ここまでで準備完了です。 

【プログラムの、ちょっとした解説(1)】

ネットを検索してみると、SPI通信に spi.xfer() を使用しているのを多く見かけます。間違ってはいません。
ですが、特にこの8桁7セグメント表示モジュールにおいては、これだと「ちらつき」が発生します。何故なのか。

この表示モジュールは(元にしたLEDモジュールもですが)、74HC595というシリアル→パラレル変換ICを使用しています。
1つのICあたり8bit、これを8つ数珠繋ぎにしていますので、1回の表示につき64bit分のシリアルデータを送ることになります。

74HC595の仕様書を見ると分かりますが、このIC、シリアル→パラレル用のD-FF、8bit保持用のD-FF、の2段構えになっています。
ですが、spi.xfer() だと、8bit(1バイト)送る度に、8bit保持D-FF用の”RCK"をアクティブにしてしまう…
つまり「表示」されてしまいます。表示とシフトを繰り返してしまうので、ちらつく、というワケです。

では、どうすればいいのか。

上記プログラムに記載ありますが、spi.xfer2() を使うのが正解です。
この関数は、与えられたデータを全て転送した後、最後に"RCK"をアクティブにします。ですので、ちらつきは発生しません。
シリアル→パラレル変換中は、変換用のD-FFが値を保持していますので、8bit保持D-FF用の”RCK"を毎回アクティブにする必要は
無いのでした。

【プログラムの、ちょっとした解説(2)】

このプログラムは、あまり正確なタイマーではありません。単純に time.sleep() で時間調整していますので、実行環境の
影響を受け易いです。まぁ、テストプログラムなので…
ガチでやろうとすると、タイマー割込み(スレッド処理?)を使用する事になるでしょう…

| |

« 【MMD】リベルニア鉄道の進捗。その4 | トップページ

コメント

この記事へのコメントは終了しました。