はじめに
こちらのページはTokyo City University Advent Calendar 2019 19日目の記事です。
前日の記事はナカX卜さんの「TAPの全体的なまとめになるレポートを書きます。」です!
もくじだよ~
ごあいさつ
- 皆様、はじめまして(震)。情報システム学科でひっそり大学生をさせていただいてるましまといいます。
人生初ブログな上に周りのつよい人たちの記事が怖すぎて震えながら書いています
色々拙い部分もあるとは思いますが最後まで読んで頂ければ幸いでございます....
なぜにキーボード?
基板設計からやる自作キーボードの流れ
- あんまり詳しく書きすぎると記事が終わらなくなっちゃうので全体の流れを書いていきます。詳しく知りたい所はお手数ですが自分で調べて見てくださいな...
まず必要なものを買う
- とにかく期限的にもすぐ着手しなきゃいけないのでひとまず
- Pro Micro
こいつにプログラムを書き込んで制御させる
いわゆる頭脳の部分
- タクトスイッチ
本物のキースイッチを使って実験してたらお金が足りないので
ひとまずタクトスイッチで検証する
- 抵抗
10kΩがあればいい
- その他 ジャンパピン, ブレッドボードなどなど
を購入
どんなキーボードを作るのか目標を建てる
とまあこんな感じな目標が立ちました
とりあえず簡易的な物を作って学ぶ
- まず第一にキーボードがどのような仕組みで動いているのかすらさっぱり分からないのでネットで見つけたゆかりさんの記事を参考にキーボードの仕組みの基礎的な部分を学んでいきます....
ものの30分程度で簡易的な2キーボードが...
回路は
1. VCCピン(電源ピン)から電源を引っ張る
2. スイッチにつなぐ
3. スイッチから信号を受け取るピンに線をつなぐ
4. 押していないときに0Vとなるよう抵抗を使って信号を受け取るピンからGNDにつなぐ
これをプルダウンというらしい
- 文字だけだとわからないと思うから図を書いてみる 下の図はPull Down回路を簡単に書いたもの
スイッチがオンになると電気がArduinoに流れて押されたことを判別できる
(もっと詳しく知りたい場合は「Pull Down Arduino」でググると多分出てくる)
- これを元に書いた回路図が下の写真
手書きだから汚いのはご愛敬
プログラムはごめんなさい適当に作って消しちゃいました....
ただ5分もしないうちに書けてたのでかなり単純にできちゃいます
とこんな感じであっさり2キーキーボードの原型が完成してしまった...
実はクソ簡単なんじゃね??
この思い上がりが後の地獄へと発展していく
回路を考える
- あまりにもかんたんに2キーキーボードの原型が完成してしまったのでどうせならもうちょっとキー数増やしたいなぁ... と思い、早速2x5キーの回路を考えてみました(は?)
仕組みを学ぶ
- 色々調べていくうちにArduinoの「Input Pull Up」という機能を見つけた。
簡単に言えばPull Downの逆バージョンでArduino内の抵抗を使うことで必要な抵抗の数を減らすことが出来るとのこと。
Pull Downについて
- まずはただの「Pull Up」の図
抵抗とスイッチの位置が逆になってること以外違いがない...
- 次はArduinoの「Input Pull Up」の機能を使うとこうなる
抵抗の部分が全部Arduino内で完結している(感動
こちらで用意するのはスイッチの部分だけなので回路はものすごく簡単になる
キーマトリクスってなに?
- そういえば遊舎工房で他のキーボードを眺めるとArduino一個に対してキーが30個近く繋がっていてこれではArduinoの足の数が足りないのでは?という疑問が生まれた
足とキーの数が合わないんだけど
- 足が足りなきゃ当然ながらすべてキーの判別はできない
- 色々なサイトを調べた結果、キー数の多いキーボードではキーマトリクスという物を使ってるらしい
- とりあえずキーマトリクスについて調べると
これがキーマトリクスらしいが...よくわからない...
Google先生に助けを求めて1時間、こんな情報を見つけました
「時間ごとに各列を管理する」
要は、出力1,2を同時に出力するのではなく交互に出力すればいいらしい
もっとかみ砕くだいて説明する
タイミング1
この場合、赤枠の中の出力1からのみ電気が流れる、そのため出力1 + 入力1~2の組み合わせのみが反応する
タイミング2
この場合、青枠の中の出力2からのみ電気が流れる、そのため出力2 + 入力1~2の組み合わせのみが反応する
2x2の回路ではあまり効果を実感できないかもしれないが5x5などキー数が多くなった時にわざわざ25ピン用意する必要はなく、5つの出力と5つの入力 つまり10ピンあれば5x5のキーボードを制御できてしまうのである...
基板設計をしていく
よくわかんないけどつよそう(初心者並感)
自動配線ではどうしても無理な配線が出てきてしまったりするのでそこは手作業で確認しながら編集していきます
設計変更の繰り返し
何か割とスイスイ進んでるし、どうせやるならいいもの作ってみんなを驚かせてやりたいやい!
とまあふざけた思い上がりをしたが為に
回路 基板の設計を何度もやり直すこととなります
廃案となった者たち
目標ってなんだよ
- 結局幾度にも渡る設計変更の末、はじめの目標は完全に消え失せ
5x5のキーボードになりました
これが完成したもの
初めて作るクセにやれ独創性だのやれオリジナリティなどとあーでもないこーでもないと設計を変更し続け、果たして本当に使いやすいのかエルゴノミクスを完全に無視したオレゴノミクスキーボードが完成します
基板を業者に発注する
- 今回はFusionPCBさんで注文しました。PCBを発注するにはまずガーバーデータの出力が必要になります。
業者によって出力の際の設定が違うのでしっかり確認しながらやりましょう
ファイルの中のプロットを選択
ガーバーデータを出力する
ドリルデータも出力する
全データを一つのファイルに圧縮してFusionPCBさんに送る
こちらの業者はファイルを送るとサイトでデータのチェックが出来ます
確認が終わったら枚数等の必要事項の入力
住所、クレジットカードを入力したら完了です
あとは出来上がるまで気長に待ちましょう...☕
(一週間から二週間ほどで届きます)
アキバでパーツあつめ
ソフトを書こう
ここからがやっと我ら情報システム学科生の本領です
#include "Keyboard.h"
//多分HIGHとかLOWはTRUE, FALSEにおきかわるんですかね
#define R_N 5 //行数 今回は5
#define C_N 5 //列数 今回は5
//Pinの情報
const int row_Pin[R_N] = {5, 6, 7, 8, 9};
const int col_Pin[C_N] = {10, 16, 14, 15, 18};
//ピン番号はちゃんと本体を見ながら打とう!
bool nowStatus[5][5]; //現在
bool beforeStatus[5][5] = {0}; //走査前
const unsigned char Keymap[R_N][C_N] =
{ //これが入力される文字たち
{0x35, 0x34, 0x33, 0x32, 0x31},
{0x74, 0x72, 0x65, 0x77, 0x71},
{0x67, 0x66, 0x64, 0x73, 0x61},
{0x62, 0x76, 0x63, 0x78, 0x7a},
{0x0, 0x20, 0xB1, 0x82, 0x80}
};
void setup()
{
// Pinのセットアップ
for(int i = 0; i < R_N; ++i) pinMode(row_Pin[i], OUTPUT);
for(int i = 0; i < C_N; ++i) pinMode(col_Pin[i], INPUT_PULLUP);
for(int j = 0; j < R_N; ++j)
{
digitalWrite(row_Pin[j], HIGH); //あくてぃぶろーなので一回HIGH統一ですべての走査を切る
for(int i = 0; i < C_N; ++i)
{//Activeになった時にLOWへと変化するため初期値はHIGHで固定
nowStatus[j][i] = HIGH;
beforeStatus[j][i] = HIGH;
}
}
Serial.begin(9600);
Keyboard.begin();
}
void loop()
{
for(int j = 0; j < R_N; ++j)
{
digitalWrite(row_Pin[j], LOW); //走査する列のピンをLOWへ変更
for(int i = 0; i < C_N; ++i)
{
nowStatus[j][i] = digitalRead(col_Pin[i]); //ピン状態の取得
if(nowStatus[j][i] != beforeStatus[j][i]) //以前の状態と違うときに
{
if(nowStatus[j][i] == LOW)
{
Keyboard.press(Keymap[j][i]); //Press!
}
else
{
Keyboard.release(Keymap[j][i]); //現在状態がHIGHということは押されてないと言うことなのでここでReleaseしよう
}
}
beforeStatus[j][i] = nowStatus[j][i];
}
digitalWrite(row_Pin[j], HIGH); //走査完了、もとに戻そう
}
}
- ここについてはあまり時間をかけられずもっと改善したい所が満載なので今後もっと改良していきたい
ケースをつくろう
もちろんキーボードを基板むき出しで使うわけには行かないので今回はアクリル板を使ってケースを作っていきます
KiCadからレイヤーごとのDXFファイルを出力する
ファイルからプロットを選んで...
これで「製造ファイル出力」を選べばKiCadのレイヤーごとのDXFデータが出力されます
AutoCADでDXFファイルをそれぞれ読み込んでいく
こんな感じで読み込めるようになる
AutoCAD内で編集する
ちなみにKiCadじゃなくてEagleで作るとこの作業がすごく楽になります
AutoCADからDWGファイルを出力する
DWGファイルをレーザー用のデータに加工してプリントする
加工中の写真
アクリルを切るのにはどのご家庭にもおいてあるレーザー加工機を使用しました
ちなみに必ず失敗するので自分でレーザーを使って作るときはアクリルを多めに買いましょう(経験談)
今回はキーボード裏面にアクリル彫刻をすることにしました
5分ほどで印刷完了 好きなergから推しヒロインを印刷した かわいい
さて組み立て!
なんとかアクリルも切り終わり外装も完成したので早速組み立てていきます が、 まあ当然というか干渉してしまってる部分などが見えてきましたしにたい
1.キーキャップ同士が干渉してしまう
- これを直すには基板の修正からしなければならないがどうしようもないのでもうこればっかりはしょうがないので、干渉する箇所はすべて手作業で削りました
つらい
2.リセットスイッチ用の穴を開け忘れた
- 一度切ってしまったアクリルに後から穴をどうにか開けるのも位置がずれそうで嫌だったので
見なかったことにしました
3.はんだつけする位置を間違いまくる
- アクリルを切り終わった勢いそのまま深夜にハンダ付けを始めてしまったのであらゆる所でハンダ付けするものを間違え、泣きながら剥がしてはつけ直す作業を続けていました( 当然ですがつけては剥がすなんてことを続けていたら基板にも部品にもダメージが入ってしまうのでハンダ付けする前はちゃんとどこに何をどのような向きでつけるのか確認してから作業しましょう!
はずす時にスルーホールが2つほど取れてしまったProMicroさんほんとごめんな
地獄のバグ潰し
深夜に泣きながらハンダ付けをやり直してなんとかすべてのパーツを乗っけることができたので早速以前作ったプログラムを焼いていこうとするも
まずPro micro認識されねぇ( ^ω^)
ここからまた数時間にかけてキーボードとの格闘がはじまります((
何故か認識されないProMicro互換品
何故かこんな感じになって認識されない
- 恐らく互換品使ってるからこんな羽目になってるんだとは思いますが、解決としてはProMicroにあるResetモード(RSTとGNDをショートさせると入れる)を動かすとBootloaderが立ち上がってくるのでそこで対象ボードにArduino Leonardoを指定して焼き込んであげるとLeonardoとして認識され使えるようになりました。
というわけで早速ProMicroに作ったソフトを焼いていきます...
一部のキーが全く認識されない
正直これが起こったときはもうオシマイダー!!の顔つきして布団にダイブしてひたすら枕を殴っていましたが何とかなりました
ProMicroのピン番号指定にご注意!
- ずっと図面眺めてたせいですっかり忘れていたのですが、ProMicroのピン番号は決して連番ではなく各ピンごとに数字が決められている のでしっかり画像を本体を見てピン番号を確認しましょう!
図面と本体で番号が違うのですっかり忘れていた
ハンダ付けちゃんとしよう!
ただ何故かソフトを修正しても一列だけ全く反応してくれなかったのでテスターでちゃんと通電しているのかを確認していきます。
テスターでチェックしたところ問題の列(A0ピンがINPUT_PULLUPのピンとして指定されていた)には微弱な反応があっただけでほぼ通電していない状態だったソフトの方は修正済みだし、アナログピンと共用だからといって何か問題があるわけでもないので微弱な反応があったという点も考慮にいれて再度しっかりハンダ付けすることにした...
そしたらあっさり何事もなかったように動きました()
ここだけで2時間近く悩んでいたので皆さんはちゃんとハンダ付け、しよう!
とりあえず完成!!
- やっとここまでたどり着きました(投稿数時間前)最後に用意したネジでキーボードにバックパネルをくっつければ...
うおおおおおお!
今回の感想
- 正直本当に期間がなさすぎてとりあえず完成を目指していたのでプログラム面や設計においてもかなり改善点を抱えてはいますが初作品にしてはよかったのかなって...
- 今後の改善点としてはソフトをQMK Firmwareと言われるフレームワークを使って書き直す、I2C用のジャックも実は実装しているので2つつなげての使用をできるようにしたいと思ってます
おわりに
正直途中から本当に19日目までに仕上がるのか不安で不安で仕方がなかったのですがギリギリ完成させることができました(完成したのは3日前)(記事は徹夜)ただただ本当に初めてなことまみれ過ぎて死ぬほど大変だったので皆さんはちょっとずつまずは小さいものから作っていきましょう(当たり前)
今回この記事を書くにおいて様々な知識やアドバイス、お手伝いをしていただいた情シス同期の田んぼくんにはマジで頭が上がりません本当にありがとうございました....間違いなく今回の企画がうまくいったのは彼の協力のおかげです、今度私のお金でご飯いっぱい食べに行きましょ
今回手伝わせていただいた田んぼと申します。まずはキーボードづくり&記事づくりお疲れ様でした。正直今回の企画時間的にも精神的にもギリギリでしたがとても楽しい時間を過ごさせていただきました。完成するか私もドキドキしてましたが無事完成してほっとしてます。機会があればまたやりましょう。本当にお疲れ様でした。(田んぼ)
(´;ω;`)ありがとう
明日は TCUAC 20日目 あいうさんの記事となります!
よろしくお願いします....