はじめに
入力キーコマンドによりリレーが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のドレイン側電圧が上昇(サージ電圧)し壊れます。そのため保護用にダイオードを挿入し電流を逃がす経路をつくっています。
UART-USB変換基板はこんな感じです。Zyboでも使えるPmodコネクタに合わせてピンヘッダを出しています。USB typeC、5V半二重通信や電源機能も付いた豪華な基板です。今回はnetPort3、netPort4より右の部分だけあれば問題ありません。
便利なので通信以外の目的でPmodを使う場合でもこの基板を使っています。
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
デモ
こんな感じで動きます。
参考