Arduino Uno R4をHID キーボードデバイスにしよう

__Arduino Uno R4__ の特徴としてUSBペリフェラルによるHID キーボードデバイスがあります。
今回は、__Arduino Uno R4__ のHID キーボードデバイスを触ってみましょう。
# USB HID デバイスとは？
パソコンのキーボードやマウスとして文字入力やマウスカーソルの操作をマイコンから行える機能になります。
キーボードやマウス入力機能を有するArduinoの純正としては __ATmega32u4__ を搭載した __Arduino Leonardo、Arduino Micro__ があります。
__Arduino Leonardo__ は4000円程度と割高な中、__Arduino Uno R4 Minima__ は USB対応の上、価格も __Arduino Leonardo__  より安価です。
また、換ボードは2000円程度とArduino Unoの互換ボードと比較すると割高とはいえ、安価といえます。
ただし、Uno形状でなくていい場合、Ch552やRaspberryPiPicoなどの方がさらに安価といえます。
# サンプルプログラム
Arduinoのサンプルプログラム __Keyboard and Mouse Control__ を参照します。

https://docs.arduino.cc/built-in-examples/usb/KeyboardAndMouseControl
# 必要なコード
使用には以下のコードが必要です。
```
#include "Keyboard.h"
  Keyboard.begin();
    Keyboard.write('x');
```
# Buttonプログラムに移植した例
これをButtonプログラムに移植します。

```
/*
  Button

  Turns on and off a light emitting diode(LED) connected to digital pin 13,
  when pressing a pushbutton attached to pin 2.

  The circuit:
  - LED attached from pin 13 to ground through 220 ohm resistor
  - pushbutton attached to pin 2 from +5V
  - 10K resistor attached to pin 2 from ground

  - Note: on most Arduinos there is already an LED on the board
    attached to pin 13.

  created 2005
  by DojoDave <http://www.0j0.org>
  modified 30 Aug 2011
  by Tom Igoe

  This example code is in the public domain.

  https://www.arduino.cc/en/Tutorial/BuiltInExamples/Button
*/
#include "Keyboard.h"

// constants won't change. They're used here to set pin numbers:
const int buttonPin = 2;  // the number of the pushbutton pin
const int ledPin = 13;    // the number of the LED pin

// variables will change:
int buttonState = 0;  // variable for reading the pushbutton status
int buttonState_old = 0;  // variable for reading the pushbutton status

void setup() {
  // initialize the LED pin as an output:
  pinMode(ledPin, OUTPUT);
  // initialize the pushbutton pin as an input:
  pinMode(buttonPin, INPUT_PULLUP);
  Keyboard.begin();
}

void loop() {
  // read the state of the pushbutton value:
  buttonState = digitalRead(buttonPin);
  if (buttonState != buttonState_old) {
    // check if the pushbutton is pressed. If it is, the buttonState is HIGH:
    if (buttonState == LOW) {
      // turn LED on:
      digitalWrite(ledPin, HIGH);
      Keyboard.write('u');
    }
  }
  buttonState_old = buttonState;
  delay(100);
}
````
buttonPinである２ピンをGNDに接続することでLEDとともに、uという文字が入力されます。
# 複数種類の入力に対応する
さらに複数の入力ピンに対応したプログラムにします。
```
/*
  Button to HID Custom!
  This example code is in the public domain.

  https://www.arduino.cc/en/Tutorial/BuiltInExamples/Button
*/
#include "Keyboard.h"

// constants won't change. They're used here to set pin numbers:
const int Button2 = 2;  // the number of the pushbutton pin
const int Button3 = 3;  // the number of the pushbutton pin
const int Button4 = 4;  // the number of the pushbutton pin
const int Button5 = 5;  // the number of the pushbutton pin
const int Button6 = 6;  // the number of the pushbutton pin

const int ledPin = 13;  // the number of the LED pin

// variables will change:
int buttonState2 = 0;   // variable for reading the pushbutton status
int buttonState3 = 0;  // variable for reading the pushbutton status
int buttonState4 = 0;  // variable for reading the pushbutton status
int buttonState5 = 0;  // variable for reading the pushbutton status
int buttonState6 = 0;  // variable for reading the pushbutton status

void setup() {
  // initialize the LED pin as an output:
  pinMode(ledPin, OUTPUT);
  // initialize the pushbutton pin as an input:
  pinMode(Button2, INPUT_PULLUP);
  pinMode(Button3, INPUT_PULLUP);
  pinMode(Button4, INPUT_PULLUP);
  pinMode(Button5, INPUT_PULLUP);
  pinMode(Button6, INPUT_PULLUP);

  Keyboard.begin();
}

