LoginSignup
5
0

More than 1 year has passed since last update.

FPGAとリレーで打鍵音が楽しいキーボードの作り方

Last updated at Posted at 2022-12-06

はじめに

入力キーコマンドによりリレーがON/OFFしプロトタイプFPGAをリセットできる仕組みを作っていました。テストでリレーのON/OFFを繰り返してるとカチカチっという音が心地よく、ふと打鍵時にメカニカルな音が鳴りテンションが上がるキーボードを作りたくなりました。

開発環境

Windows 11
Vivado 2021.2

セットアップ

  • FPGA評価ボード Zybo (xc7z010clg400-1)
  • リレー OMRON G2R-1 5VDC
  • NチャネルFET BSS138-7-F
  • ショットキバリアダイオード RB168M-60TFTR
  • 抵抗
  • UART-USB変換回路

製作

リレーおよび周辺

例えば下図のようにリレー回路を組みます。DC5Vで動作するかっこいいリレーが日本橋で売っていたので使ってみました。今回使ったメカニカルリレーは入力側に一定の電圧を加えると、内部のソレノイドが磁気を発生し出力側のスイッチをON/OFFする部品です。機械的に動作するので、スイッチの開閉時にカチカチっと音がします。リレーはFETのゲートに小信号を与えることで動作させます。リレーに対し3.3Vの評価ボード出力信号を使っています。FET等の特性、定格に合わせて適宜抵抗の定数を調整します。また、ソレノイドはFETがOFFした瞬間は電流を流し続けようとするため、FETのドレイン側電圧が上昇(サージ電圧)し壊れます。そのため保護用にダイオードを挿入し電流を逃がす経路をつくっています。
Schematic_relay_2022-12-06.png

今回はリレーを2個使ってます。上の回路が2回路入ってます。
DSC_3588.jpg

UART-USB変換基板はこんな感じです。Zyboでも使えるPmodコネクタに合わせてピンヘッダを出しています。USB typeC、5V半二重通信や電源機能も付いた豪華な基板です。今回はnetPort3、netPort4より右の部分だけあれば問題ありません。
Schematic_com1_2022-12-06.png

便利なので通信以外の目的でPmodを使う場合でもこの基板を使っています。
DSC_3589.jpg

FPGA

基本的にはUARTとステートマシンのみのシンプルな回路です。今回は信号にかかわらず、入力があったかどうかだけ見ればよいので、RDY信号しか見てません。RDYがHIGHになったら、一定期間リレーをONし、その後OFFにします。

--UARTコンポーネントの入出力ポート(内部詳細は割愛)
RS232_2:RStop port map(CLK,RST2,TXD2,RXD2,CTS2,RD2,DATArev2,DATAsend2,F_busy2,RDY2,open);

--リレー制御部
process(CLK)
begin
if(CLK'event and CLK='1')then
    if(RDY2 ='1')then
--RDY2がHIGHになったらreg_keyboardをHIGH(リレーをON)し、タイマーのカウントを0にする。
        reg_keyboard <= '1';
        count_key <= 0;
    elsif(count_key =5000000)then
--タイマーが5000000(CLK周波数が125MHzなので40msec)になったら、reg_keyboardをLOW(リレーをOFF)し、タイマーのカウントを0にする。。
        reg_keyboard <= '0';
        count_key <= 0;
    else
--タイマーのインクリメント
        count_key <=count_key + 1;
    end if;
end if;
end process;

インターフェース

バックグラウンドで動作し、キー入力をUART出力したかったので簡単なプログラムを書きました。この辺はあまり詳しくないのでもっといいやり方があるかもしれません。

from pyhooked import Hook, KeyboardEvent, MouseEvent
import serial

ser = serial.Serial('COM1', 115200) #シリアルポートの設定
oldkey = [] #既に押しているキーを記憶するための空のリストを定義

def handle_events(args):
    global oldkey
    if isinstance(args, KeyboardEvent):
        if args.event_type == 'key down' and not(args.current_key in oldkey): 
            print(args.current_key)
            ser.write(str.encode(args.current_key)) #キーが押されたらそのキーのアスキーコードをシリアルで送る。
            oldkey.append(args.current_key) #送ったキーを記憶する。
        elif args.event_type == 'key up':
            oldkey.remove(args.current_key)  #キーが離されたらそのキーの記憶を消す。

hk = Hook()  # make a new instance of PyHooked
hk.handler = handle_events  # add a new shortcut ctrl+a, or triggered on mouseover of (300,400)
hk.hook()  # hook into the events, and listen to the presses

デモ

こんな感じで動きます。

参考

5
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
0