動機
以前Twitterでこんな投稿を見つけました。
よく使うキーボードが発売! pic.twitter.com/BcXMyCX0Le
— サドルとペダル (@Pedalandsaddle) 2017年11月27日
「お疲れ様でした」や「ありがとうございます」等の定型文が入力できるキーボードです。
めっちゃ便利そうなので自分で作ってみることにしました!
仕様
とりあえずの構想はこんな感じで行きます
- キーを押したことをArduino Nanoで認識
- Arduino NanoからUSB経由でパソコンにデータを送信
- パソコン側でPythonプログラムがデータを受信
- プログラムが文字を打ち込む
必要なものと環境
- 300円デバイス、Arduino Nano
- ボタンスイッチ
- Python3.5(3.6以上だと動作しない可能性あり?)
- Windows 10(ここは何でも構いません)
ボタンとArduino
まず、ボタンを押したことをArduinoで検知する部分を作ります。押すと導通するスイッチとArduinoをはんだ付けでつなぎます。

スイッチを押すとD2~D4が0Vに落ちます。

Arduino側プログラム
スイッチの0V落ちを検知して、パソコンにデータを送るプログラムを作成します。
const int pin1 = 2; const int pin2 = 3; const int pin3 = 4; const int pin4 = 5; void setup() { Serial.begin(9600); pinMode(pin1,INPUT_PULLUP); pinMode(pin2,INPUT_PULLUP); pinMode(pin3,INPUT_PULLUP); pinMode(pin4,INPUT_PULLUP); } void loop() { int x1,x2,x3,x4; x1 = digitalRead(pin1); x2 = digitalRead(pin2); x3 = digitalRead(pin3); x4 = digitalRead(pin4); if(x1==0) Serial.println(1); if(x2==0) Serial.println(2); if(x3==0) Serial.println(3); if(x4==0) Serial.println(4); if(x1*x2*x3*x4!=0) Serial.println(0); delay(10); }
スイッチ1~4が押されていれば(電圧が0Vならば)その数字を、すべて押されていなければ(x1~x4がすべて5Vならば)0を送信します。
スイッチが押されていない時(端子に何も接続されていない時)の電圧は、通常は不安定にならないように5Vまたは0Vに接続しなければいけませんがArduinoでは内部的にプルアップまたはプルダウンを選べるようです。
pinMode(pin1,INPUT_PULLUP);
このプログラムだとボタンを押している間ものすごい速さでデータが送信され続けます。一見無駄なようですが、データを受ける側のタイミングが悪いと上手に受け取れなかったりするので、受ける側で対処することにします。
パソコン側Pythonプログラム
最後に、Arduinoからデータを受け取って文字を打ち込むプログラムを作ります。シリアル通信が簡単に書けるPythonを使っていきます。
#coding utf-8 #シリアル通信で受け取ったデータによって #定型文をエディタにペーストする import serial import time import pyautogui as pa import pyperclip def put_text(t): tmp = pyperclip.paste() #今のクリップボードのデータを一時保存しておく pyperclip.copy(t) #テキストをクリップボードに読み込む pa.hotkey("ctrl","v") #”Ctrl+V”を入力 pyperclip.copy(tmp) #保存しておいたデータをクリップボードに戻す return def main(): #通信ポートおよびボーレートの設定 ser = serial.Serial('COM4',9600) while True: #データを一行受信 x = ser.readline() #受け取ったデータによって処理を実行 if (x==b'1\r\n'): put_text("お疲れ様です") if (x==b'2\r\n'): put_text("ありがとうございます") #0が送られてくるまで受信のみ while (x!=b'0\r\n'): x = ser.readline() ser.close() if __name__=="__main__": main()
通信ポートの設定の部分はArduinoが接続しているポートに合わせて変えて下さい。(windowsなら「COM◯」、Linuxなら「/dev/ttyUSB0」等)。
pyautoguiやpyperclipなどのライブラリも適宜pipで入れて下さい。僕はpyautoguiがインストール出来ずに割と悩みましたがPython3.5を使うことで解決しました。この辺の原因は謎です。
pip install pyserial pip install pyautogui pip install pyperclip
エラー処理も何もしていないプログラムなので、参考程度に使用して下さい。
テストしてみる
ArduinoKeyboard.pyを実行しておきます。その状態でスイッチを押すと…

出来ました!
2017/12/26追記:
別の環境で動かそうとしてみたところ、serialパッケージが無いと言われる。pipでインストールしたけど…
pip install serial
エラーが…
serialじゃなくてpyserialらしい
pip uninstall serial pip install pyserial
これで動いた