void loop() {
  // read the state of the pushbutton value:
  buttonState2 = digitalRead(Button2);
  // check if the pushbutton is pressed. If it is, the buttonState is LOW:
  if (buttonState2 == LOW) {
    // Keyboard Write:
    Keyboard.write('w');
  }

  buttonState3 = digitalRead(Button3);
  if (buttonState3 == LOW) {
    Keyboard.write('e');
  }

  buttonState4 = digitalRead(Button4);
  if (buttonState4 == LOW) {
    Keyboard.write('r');
  }

  buttonState5 = digitalRead(Button5);
  if (buttonState5 == LOW) {
    Keyboard.write('t');
  }

  buttonState6 = digitalRead(Button6);
  if (buttonState6 == LOW) {
    Keyboard.write('y');
  }

  delay(100);
}
```
# 前と違うときだけ入力するプログラムにする
前のプログラムの場合、ボタンを押し続けると、

       delay(100);
毎に、文字入力が続いてしまいます。
1度検知したら2度目は送らないプログラムに変更します。
```
/*
  Button to HID Custom!
  This example code is in the public domain.

  https://www.arduino.cc/en/Tutorial/BuiltInExamples/Button
*/
#include "Keyboard.h"

// constants won't change. They're used here to set pin numbers:
const int Button2 = 2;  // the number of the pushbutton pin
const int Button3 = 3;  // the number of the pushbutton pin
const int Button4 = 4;  // the number of the pushbutton pin
const int Button5 = 5;  // the number of the pushbutton pin
const int Button6 = 6;  // the number of the pushbutton pin

const int ledPin = 13;    // the number of the LED pin

// variables will change:
int buttonState2 = 0;  // variable for reading the pushbutton status
int buttonState2_old = 0;  // variable for reading the pushbutton status
int buttonState3 = 0;  // variable for reading the pushbutton status
int buttonState3_old = 0;  // variable for reading the pushbutton status
int buttonState4 = 0;  // variable for reading the pushbutton status
int buttonState4_old = 0;  // variable for reading the pushbutton status
int buttonState5 = 0;  // variable for reading the pushbutton status
int buttonState5_old = 0;  // variable for reading the pushbutton status
int buttonState6 = 0;  // variable for reading the pushbutton status
int buttonState6_old = 0;  // variable for reading the pushbutton status

void setup() {
  // initialize the LED pin as an output:
  pinMode(ledPin, OUTPUT);
  // initialize the pushbutton pin as an input:
  pinMode(Button2, INPUT_PULLUP);
  pinMode(Button3, INPUT_PULLUP);
  pinMode(Button4, INPUT_PULLUP);
  pinMode(Button5, INPUT_PULLUP);
  pinMode(Button6, INPUT_PULLUP);

  Keyboard.begin();
}

void loop() {
  // read the state of the pushbutton value:
  buttonState2 = digitalRead(Button2);
  if (buttonState2 != buttonState2_old) {
    // check if the pushbutton is pressed. If it is, the buttonState is LOW:
    if (buttonState2 == LOW) {
      // Keyboard Write:
      Keyboard.write('w');
    }
  }
  buttonState3 = digitalRead(Button3);
  if (buttonState3 != buttonState3_old) {
    if (buttonState3 == LOW) {
      Keyboard.write('eu');
    }
  }
  buttonState4 = digitalRead(Button4);
  if (buttonState4 != buttonState4_old) {
    if (buttonState4 == LOW) {
      Keyboard.write('r');
    }
  }
  buttonState5 = digitalRead(Button5);
  if (buttonState5 != buttonState5_old) {
    if (buttonState5 == LOW) {
      Keyboard.write('t');
    }
  }
  buttonState6 = digitalRead(Button6);
  if (buttonState6 != buttonState6_old) {
    if (buttonState6 == LOW) {
      Keyboard.write('y');
    }
  }
  buttonState2_old = buttonState2;
  buttonState3_old = buttonState3;
  buttonState4_old = buttonState4;
  buttonState5_old = buttonState5;
  buttonState6_old = buttonState6;

  delay(100);
}
```
以上で、ボタンを押し続けても1度しか文字を送らないプログラムになったと思います。
コード自身は、非常に簡単なうえ、力業です。
__buttonState__ が __buttonState_old__ と異なる場合
かつ、__buttonState__ が __LOW__ の場合のみ、文字入力を行うプログラムになります。