M5Cardputer のサンプルプログラムに「M5Cardputer を USBキーボードにする」というものがありました!
これは、長らく探し続けていた「小型USB有線キーボード」…なのでは!
https://github.com/m5stack/M5Cardputer/tree/master/examples/Basic/keyboard/usbKeyboard
examples に M5Stack Cardputer を USB キーボードとして動作させるプログラムが…!
まさにこれは、長年探していた超小型USB有線キーボード!https://t.co/6EM1oQilP4— Nochi(ドウスル?▮) (@shikarunochi) October 17, 2023
シンプルな機能のみですが、USBキーボードとしてしっかり動作します!
USBキーボード試してみました。Windows 11日本語版からは日本語キーボード扱いされる感じです。(そう思って使えば大丈夫ですw)
カーソルキーが使えないです。Fn 押下時にキーコードの変換処理を追加する必要ありますね。
オートリピートも無いです。 pic.twitter.com/MJ03EJBSYg— Nochi(ドウスル?▮) (@shikarunochi) October 17, 2023
キーコードのみを返してるので、OSの標準キーボードとして認識されるみたいですね。日本語版Windowsからは日本語キーボード扱いされるので、記号と入力文字が合わなくなります。(そういうものだと思って使うなら問題なしです。)
Fnキーを押したときに、カーソルキーのコードを返すようにしました。これでカーソルキー使えます!
カーソルキーは、Fn ステータスが true の時に、該当 HID キーコードを書き換えるようにしました。https://t.co/suL3utI2kY pic.twitter.com/uV5kPLJxeL
— Nochi(ドウスル?▮) (@shikarunochi) October 18, 2023
あとは押しっぱなしの時のキーリピートが欲しいとこですね。いろいろ試してみた結果、keyboard.releaseAll() の位置を is Pressed() の else のところに移動するとバッチリでした。
keyboard.releaseAll() の位置を is Pressed() の else のところにすると、めちゃいい感じになりました! pic.twitter.com/CEYdMwAlpy
— Nochi(ドウスル?▮) (@shikarunochi) October 18, 2023
おそらく、近いうちに、本体単独でプログラムを入れ替え実行可能な Lovyan Launcher for Cardputer が登場すると思いますが、その前に、プログラム入れ替えの M5Stack-SD-Updater 単体で動作させてみました。
きっとまもなく @lovyan03 さんが Lovyan Launcher for Cardputer を作ってくれると思いますが、その前に @TobozoTagada さんの M5Stack-SD-Updater 単体動作を試してみました。
bin ファイル名直接指定で、プログラムを入れ替えてます。いい感じに動作します~。 pic.twitter.com/gqedkSMCc7— Nochi(ドウスル?▮) (@shikarunochi) October 22, 2023
「A」キーを押しながらリセットすることで、指定したプログラムに入れ替わります。
最初はトリガーを右上の G0 ボタンにしようと思ってたのですが、G0 + リセット だとダウンロードモードに入ってしまうのでしたw
個人用プログラムであれば、A を押しながらリセットでプログラムAを起動、Bを押しながらリセットでプログラムBを起動、みたいな決めうちで作っちゃうのも便利かも。— Nochi(ドウスル?▮) (@shikarunochi) October 22, 2023
プログラム全体はこういう感じです。(M5Stack-SD-Updater 対応で SD 関連も入ってます。)
/**
* @file usbKeyboard.ino
* @author SeanKwok (shaoxiang@m5stack.com)
* @brief M5Cardputer USB Keyboard test
* @version 0.1
* @date 2023-10-13
*
*
* @Hardwares: M5Cardputer
* @Platform Version: Arduino M5Stack Board Manager v2.0.7
* @Dependent Library:
* M5GFX: https://github.com/m5stack/M5GFX
* M5Unified: https://github.com/m5stack/M5Unified
*
* modified by @shikarunochi
*/
#include <SD.h>
#include <M5Cardputer.h>
#include <USB.h>
#include <USBHIDKeyboard.h>
#include <M5StackUpdater.h>
USBHIDKeyboard Keyboard;
SPIClass SPI2;
void setup() {
auto cfg = M5.config();
M5Cardputer.begin(cfg, true);
SPI2.begin(
M5.getPin(m5::pin_name_t::sd_spi_sclk),
M5.getPin(m5::pin_name_t::sd_spi_miso),
M5.getPin(m5::pin_name_t::sd_spi_mosi),
M5.getPin(m5::pin_name_t::sd_spi_ss)
);
while (false == SD.begin(M5.getPin(m5::pin_name_t::sd_spi_ss),SPI2)) {
delay(500);
}
M5Cardputer.update();
if (M5Cardputer.Keyboard.isKeyPressed('a')) {
updateFromFS(SD,"/helloWorld.bin");
ESP.restart();
}
M5Cardputer.Display.setRotation(1);
M5Cardputer.Display.setTextColor(GREEN);
M5Cardputer.Display.setTextDatum(middle_center);
M5Cardputer.Display.setTextFont(&fonts::Orbitron_Light_24);
M5Cardputer.Display.setTextSize(1);
M5Cardputer.Display.drawString("USB Keyboard",
M5Cardputer.Display.width() / 2,
M5Cardputer.Display.height() / 2);
USB.begin();
}
void loop() {
M5Cardputer.update();
// max press 3 button at the same time
if (M5Cardputer.Keyboard.isChange()) {
if (M5Cardputer.Keyboard.isPressed()) {
Keyboard_Class::KeysState status = M5Cardputer.Keyboard.keysState();
KeyReport report = {0};
report.modifiers = status.modifiers;
uint8_t index = 0;
for (auto i : status.hid_keys) {
auto fixedI = i;
if(status.fn){
switch(i)
{
//https://wiki.onakasuita.org/pukiwiki/?HID%2F%E3%82%AD%E3%83%BC%E3%82%B3%E3%83%BC%E3%83%89
case 0x36:fixedI = 0x50;break; //, LeftArrow
case 0x37:fixedI = 0x51;break; //. DownArrow
case 0x33:fixedI = 0x52;break; //; UpArrow
case 0x38:fixedI = 0x4F;break; /// RightArrow
}
}
report.keys[index] = fixedI;
index++;
if (index > 5) {
index = 5;
}
}
Keyboard.sendReport(&report);
//Keyboard.releaseAll();
// only text for display
String keyStr = "";
for (auto i : status.word) {
if (keyStr != "") {
keyStr = keyStr + "+" + i;
} else {
keyStr += i;
}
}
if (keyStr.length() > 0) {
M5Cardputer.Display.clear();
M5Cardputer.Display.drawString(
keyStr, M5Cardputer.Display.width() / 2,
M5Cardputer.Display.height() / 2);
}
} else {
M5Cardputer.Display.clear();
M5Cardputer.Display.drawString("USB Keyboard",
M5Cardputer.Display.width() / 2,
M5Cardputer.Display.height() / 2);
Keyboard.releaseAll();
}
}
}
platform.ini
[env:m5stack-cardputer] platform = espressif32 framework = arduino board = esp32-s3-devkitc-1 board_build.mcu = esp32s3 lib_ldf_mode = deep board_build.f_cpu = 240000000L lib_deps = https://github.com/m5stack/M5Unified https://github.com/m5stack/M5Cardputer https://github.com/pfeerick/elapsedMillis https://github.com/tobozo/M5Stack-SD-Updater