2020年8月16日日曜日

DigisparkでキーボードのLEDの状態を取得してみる

 久しぶりにDigisparkを引っ張り出してきたのでUSBキーボードエミュレーションして遊んでいたらキーボードのLED状態を取得できるような機能をライブラリに追加していた人がいたので試してみた。

キーボードのLEDステータスというのはCapsLockとNumLockとScroll LockのLEDの状態のこと。DigikeyboardだとそもそもPCからの情報取得は行わないようになっていたのでAdafruitのTrinket USBを使う方法しかなかった。

これが使えると何が便利なのかというとパソコンからDigisparkへのInputとして使えたり。
例えば、ScrollLockキーを押すとScrollLockのLEDが点灯するのでそれをDigikeyboardから読み込んでなにか動作をさせることが可能…
という具合。

まぁ普通にNumLock LED付きNumLock専用ボタンとかも作れちゃうわけだけど…

Digikeyboard with LEDs 作者のページには動画も上がっているので参考に。

というわけで早速試してみた。まずはGithubの作者のページから
DigiKeyboard.h
usbconfig.h
hidkeys.h
この3つのファイルをダウンロードしてくる。

そしたらエクスプローラで
%appdata%\..\Local\Arduino15\packages\digistump\hardware\avr\1.6.7\libraries\DigisparkKeyboard\
を開いて上書き。
これで準備は完了。

ちなみにこれをやるとDigiKeyboard.getLEDs()を使っていなかったとしてもフラッシュメモリの使用量が200バイトぐらい増えるので注意。

Digisparkの起動直後はうまく判別できなかったのでsetupにDigiKeyboard.delay(300)をいれて対策した。どうしてもLEDがついてないのに電源入った直後は起動していることになっている?これでもたま不安定…

とりあえず実用例がだいぶ前に作ったミツトヨのデジマチック出力をUSBキーボードとして入力してくれるデバイスぐらいしか思いつかなかったのでこいつを改造してみた。
スクロールロックキーを押すとミツトヨのノギスとかの測定データをUSBキーボードとして入力してくれる。これ、自分が持ってる海外製ノギスにもそのうち対応したい…

デジマチック出力の詳細は前回の記事を参考にしてもらうとして、これにSCROLL LOCKのLED状態を判別する部分を追加しただけ。フットスイッチでSCROLL LOCKを設定すればフットスイッチでも値を入力できる!かも?
追加したのはSCROLL LOCKのLEDがついたのを確認したら測定ボタンを押されたときの動作をした後、もう一回SCROLL LOCKをキーストロークしてSCROLL LOCKのLEDを解除するというだけ。(SCROLL LOCKを自動で解除しないと無限ループになってしまうし…)
まぁこういった使い方もできるということで…
// Use modified version of DigiKeyboard library
// https://github.com/Danjovic/DigistumpArduino/tree/master/digistump-avr/libraries/DigisparkKeyboard
#include "DigiKeyboard.h"

#define REQ 1
#define DAT 0
#define CLK 2
#define BTN 5//reset pin

void setup() {
  pinMode(REQ, OUTPUT);
  pinMode(DAT, INPUT_PULLUP);
  pinMode(CLK, INPUT_PULLUP);
  pinMode(BTN, INPUT_PULLUP);
  digitalWrite(REQ,LOW);
  DigiKeyboard.delay(300);
  if (DigiKeyboard.getLEDs() & SCROLL_LOCK){
    DigiKeyboard.sendKeyStroke(0);
    DigiKeyboard.sendKeyStroke(KEY_SCR_LOCK);
  }
 }

void loop() {
  DigiKeyboard.update();
  static boolean scrStatus = false;
  if (DigiKeyboard.getLEDs() & SCROLL_LOCK){
    scrStatus = true;
  }
  if(digitalRead(BTN) == LOW || scrStatus == true){
    byte mydata[14];
    digitalWrite(REQ, HIGH);
    for(uint8_t i = 0; i < 13; i++ ) {
      uint8_t k = 0;
      for (uint8_t j = 0; j < 4; j++) {
        while( digitalRead(CLK) == LOW) {
          DigiKeyboard.update();
        }
        while( digitalRead(CLK) == HIGH) {
          DigiKeyboard.update();
        }
        bitWrite(k, j, (digitalRead(DAT) & 0x1));
      }
      mydata[i] = k;
    }
    digitalWrite(REQ,LOW);
  
    uint8_t sign = mydata[4];
    uint8_t decimal = mydata[11];
    //uint8_t units = mydata[12];

    char buf[7];
    for(int lp = 0; lp < 6; lp++){
      buf[lp] = mydata[lp+5] + '0';
    }
    buf[6] = 0;
    float num = (atol(buf));
    switch (decimal){
      case 2:
        num = num / 100;
        break;
      case 3:
        num = num / 1000;
        break;
      case 4:
        num = num / 10000;
        break;
      case 5:
        num = num / 100000;
        break;
    }
    if(mydata[1] == 0xF && mydata[2] == 0xF && mydata[3] == 0xF){
      DigiKeyboard.sendKeyStroke(0);
      if(sign == 8){
        DigiKeyboard.print("-");
      }
      DigiKeyboard.print(num, decimal);
      DigiKeyboard.sendKeyStroke(KEY_ENTER);
      DigiKeyboard.delay(60);
      while(digitalRead(BTN) == LOW){
        DigiKeyboard.update();
      }
    }
    if(scrStatus == true){
      scrStatus = false;
      DigiKeyboard.sendKeyStroke(0);
      DigiKeyboard.sendKeyStroke(KEY_SCR_LOCK);
      DigiKeyboard.delay(300);
    }
  }
}

0 件のコメント:

コメントを投稿