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