#meishi654 について
meishi654はBLE Micro Proに採用されているBluetoothコントローラ、通称「BLE654」を使用した名刺サイズの実験基板です。この基板はいわゆる開発者向け基板になります。また、すべての機能は実験段階であり、動作の保証は出来かねますことをご了承ください。 必要な部品はBMP同様およそ表面実装のものを使い、コンパクトにをまとめました。
基板上部に2.54mmピッチのパッドを用意し、SWDやUART、I2Cなどピンヘッダがあると便利な実験がしやすいようにしています(手配線が必要になります)。
1つ目のパターンは、裏面のみに部品を固めたもの。表面に部品を実装しないため、工場以外での実装も視野に。
この基板の用途としては以下を想定しています
- BLE Micro Proでは実現できなかったキー数の実験
- 一体型キーボード自作におけるatmega32u4など直付けコントローラを置き換えての実験
- BL654に搭載されているNFCアプリケーションの実験およびプログラム整備
- GCT製スルーホールUSB Type-Cコネクタを始めとした各種フットプリントの実証
- 各アプリケーション使用時におけるボタン電池寿命の実証
(以上は一例です)
BMPにおいて使用されているピンにはIOXXのように、またBMPにて未使用のピンもその多くを引き出しシルク印刷でnRF52840 QFN nameなどを表示しているため広く実験に使うことができるでしょう。
なお工場実装部品の検討(費用面)に際して、最低限必要になる部品のみを裏面に実装するパターンも用意しています。
すべての部品を実装する先2枚のような基板での製造を予定していますが、場合によってはひとの手によるはんだ付けが可能な部品を残したあと2枚のようなパターンでの製造になるかもしれません。
詳細はまた追ってお知らせします。
#answer40 の組み立てについて
answer40では、ビルドガイドに当たる記述を見なくても組み立てられるように基板上に部品リスト/マウント位置を印刷しています。
このキットは表面実装の部品を使用しているため、ある程度知識や経験のある方の購入/組み立てを想定しています。後日大半の部品を実装済みの基板もごく少数ですが頒布予定ですので、細かい部品のはんだ付けにあまり自信のない方は今しばらくお待ちください。 (更新2019/06/02)answer40と部品実装済みのセットanswer40Aを東京秋葉原の遊舎工房さんにて一週間(2019/06/01-2019/06/07)限定の自作キーボード郡遊伝としてお取り扱いいただいております! 部品の対応などがわからなくなった際は、以下に先日組み立てた際のビルドログを記しますので、こちらをご覧ください。また、ビルドログ中の写真にあるベリリウム銅ソケットはキットに含まれませんのでご注意ください。
qmk_firmwareのビルド環境を構築していない場合は、まず先に環境構築からお願いします。 2019年5月4日現在対応ファームウェアは私のフォーク先"answer40"ブランチにございます。
回路図についても以下に用意がございます。
USBコネクタ(J1)を取り付けます
テスターなどを用いて導通確認をします
リセットスイッチ(SW45)を取り付けます
水晶発振器(Y1)を取り付けます
向きに注意して、U1を取り付けます
ショットキーバリアダイオード(D45)を取り付けます
- 以降ダイオードの向きは基板の白枠にパッケージの帯が来るように合わせます
基板のパーツリストとマウント位置、チップ部品のシールを確認しながら残りの部品を取り付けます
- 黄色のシールはコンデンサ(C)、白のシールは抵抗(R)にそれぞれ対応しています
- 基板表面のSK6812MINI(D46,D47)はレンズ脇の切り欠きが右下に来るように合わせます
キースイッチ実装の前に動作確認をします
- USBハブなどを介してPCと接続し、lsusbやSystem ImformationなどでATmega32u4 DFU bootloaderなどと見えることを確認します
qmk_firmware配下/answer40ブランチ内で
make answer40:default:dfu
を実行し、リセットスイッチを押すことで書き込むことができますLEDを実装した場合、この段階で熱による破損、動作不良などがないことを確認します
動作確認が済んだ後、キースイッチの配置/レイアウトを決めます
- 下の画像のようなレイアウトを選ぶことができます
- Backspace部の1U+1U/2U/1.75U
- スラッシュ、右シフト部の2.75U/1U+1.75U/1.75U+1U
- スペースバー部の6.25U/2.75U+1.25U+2.25U
レイアウトを決めたら、スタビライザーを取り付けます
キースイッチを取り付けて、完成です!
#answer40 について
何枚かの基板を発注してきた私も、一体型キーボードとして動作する基板を作りたい気持ちになったので、作ってみました。このエントリは先日のツイートをひとまとめにしたものになります。詳しくはまた後日書くかもしれませんし、書かないかもしれません。
answer40は最大44キーを扱うことができる40%一体型自作キーボードです。 使用するキーキャップセットによってBを中心におよそ左右対称のレイアウトで使うことができます。
ゆかりキーボードファクトリーさんなどで手に入るtai-hao製のキーキャップセットをきれいに使うことができるほか、Shiftキーの多く含まれるキーキャップセットではスペースバーを3つに分割することができ、レイヤーを駆使したキーマップを大変便利に使うことができます。
この基板には試験的にジョグダイアルなどと呼ばれるレバースイッチ“TMHU28”用のフットプリントを追加しています。 プログラム側での対応がまだ済んでいないほか、最終的な配線は手で行う必要がありますが、左右カーソルキーやShift+スクロールホイールを割り当てることでさらに便利に使うことができるのではないかと考えております。
キースイッチを除くほぼすべての部品が表面実装になっているため、若干(?)のはんだ付けスキルは必要になるかと思います。 現在製作中の第2版ではPCBAできるようなデザインにする予定です。
自キと私とu16(universal16)
この記事は『自作キーボード #3 Advent Calendar 2018』11日目に寄せたものです。
進捗が渋いため 怪文書 ポエムでお茶濁しさせてください...ごめんなさい......
昨日の記事はENDO Katsuhiro(@ka2hiro)さんの『小斧(MiniAxe)ノススメ』です。
前置き)
昨年の冬コミ辺りからキーボードを自作する人をよく見かけるようになり「わたしもなにかやってみたいなぁ」と思って半年と少し。2018のMaker Faire Tokyoで自作キーボードの人たちが多く出展すると聞き、足を運びました。
当時HHKBを使っていた私は、ゆかりさん(https://twitter.com/eucalyn_)が設計したMint60という、いわゆる60%キーボードを左右で分けたデザインのものを求めて東京ビックサイトへと出掛けていきました。
前回MFTに出掛けたのは2年前で、その時の倍ほどの広さの会場に少し迷いながらウロウロとしていると、遊舎工房さんのブースを見つけます。ゆかり屋さんでのMint60の販売開始まで時間があったため、キースイッチテスターを触りにお邪魔しました。
そこで見かけたのがHelix Picoで、こちらも事前情報として『"ピコピコ"と音がなりコンパクトでとても可愛らしい自作キーボードキット』と聞いていました。家を出た時点でのお買い物リストには上がっていなかったのですが、どういうわけか東京ビックサイトを出たとき鞄の中に入っていました🤔
かわいい! #HelixPico #MFT2018 pic.twitter.com/Y9MBEogiuv
— せがた ひろみ (@keyaki_namiki) 2018年8月4日
ゆかり屋さんでの販売が開始される頃には、ブースに長い列ができていました。
販売開始30分前ですが、すでに待機列ができています。欲しいカラーにご希望のある方は早めに来て頂いたほうがいいかもです! #Mint60 #blockey #MFTokyo2018 pic.twitter.com/crFrZHO1zd
— ゆかり (@eucalyn_) 2018年8月4日
そこでMint60キーボードキットと一緒に買ったのが『ねこでも作れる!オリジナルキーボード』(通称"ねこつく")という本で、左右分割のキーボードをケースの3Dモデリングの方法まで触れられています。
(ここまでが前置き
ねこつく内ではブレッドボードを用いた実験などが紹介されていますが、手元に大量に余ったキースイッチを使ってなにかしたいなと、また、基板に直接スイッチを乗せるようにして、手作業でアクリル板に四角く穴を開けるケース加工の必要ないものにしたいなと思った私は、かねてから気になっていた基板発注をしてみようと思いました。
Kicadを初めて触る私にはkimio_kosakaさんの『KiCad 5.0入門実習テキスト「KiCad Basics for 5.0」』がとてもわかりやすく、参考になりました。
部品のフットプリントを配置して、線を繋いで。1つ目(厳密には2つ目ですが)のデザインはこのような、planck_thkの部品を取り除いたようなものになりました。
ですが、このデザインの外形サイズを見積もり画面に入力すると、10枚で$57.01、5枚でも$42程度と少し勇気のいる価格になりました。そこで、Twitterで見かけたFusionPCBの「$1で基板3枚を手に入れよう!」という企画の100mm x 100mm に収まるサイズで作り直しします。
そしてできたのが、universal16でした。
これは全く別の基板ですが、ユニバーサル基板にすることでこんな風に後から自分で配線できるため、いろいろなMCU/コントローラーや秋月電子さんのDIP化基板で2.54mmピッチに揃えてある電子部品をキーボード(キーパッド(?))に乗せて実験できて良さそうだなと思っています。
プリント基板って便利だなぁと思いましたこなみ pic.twitter.com/gyAJBeqKTt
— せがた ひろみ (@keyaki_namiki) 2016年10月25日
universal16についてはこちらにある他、多く発注した分をお譲りしていますのでこちらもご確認ください。
1枚目の基板を発注/受け取ってみて、見えてきた改善点をもとに2枚目(2種類目)を発注してと、作って見えてくる点が多くとても面白い経験でした。(2種類目が届いてまたやりたいことができました💪
またそれとは別に、plus4として20キーを配置できる基板を発注して、事実上の40キー キーボードとしてなにか作ることができそうだなと思っています(本当はここをまとめたかった)。
写真の、Mbedを使ったものはまた別の記事にすることとして、今日はこの辺りで締めさせていただきます。
無理矢理まとめるなら、「軽い気持ちで基板を発注してみましょう」という感じでしょうか。。。
この記事は、Corne-Cherry + Gateron Silent Black + Bigbang Ortholinear Kit で書きました。
12日目はanekosさん『寒いので目玉もキーボードも光らせる』です。
Moge Micro
それは、朝日の昇る少し前の話であった。
なんとはなしにキーキャップを外していたところ、universal16が僅かに傾いた。私はそれに気づかず、軽く力をかけてしまった。
『ガリッ』
キーキャップと机が立てた音と思って手に取ると、なにか"シガラミ"から解き放たれたような軽い感覚があった。
universal16は、時代の先をゆく『BLE Micro Pro』を搭載してはいない。
置き去りにされた"しっぽ"を横目に、私は悟った。
実 績 解 除
— せがた ひろみ@universal16 (@keyaki_namiki) November 24, 2018
S U C C E S S
M o g e M i c r o pic.twitter.com/VSB8ECHG5C
そう、これが世に言う『Moge Micro』であると。
さようなら、わたしのぷろまいこ。
短い間だったね。
対策をしっかりしてMoge Microを未然に防ぎましょう
以下はMC 英 (@hdbx) | Twitterさんの記事。
#universal16 v0.2をqmk_firmwareで使う(その2) ソフトウェアの用意
このエントリは以下の'続き'になります。配線にあたっての注意点などをお探しの場合はこちらをご覧ください
Note
universal16を使ってqmk_firmwareで新しいキーボードを作成する手順をご紹介します。私自身、qmk_firmwareでキーボードを作成する一連の操作は初めてのものであり、手順に誤りや不足がある可能性があります。この手順のコピペだけでなく公式のDocumentなどを読みながらの操作をおすすめします。当記事についてお気づきの点がありましたら、Twitter(@keyaki_namiki)までお知らせいただけると幸いです。
また、これ以降Git/GitHubの知識が必要になる箇所が多々あります。知らない単語やコマンドはコピペして実行するのではなく、適宜検索するなどしてどういう意味なのか、何をするコマンドなのかを確認するようにしてください。
Gitがインストールされていない場合はapt install git
やpacman -S git
、brew install git
などでインストールできる場合があります。詳しくは、[ git インストール ]
などで検索してみてください。
最後にもう一点、当記事はArchLinux、macOSに展開した環境の下作成されたものです。お使いのOSによってはこの記事の他に必要な手順が発生する可能性がありますことをご留意ください。
配線が済んだら、次にソフトウェアの準備をします。
qmkのrepository(以降、repo)からforkしたものを、手元の、任意のフォルダ下にcloneします。(GitHubのアカウントを持っていない場合は、qmkのrepoからcloneすることもできます)
git clone https://github.com/[YOUR_USERNAME]/qmk_firmware.git
cd qmk_firmware
などでqmk_firmwareのフォルダ内に入ります。
手元のrepoは自分がforkしたものを本流として持っているので、本家qmkのrepoをremoteのリストに追加します。
git remote add [本家とわかる略称、ここでは‘upstream’] https://github.com/qmk/qmk_firmware.git
これでforkした自分のrepoとは別に本家qmkのrepoからも差分を取得できるようになりました。
以下のコマンドで確認することができます。
git remote -v
出力が以下のようになっていることを確認します。
origin https://github.com/[YOUR_USERNAME]/qmk_firmware.git (fetch) origin https://github.com/[YOUR_USERNAME]/qmk_firmware.git (push) upstream https://github.com/qmk/qmk_firmware (fetch) upstream https://github.com/qmk/qmk_firmware (push)
次に、新しい作業用のbranchを用意します。
masterのbranchで作業/commitしてしまうと、本家qmkとの差分で競合が発生したときの調整が大変になってしまうためです。
git checkout -b [開発branchとわかる名称、ここでは‘dev_branch’] master
git status
を実行すると、いま作業しているbranchの名前が(例えば以下のように)わかるので、時々確認するのも良いかと思います。
On branch dev_branch Your branch is up to date with 'origin/master'. nothing to commit, working tree clean
これで、新しくキーボードを作成する準備が大方整いました。早速、やっていきましょう。
新しいキーボードを作成する上で、雛形となるファイルはutil/new_project.sh [あなたのキーボードプロジェクト名]
の実行にって生成することができます。今回は、
./util/new_project.sh universal16
を実行したと仮定して、進めていきます。
先程のコマンドを実行すると、keyboards/
配下にuniversal16
というフォルダができると思います。その中に以下のファイル群が含まれることを確認してください。
config.h
info.json
keymaps
keymaps/default/
keymaps/default/config.h
keymaps/default/keymap.c
keymaps/default/readme.md
readme.md
rules.mk
universal16.c
universal16.h
以降、特に言及がない限り"Hogehoge
というファイル"とあるものはkeyboards/universal16/
の下にあるものを指します。
まずは、config.h
というファイル。
@@ -1,3 +1,3 @@ /* -Copyright 2018 REPLACE_WITH_YOUR_NAME +Copyright 2018 keyaki-namiki @@ -22,8 +22,8 @@ /* USB Device descriptor parameter */ #define VENDOR_ID 0xFEED #define PRODUCT_ID 0x0000 #define DEVICE_VER 0x0001 -#define MANUFACTURER You -#define PRODUCT universal16 -#define DESCRIPTION A custom keyboard +#define MANUFACTURER keyaki-namiki +#define PRODUCT universal16 +#define DESCRIPTION 4x4 simple key_matrix with universal board @@ -30,4 +30,4 @@ /* key matrix size */ -#define MATRIX_ROWS 2 -#define MATRIX_COLS 3 +#define MATRIX_ROWS 4 +#define MATRIX_COLS 4 @@ -44,4 +44,4 @@ -define MATRIX_ROW_PINS { D0, D5 } -#define MATRIX_COL_PINS { F1, F0, B0 } +#define MATRIX_ROW_PINS { B1, B3, B2, B6 } +#define MATRIX_COL_PINS { C6, D7, E6, B4 } #define UNUSED_PINS
このファイルには、キーボードの配線(どのピンがどの回路に繋がっているかなど)や機能の設定について記述します。詳しくはこちら
今回は、Rows/Colsの部分のみを変更しました(ここでピンの接続について記述しますが、ピンの名前はArduinoで扱うときのものではない点に注意が必要です)。
次に、rules.mk
というファイル。
@@ -42,9 +42.9 @@ # Bootloader selection # Teensy halfkay # Pro Micro caterina # Atmel DFU atmel-dfu # LUFA DFU lufa-dfu # QMK DFU qmk-dfu # atmega32a bootloadHID -BOOTLOADER = atmel-dfu +BOOTLOADER = caterina
今回はコントローラにPro Microを使用するのでcaterina
を選択します。
続いて、universal16.h
というファイル。
universal16は4キーx4キーの16キーで構成されているため、デフォルトで用意される3キー+2キーの5キーで構成される部分を編集します。
@@ -29,9 +29,13 @@ #define LAYOUT( \ - K00, K01, K02, \ - K10, K11 \ -) \ -{ \ - { K00, K01, K02 }, \ - { K10, KC_NO, K11 }, \ -} + K00, K01, K02, K03,\ + K10, K11, K12, K13,\ + K20, K21, K22, K23,\ + K30, K31, K32, K33\ +) \ +{ \ + { K00, K01, K02, K03 }, \ + { K10, K11, K12, K13 }, \ + { K20, K21, K22, K23 }, \ + { K30, K31, K32, K33 }, \ +}
K00からK33まで、16キーを配置しているのがわかるかと思います。
最後にkeyboards/universal16/keymaps/
内の、default/keymap.c
というファイルを編集します。
@@ -24,7 +24,9 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { [0] = LAYOUT( /* Base */ - KC_A, KC_1, KC_H, \ - KC_TAB, KC_SPC \ - ), -}; + KC_KP_1, KC_KP_2, KC_KP_3, KC_UP,\ + KC_KP_4, KC_KP_5, KC_KP_6, KC_RIGHT,\ + KC_KP_7, KC_KP_8, KC_KP_9, KC_LEFT,\ + KC_KP_DOT, KC_KP_0, KC_KP_EQUAL, KC_DOWN\ +), +};
最初なので、16あるキーにnumpadの0-9と"." "="、矢印キーをあててみました。ここから更に、レイヤー機能などを使ってuniversal16を便利にすることができるでしょう。
キーコードについてはこちらに詳しくあります。
以上が、universal16を使ってqmk_firmwareで新しいキーボードを作成する上で最低限編集の必要なファイルになります。
さっそく、Pro Microに書き込んでみましょう。
これまでの手順を書いたとおりになぞっている場合、書き込みに必要なツールはまだインストールされていないかと思います。qmk_firmware
のある位置(pwd
などをして今居るディレクトリがqmk_firmware
であることを確認できます)に移動し、以下のコマンドを実行します。
./util/qmk_install.sh
このコマンドひとつで今使っている環境を調べて必要なパッケージをすべてインストールすることができます。
続いて、コンパイル。
make universal16:default
書き込みまでひと思いに済ませてしまうには、
make universal16:default:avrdude
を実行します。
書き込み用ソフトウェア、QMK Toolboxを使うこともできます。
。。。
どうでしょうか。
#universal16 qmk_firmwareで動かすところまでできた!!! pic.twitter.com/GuRpLFBjEN
— せがた ひろみ (@keyaki_namiki) November 23, 2018
カーソルキーがとても細くて見づらいかと思いますが、うまくいくとこんな風に機能します。
次はMxLEDBitPCB、通称"無限の可能性"を使ってもう2つ、キーを増やしてみます💪
#universal16 v0.2をqmk_firmwareで使う(その1) 配線/はんだ付け編
今回は"universal16 v0.2"についての更新になります。"universal16 v0.2"については、こちらをご覧ください。
Note
universal16を使ってqmk_firmwareで新しいキーボードを作成する手順をご紹介します。私自身、キーボードを作成する一連の操作は初めてのものであり、手順に誤りや不足がある可能性があります。この手順のコピペだけでなく公式のDocumentなどを読みながらの操作をおすすめします。また、当記事についてお気づきの点がありましたら、Twitter(@keyaki_namiki)までお知らせいただけると幸いです。
さて、universal16は多種多様なコントローラでの実験を想定した基板であり、ラスト数センチの配線がなされていません。まずは基板の準備から進めていきましょう。
基板には、それぞれ回路を引き出したパッドが用意してあります。
パッドの詳細については、こちらをご確認ください。
また、UnderglowLED用の信号線など、上部に置いてあるパッドの一部に「片面にしかないもの」があります。
これらのある面にスイッチを実装する予定の場合、まず最初にポリウレタン銅線などを使ってうら面(スイッチを実装しない面)に線を引き出してください。
ICソケットの間を抜ける線の画像
つづいて、ダイオードを実装します。
Cherry MX互換タイプのスイッチを使う場合、どちらの面にどのタイプのダイオードを使っていただいても問題ありませんが、なにかあった時のためにうら面に部品が来る状態をおすすめします。
Kailh LPスイッチを使い、ユニバーサル基板部分を右側に置いて基板を使う場合、SMDタイプのダイオードを使用してください。
ユニバーサル基板部分を左側に置いて、Kailh LPスイッチを使う場合、リードタイプのダイオードの脚が出ないように工夫する必要があります。横から見たときに基板から足が出ていると、プレートに傷がつき、破損する恐れがあります。
ダイオードが実装できたら、次に、スイッチをプレートにはめます。
(画像は脚(スペーサー)がついた状態ですが、この時点で特につける必要はありません。)
スイッチをはめ終わったら、プレートを基板に載せ、はんだ付けします。
ここまで作業を進めてしまうと、先述の上部パッドにアクセスすることが極めて困難になります。使いそうな配線は先に逃しておいてください。
スイッチのはんだ付けが終わったら、コントローラと基板を配線していきます。
今回はArduino Microの互換品、Pro Microを使用します。
どの配線をどのピンに繋いだかをしっかり正確にメモしておくことで、後々迷路のような配線たどりをしなくて済むことになります。(また、スペーサーの通る穴はGNDと接続がありますので、お近くのGNDが使用中の場合、ここに逃がすこともできます。)
実現したい機能、実験したい部品によってコントローラとの配線は変わってくると思いますが、今回はCol0-3をPro Microの5-8ピンに、Row0-3を15,14,16,10ピンにつなぎました。
(その2)に続きます。
LEDマトリクスの操作
前回、Pro Microとは別にLED制御用のArduino(ATmega328P:以降、328P)を用意することでuniversal16のLEDマトリクスを点灯させることができました。
今回もゆかりさん (https://twitter.com/eucalyn_)の「ねこでも作れる! オリジナルキーボード」とともに、Pro Microからキー入力をシリアル通信で受け取ってバックライトの点灯/消灯を操作してみます。
Pro Microはシリアル通信用のピンがUSBシリアルとは別に用意してあるためTxやRxとあるピンを使いますが、328Pにはシリアル通信用のピンがない(シリアルモニタが使えなくなる)ため、SoftwareSerialを使って通信を行います。今回はTxにA4ピンを、RxにA5ピンを使用し、それぞれUEWで配線してシリアル通信を受け取れるようにしました。
(とても分かりづらい配線の図)
次に、Pro Microから328Pに送るデータを考えます。今回必要なのは押された/離されたキーの座標のみですが、右側のユニバーサル基板部分で2つのロータリーエンコーダを扱いたいので、そのことを念頭に置いて2進数8桁1バイトの中に情報を詰め込みます。
0b0000000 _ matrix(0) or renc(1) *_ press or release **_ master or slave ***__ matrix position (row) *****__ matrix position (col) *******0 blank
少し見づらいかと思いますが、右から
- 1桁目は空白(いつでも0)
- 2~3桁目は列成分
- 4~5桁目は行成分
- 6桁目はmaster/slave判定
- 7桁目は押されたか/離されたか
- 8桁目はmatrixについての通信かロータリーエンコーダについての通信か
について必要な情報を2進数にして押し込んでいます。 master/slave判定は現時点で必要な情報ではないのですが、後々使うことになるかもしれないので、ひと桁分を用意しました。
以上を反映したPro Micro側のプログラムはこのようになりました。
const int Rowpin[] = {4,5,7,8}; const int Colpin[] = {10,15,14,16}; const int Cols = (sizeof(Rowpin)/sizeof(Rowpin[0])); const int Rows = (sizeof(Colpin)/sizeof(Colpin[0])); bool beforeState[Rows][Cols]; bool currentState[Rows][Cols]; byte sendData,readData; /* data description * * 0b0000000 * _ matrix or renc * if matrix(0) * *_ press or release * **_ master or slave * ***__ matrix position (row) * *****__ matrix position (col) * *******0 blank * if renc(1) * *_ renc0 or renc1 * **_ button press or release * ***_ rotate (en/dis)able * ****_ rotate direction * *****000 blank */ void setup(){ Serial.begin(9600); Serial1.begin(115200); Serial1.write("hello!"); // while(!Serial); Serial.println("Started."); for(int i=0;i<Cols;i++){ pinMode(Rowpin[i],OUTPUT); } Serial.print("num of Rowpin: "); Serial.println(Rows); Serial.println("Rowpin initialized."); for(int i=0;i<Rows;i++){ pinMode(Colpin[i],INPUT_PULLUP); } Serial.print("num of Colpin: "); Serial.println(Cols); Serial.println("Colpin initialized."); for(int i=0;i<Rows;i++){ for(int j=0;j<Cols;j++){ currentState[i][j] = HIGH; beforeState[i][j] = HIGH; } } Serial.println("initialize finished"); } void loop(){ int isPress = 0; delay(1); for(int i=0;i<Rows;i++){ digitalWrite(Rowpin[i],LOW); for(int j=0;j<Cols;j++){ currentState[i][j] = digitalRead(Colpin[j]); if (currentState[i][j] != beforeState[i][j]){ Serial.print("key "); Serial.print(i); Serial.print(","); Serial.print(j); if(currentState[i][j] == LOW){ Serial.println(" pressed!"); isPress = 1; } else { Serial.println(" released!"); isPress = 0; } beforeState[i][j] = currentState[i][j]; sendData = isPress << 5 | i << 3 | j << 1 | 0 ; Serial1.write(sendData); Serial.print("sent :"); Serial.println(sendData); } } digitalWrite(Rowpin[i],HIGH); } }
さて、これでPro Microからキー座標を送ることができるようになりました。
次に、328P側での挙動を考えます。水滴が落ちるようなアニメーション動作ができるととてもかっこいいのですが、まずは押したキーのバックライトが点灯するようにプログラムを書いてみました。
#include <SoftwareSerial.h> const int ledcols = 4; const int ledrows = 4; const int ledcol[ledcols] = {A2,A3,4,2}; const int srclk = 7; const int srclr = 8; const int sra = A0; const int srb = A1; //const int renc = 2; //const int rencr[renc] = {11,6}; //const int rencg[renc] = {10,5}; //const int rencb[renc] = {9,3}; const int Tx = A4; const int Rx = A5; SoftwareSerial keyserial(Rx,Tx); byte sendData,readData; //int r[renc] = {0}; //int g[renc] = {0}; //int b[renc] = {0}; int matrixDefault[ledrows][ledcols] = { {1,1,1,1}, {1,1,1,1}, {1,1,1,1}, {1,1,1,1} }; int keyPressed[ledrows][ledcols]={0}; void srclock(){ digitalWrite(srclk,1); digitalWrite(srclk,0); }; void setup(){ Serial.begin(9600); keyserial.begin(115200); while(!Serial); if(keyserial.available()){ readSerial(); } pinMode(srclk,OUTPUT); pinMode(srclr,OUTPUT); pinMode(sra,OUTPUT); pinMode(srb,OUTPUT); for(int i=0;i<4;i++){ pinMode(ledcol[i],OUTPUT); digitalWrite(ledcol[i],0); } Serial.println("initialized"); digitalWrite(srclk,0); digitalWrite(srclr,0); digitalWrite(sra,0); digitalWrite(srb,0); } void loop(){ int *matrix[ledrows]; for(int k=0;k<ledrows;k++){ matrix[k] = matrixDefault[k]; } for(int i=0;i<ledrows;i++){ int swapMatrix = 0; for(int j=0;j<ledcols;j++){ swapMatrix += keyPressed[i][j]; } if(swapMatrix != 0){ for(int k=0;k<ledrows;k++){ matrix[k] = keyPressed[k]; } break; } } for(int i=ledcols;i>=0;i--){ digitalWrite(srclr,1); digitalWrite(srb,1); for(int j=ledrows;j>=0;j--){ digitalWrite(sra,matrix[j][i]); srclock(); digitalWrite(sra,0); } digitalWrite(ledcol[i],1); delay(3); digitalWrite(srclr,0); digitalWrite(ledcol[i],0); } if(keyserial.available()){ readSerial(); } } void readSerial(){ int Row1, Col1, isPress; readData = keyserial.read(); Serial.println(readData); if(readData & 0b00000000){ } else { isPress = readData >> 5; Row1 = (readData & 0b00011000) >> 3; Col1 = (readData & 0b00000110) >> 1; Serial.print("key "); Serial.print(Row1); Serial.print(","); Serial.print(Col1); if(isPress){ keyPressed[Row1][Col1] = 1; Serial.println(" pressed!"); } else { keyPressed[Row1][Col1] = 0; Serial.println(" released!"); } } }
キーを押さない通常時は全点灯の状態にしたかったので、前回のプログラムに
- シリアル通信を受け取る関数を足し、その中で新しい配列
keyPressed
に今押されているキーの座標を追加 void loop()
の最初で押されたキーがあるかどうかを判断して、ひとつでもあるようなら新しい配列keyPressed
から点灯するLEDの座標を読み出す
ように手を加えました。
うまくいった! #universal16 pic.twitter.com/Fmv02tE8MR
— せがた ひろみ (@keyaki_namiki) November 15, 2018
(うごいている様子)
続きます。
一連の実験をお手元でお試しいただける基板、universal16 v0.2を少数ですがboothにて販売しています。プレート付属の基板キットを使って、あなただけの左手/右手デバイスを作ってみませんか?
#universal16+4
universal16を描いていて、1枚あたり16キーではなく20キーにすると2枚用意して両手で40キーのsplit-keyboardとしてつかえるのでは🤔と思ったので、作ってみました。(発注して到着待ち) 到着しました!(🔜後日更新の予定)
基本的にはuniversal16 Stemに4キー足しただけですが、左手用に(裏返せば右手用にも)スペースバー(といっても2Uですが)を置けるように最下部にスタビライザ用の穴を配置してみました。
qmk_firmwareを用意してサクッと使ってみるもよし、気になったコントローラでSplit Keyboardとして使ってみるもよし、気になった部品を実用的な[要出典]キーボードと一緒に試してみるもよしといった基板になるのではないでしょうか。
LEDマトリクスの点灯
universal16のキーバックライトLEDは基板上でマトリクス状に配線されており、シフトレジスタなどを操作することでキーごとの点灯ができるようになっています。
これもプログラムの勉強にと追加した機能のひとつなのですが、手持ちのシフトレジスタをきちんと扱おうとすると4ピン必要になるため、Pro Microとは別にArduino(ATmega328P)を用意してそこからLED全般を制御することにしました。
......? pic.twitter.com/r636gDRCde
— せがた ひろみ (@keyaki_namiki) October 29, 2018
今回使ったのはうちにあった74HC164というシフトレジスタですが、もう少し大きな電流を流せる部品をちゃんと選んだほうがいいかもしれません。
「何もわからん」とある通り、とても見るだけではわからない配線ですが、LED Cols 0-3にA2,A3,4,2を、74HC164のQA-QDにLED Rows 0-3を、などと配線しています。
何もわからん pic.twitter.com/dPNGssCZQy
— せがた ひろみ (@keyaki_namiki) November 2, 2018
諸々の配線を済ませた上で以下のプログラムを実行すると、左斜め対角線を消灯した状態になるかと思います。
const int ledcols = 4; const int ledrows = 4; const int ledcol[ledcols] = {A2,A3,4,2}; const int srclk = 7; const int srclr = 8; const int sra = A0; const int srb = A1; int matrix[ledrows][ledcols] = { {1,1,1,0}, {1,1,0,1}, {1,0,1,1}, {0,1,1,1} }; void srclock(){ digitalWrite(srclk,1); digitalWrite(srclk,0); }; void setup(){ pinMode(srclk,OUTPUT); pinMode(srclr,OUTPUT); pinMode(sra,OUTPUT); pinMode(srb,OUTPUT); for(int i=0;i<4;i++){ pinMode(ledcol[i],OUTPUT); digitalWrite(ledcol[i],0); } digitalWrite(srclk,0); digitalWrite(srclr,0); digitalWrite(sra,0); digitalWrite(srb,0); } void loop(){ for(int i=ledcols;i>=0;i--){ digitalWrite(srclr,1); digitalWrite(srb,1); for(int j=ledrows;j>=0;j--){ digitalWrite(sra,matrix[j][i]); srclock(); digitalWrite(sra,0); } digitalWrite(ledcol[i],1); delay(5); digitalWrite(srclr,0); digitalWrite(ledcol[i],0); } }
今回は適当なチップ抵抗の手持ちがなかったため、途中に余計なdelay(5);
を置いてごまかしていますが、ちゃんと抵抗値を選んだ上で、delayの値をもっと小さくするか、そもそもdelayさせないことでちらつきの少ないキーバックライトを実現できるでしょう。
抵抗値の高いチップ抵抗しか持ってなかったので部屋を暗くしないとダイナミック点灯っぽくならなくなってしまった...... #universal16 pic.twitter.com/hr25QavQNe
— せがた ひろみ (@keyaki_namiki) November 2, 2018
(キーバックライトが暗いの図)
いい感じ #universal16 pic.twitter.com/XqtNs8e5ld
— せがた ひろみ (@keyaki_namiki) November 2, 2018
動作イメージ(上の動画では配列の扱い方が逆になっていて右対角線が消灯しています)
次の課題はPro Microからキー入力を受け取ってバックライト点灯を操作するあたりでしょうか。。。