LoginSignup
14
13

More than 3 years have passed since last update.

DigisparkをUSBキーボードにして一発入力させてみた

Last updated at Posted at 2018-08-26

あらかじめセットしておいた動作をボタン一つでブワァァアアって実行してくれるキーボード(プログラマブルキーボードというそうですね)をDigisparkを用いて自作した際に多少ハマった点があったので,書き残しておきたいと思います.

環境

  • Arduino IDE 1.8.4
  • 中華Digispark

キーボードの動作はUSB2.0ポートを搭載したWindows8.1マシンで確認しています.

Digisparkとは

Digisparkはとっても小さくて安くて(性能が)カワイイ,Arduino互換ボードです.
開発環境の準備からLチカ,自動入力まではこちらの記事がとても参考になります.

DigiSparkでボタン入力を受け付けてPCにキー入力するまで

ハマった点

使用するピンについて

Didisparkには0番から5番まで計6本のGPIOピンが用意されていますが,USB機器として使用する場合は通信のため3,4番ピンが使用できなくなります.またLEDが1番ピン(世代が古いと0番)につながっています.

じゃあ残った0,2,5にスイッチをつないで,押されたら1ピンのLED光らせちゃおうかな!!と思ったのですが,モノによっては5番ピンもUSB接続で潰れるようです.

ですので入出力に安定して使えるピンは0,1,2番だけとなります(僕は3つキーがほしかったのでLEDはあきらめました).

sendKeyStroke()の引数について

Digisparkにキーを出力させる時に使うsendKeyStroke()関数ですが,引数は

  • 第一引数:押したいキー
  • 第二引数:同時押ししたいキー(省略可)

です.ハマりポイントですが,実際にキーを操作するときの操作順は関係ありません.

//Enterキーを押したことにする
DigiKeyboard.sendKeyStroke(KEY_ENTER);

//Alt + Enter(プロパティを表示)
DigiKeyboard.sendKeyStroke(KEY_ENTER, MOD_ALT_LEFT);

//N + Ctrl + Shift(フォルダの新規作成)
DigiKeyboard.sendKeyStroke(KEY_N, MOD_CONTROL_LEFT | MOD_SHIFT_LEFT);

sendKeyStroke()関数は指定されたキーの「押して離す(短押し)」を出力します.
長押ししたい場合はsendKeyPress()を使い,思う存分押してからsendKeyPress(0,0)で離します.

キーの指定について

先ほどキーをKEY_ENTERとかMOD_SHIFT_LEFTで指定しましたが,本来キーはIDで指定されるべきものです.これを使いやすいように,DigiKeyboard.hファイルでIDごとに定義してあります.

ただしヘッダファイルで定義されていないキーもありますので,それらはスケッチの冒頭で,自分で定義する必要があります.

#define KEY_ESCAPE 0x29    //EscキーのIDを定義しています
#define KEY_TAB 0x2B       //Tabキー
#define KEY_ZENHAN 0x35    //全角半角キー

DigiKeyboard.h を見てみて,ご所望のキーが見当たらなければ未定義です.

キーのIDは,usb.orgの公式リファレンスの53ページから始まる表を参照してください.
Universal Serial Bus HID Usage Tables
Usage ID(Hex)がそれにあたりますので0xのあとにそのIDを続けてください.十進数がお好みであればUsage ID(Dec)をそのまま記述しても構いません.

2020/3/15追記
USB.orgのサイトリニューアルにつきリンクが切れていたので修正しました

利用可能な文字について

Hello!と自動入力させたい場合に,1キーづつsendKeyStroke()はしないですよね.
この場合はprint()関数やprintln()関数の方が便利なわけですが,ここで問題になるのがUSキーボードと日本語キーボードのレイアウトの差です.以下のスケッチを書き込んだとします.

#include "DigiKeyboard.h"
void setup() {
}
void loop() {
  DigiKeyboard.sendKeyStroke(0);
  DigiKeyboard.print("https://");
  DigiKeyboard.delay(5000);
}

日本語キーボードを搭載したPCでDigisparkがこれを実行すると,実行結果は
https+//
となってしまいます.あれっ!?コロンはどこに行ったんや!!

実はキーボードレイアウトの差(USキーボードで:がある位置に日本語キーボードでは+があるなど)により,一部の記号はそのままでは正しく入力できません.僕が考えた解決策としてはあらかじめ誤作動を見越して置換しておくというのがお手軽かと思います.

記号を入力させたい場合は,必要に応じて以下のように置換してください.
置換の必要がないものや,エスケープシーケンスが必要なものもありますね.
kigou_okikae_large.gif

これを用いてやり直すと,先ほどのスケッチはこうなります.

DigiKeyboard.print("https\'//");

そして上の置換表を眺めているとあることに気が付きます.それは¥もとい\と,_と,|は置換できないという点です.「円マーク」「バックスラッシュ」「アンダーバー」「あとこのなんかよくわかんないけどよく使う縦棒」はUSキーボードでその位置にキーが存在しない=置換のしようがない=自動入力できないのです(これは痛い)

2018.8.29追記:ヘッダファイルをいじったら解決できました.
解決法に関する記事を書きましたのでこちらを参照してください.
DigiKeyboardが日本語キーボード搭載PCで記号を正しく出力しない問題を解決する

DigiKeyboardあれこれ

そのほか,ハマってないけどふぅーんと思った点もあったので参考までに書きます.

sendKeyStroke(0);って何よ

入力の始めにいつもあるこいつは何かと思ったら

this is generally not necessary but with some older systems it seems to
prevent missing the first character after a delay
(スケッチ例Keyboard.inoより引用)

とのことで,文字の欠落を抑えるためにダミーのキー操作を出力させているようです.

普通のdelayじゃダメなの

DigiKeyboard.delay()って長くて面倒だなと思ったのですが,

It's better to use DigiKeyboard.delay() over the regular Arduino delay()
if doing keyboard stuff because it keeps talking to the computer to make
sure the computer knows the keyboard is alive and connected
(スケッチ例Keyboard.inoより引用)

とのことで,PCにキーボード接続死んだ?と思わせないように必要みたいですね.

まとめ

このように,新興ボードとあってまだまだ資料も少なくすこーし面倒なところもありますが,Digisparkは小さいながら遊べるヤツだと思います.

製造元のWikiも参考になるのでリンクを貼っておきます.
http://digistump.com/wiki/digispark

14
13
1

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
14
13