RP2040은 USB가 포함되어 있기 때문에 진행 하려고 했던 KeyPad 프로젝트를 위한 USB HID Keyboard 를 테스트 해 보았다.
기본으로 제공하는 키보드 예제 테스트 하니 잘 동작한다.
Arduino 기본 USB Keyboard 예제는 심플하고 간단해서 사용하기는 편한데 뭔가 좀더 복잡한 KeyBoard를 위해서는 아쉬운점이 있다.
#include "Keyboard.h"
const int buttonPin = 4; // input pin for pushbutton
int previousButtonState = HIGH; // for checking the state of a pushButton
int counter = 0; // button push counter
void setup() {
// make the pushButton pin an input:
pinMode(buttonPin, INPUT);
// initialize control over the keyboard:
Keyboard.begin();
}
void loop() {
// read the pushbutton:
int buttonState = digitalRead(buttonPin);
// if the button state has changed,
if ((buttonState != previousButtonState)
// and it's currently pressed:
&& (buttonState == HIGH)) {
// increment the button counter
counter++;
// type out a message
Keyboard.print("You pressed the button ");
Keyboard.print(counter);
Keyboard.println(" times.");
}
// save the current button state for comparison next time:
previousButtonState = buttonState;
}
좀더 다양한 기능을 사용하려면 TinyUSB를 사용하면 좋다.
컴파일 하니 에러 발생
In file included from C:\Users\jhpark\Documents\Arduino\libraries\Adafruit_TinyUSB_Library\examples\Composite\mouse_ramdisk\mouse_ramdisk.ino:17:
C:\Users\jhpark\Documents\Arduino\libraries\Adafruit_TinyUSB_Library\src/Adafruit_TinyUSB.h:31:2: error: #error TinyUSB is not selected, please select it in "Tools->Menu->USB Stack"
31 | #error TinyUSB is not selected, please select it in "Tools->Menu->USB Stack"
| ^~~~~
USB Stack을 TinyUSB로 하라고 한다.
컴파일 에러 없이 잘 동작한다.
RP2040 SSM EVM 보드에 맞도록 코드를 수정해서 스위치 누를때 마다 Key 코드가 전송되도록 테스트 해보았다.
#include "Adafruit_TinyUSB.h"
// HID report descriptor using TinyUSB's template
// Single Report (no ID) descriptor
uint8_t const desc_hid_report[] =
{
TUD_HID_REPORT_DESC_KEYBOARD()
};
// USB HID object. For ESP32 these values cannot be changed after this declaration
// desc report, desc len, protocol, interval, use out endpoint
Adafruit_USBD_HID usb_hid(desc_hid_report, sizeof(desc_hid_report), HID_ITF_PROTOCOL_KEYBOARD, 2, false);
uint8_t hidcode[] = { HID_KEY_A, HID_KEY_B, HID_KEY_ARROW_DOWN};
#if defined(ARDUINO_SAMD_CIRCUITPLAYGROUND_EXPRESS) || defined(ARDUINO_NRF52840_CIRCUITPLAY) || defined(ARDUINO_FUNHOUSE_ESP32S2)
bool activeState = true;
#else
bool activeState = false;
#endif
#define PIN_BUTTON1 D10
// the setup function runs once when you press reset or power the board
void setup()
{
#if defined(ARDUINO_ARCH_MBED) && defined(ARDUINO_ARCH_RP2040)
// Manual begin() is required on core without built-in support for TinyUSB such as mbed rp2040
TinyUSB_Device_Init(0);
#endif
usb_hid.setReportDescriptor(desc_hid_report, sizeof(desc_hid_report));
usb_hid.begin();
// led pin
pinMode(LED_BUILTIN, OUTPUT);
digitalWrite(LED_BUILTIN, LOW);
pinMode(PIN_BUTTON1, INPUT_PULLUP);
Serial.begin(115200);
// wait until device mounted
while( !TinyUSBDevice.mounted() ) delay(1);
}
uint8_t count=0;
uint8_t const report_id = 0;
uint8_t const modifier = 0;
int flag = 0;
uint8_t keycode[6] = {0,0,0,0,0,0};
void loop()
{
// poll gpio once each 2 ms
if (usb_hid.ready())
{
if (digitalRead(PIN_BUTTON1) == 0 )
{
if(flag == 0)
{
flag = 1;
keycode[1] = hidcode[1];
usb_hid.keyboardReport(report_id, modifier, keycode);
Serial.print("press=");
// delay a bit before attempt to send keyboard report
delay(50);
usb_hid.keyboardRelease(0);
}
}
else
{
if(flag == 1)
{
flag = 0;
Serial.println("unpress");
}
}
if(Serial.available() > 0)
{
int cmd = Serial.parseInt();
// look for the newline. That's the end of your sentence:
if (Serial.read() == '\n')
{
// print the three numbers in one string as hexadecimal:
if(cmd==1)
{
hidcode[1] = HID_KEY_A;
Serial.print("KeyCode Change:");
Serial.print(hidcode[0], HEX);
}
else if(cmd==2)
{
hidcode[1] = HID_KEY_B;
Serial.print("KeyCode Change:");
Serial.print(hidcode[0], HEX);
}
Serial.print(", ");
Serial.println(cmd, HEX);
}
}
}
}
// Output report callback for LED indicator such as Caplocks
void hid_report_callback(uint8_t report_id, hid_report_type_t report_type, uint8_t const* buffer, uint16_t bufsize)
{
(void) report_id;
(void) bufsize;
// LED indicator is output report with only 1 byte length
if ( report_type != HID_REPORT_TYPE_OUTPUT ) return;
// The LED bit map is as follows: (also defined by KEYBOARD_LED_* )
// Kana (4) | Compose (3) | ScrollLock (2) | CapsLock (1) | Numlock (0)
uint8_t ledIndicator = buffer[0];
// turn on LED if capslock is set
digitalWrite(LED_BUILTIN, ledIndicator & KEYBOARD_LED_CAPSLOCK);
Serial.println("OutReport");
#ifdef PIN_NEOPIXEL
pixels.fill(ledIndicator & KEYBOARD_LED_CAPSLOCK ? 0xff0000 : 0x000000);
pixels.show();
#endif
}
반응형