MENU

High-Speed対応の小型USB切替器を作ってみた

f:id:moutakusan:20210825230907p:plain:w400



最近はテレワークでの仕事が多くなり、家のデスクトップ環境の隣に会社のノートPCを置いて仕事をしております。
そうなると、家のPCで使っているキーボードを会社のノートPCにもつないで使いたくなるわけですが、意外と面倒なのがUSBの差し替えです。
一回一回は大した作業ではないのですが、毎回となると結構なストレスなんですよね。
これを何とかしようということで、今回はUSB切替器を自作してみることにしました。

この記事ではUSB切替器の制作過程を順を追って紹介します。

お知らせ

こちらの記事で紹介している基板は製品化して、スイッチサイエンスで頒布しています。

www.switch-science.com

興味を持っていただいた方はご覧ください。


では本編です。

こんな感じの仕様で作ります

今回は2入力1出力のUSB切替器を作ろうと思います。
PCからの入力が2ポート、デバイス側への出力が1ポートついていて、スイッチでUSBデバイスの接続先PCを切り替えられるようなイメージです。

f:id:moutakusan:20210813161316p:plain
USB切替器イメージ

出力側はせっかくならUSBハブが使えると便利なので、USB2.0 High Speed(480Mbps)の信号を通せることを目指します。
USB2.0って中々に高速なので、適当なスイッチや配線じゃダメだったりするんですよね。なので、USB切替専用のICを使うことにしました。

あと何気に考える必要があるのは、デバイス側への電源供給をどうするかです。
PCを切り替えるたびに、電源供給元も切り替えた側のPCに一緒に切り替えるのが自然な動作だと思うので、そのようにします。
こういう動作をさせるときに怖いのは電流の逆流です。ちゃんと回路を組まないと、片方のPCからもう一方のPCに電流が逆流したりするので危険です。

市販の機器でも電流が逆流してくるものがごくたまにあるので、機器を選ぶ際は気をつけましょう。

回路図を描いてみます

USB切替器の全体回路図はこういう感じにしました。

f:id:moutakusan:20210825224426p:plain
USB切替器回路図
pdfもあります↓
https://drive.google.com/file/d/1PDiqCJw0ZSpBnHbXeTuMrltwRQDd_-Q_/view?usp=sharing

次からはブロックごとに説明していきます。

USB信号切替回路

回路図左上のUSB信号切替回路の説明です。

f:id:moutakusan:20210813164351p:plain
USB信号切替回路

左側のJ101,J102がPC側のUSBポート、右側のJ103がデバイス側USBポートで、IC103がUSB信号切り替え用のICです。

ここでは、IC103はUSB2.0に対応した専用IC(TS3USB30E)を使用しています。
下図はデータシートからの引用で、左上がICを通してないとき、右上がICの一方のパスを、下がICのもう一方のパスを通した時のUSBの信号波形です。
(どっちがどっちのパスかはよくわかりません…。それぞれNC=Normally Close, NO=Normally Openとは記載ありますが、NormallyがHighとLowのどっちを指してるのか不明なので。)

f:id:moutakusan:20210813170016p:plain
USBの信号波形

いずれのパスを通った時でも、USB信号がほとんど劣化してないことがわかると思います。
なので、このICを使ってうまく設計してやればUSB2.0対応は行けるはずです。

回路図の上のほうに書いてあるSEL_Nは、物理スイッチSW101につながっています。
ユーザーが物理スイッチを切り替えるとIC103が連動して信号の接続を切り替えてくれるようになっています。

3.3V出力のリニアレギュレーター回路

回路図右上は3.3V出力のリニアレギュレーター回路です。

f:id:moutakusan:20210813221234p:plain
3.3V出力リニアレギュレーター回路

PCから供給される5Vから、IC103(USBスイッチIC)の電源を作っています。
IC103が高速信号扱ってるし、一応きれいな電源いるのかなぁということで、リニアレギュレーターを使いました。

USB電源切り替え回路

回路図左下はUSB電源切り替え回路です。

f:id:moutakusan:20210813221438p:plain
USB電源切り替え回路

PCから供給される電源が物理スイッチSW101に連動して切り替わるようになっています。
物理スイッチにはトグルスイッチを使いました。かっこいいので。

ここの回路の動作の説明は長くなるので、別の記事で紹介できたらなと思います。
LTSpiceを用いたシミュレーションにて動作も確認したので、それも一緒に紹介できたらいいな。

ということで、ここでは簡単な説明だけ。
それぞれのPCからの供給電源に対してPch-MOSFETが二個ずつ入っており、物理スイッチを介してFETをLowに引っ張ることで供給元の電源ラインが出力側に導通します。
トグルスイッチの構造上、上側の二つのFETと下側の二つのFETが同時にLowに引っ張られることはなく、二つの電源ラインは排他動作をします。

ちなみに、1ライン当たりFETを1個じゃなくて2個使用してるのは逆流防止のためです。
Pch-MOSFETはドレイン→ソースの中に寄生ダイオードがあり、電流は流れてしまいます。
今回のように電源ラインを2つくっつけてスイッチングする場合は、一方の電源から他方の電源へドレイン→ソース間を通っての逆流を防ぐために、ソースを背中合わせにしてFETを2つ配置します。

f:id:moutakusan:20210813230525p:plain
逆流防止のためにFETは2個配置
さらにFETはLowに引っ張られてないときは常にHighで固定したいので、抵抗を介してソース側の電源ラインにプルアップします。
その抵抗を介して電源が逆流したら困るのでダイオードも配置してあります。
 

回路の説明は以上です。

アートワークを描いてみます

今回は専用基板を起こすためにアートワークを描きます。
で、描いたアートワークがこちらです。

f:id:moutakusan:20210816224305p:plain
USB切替器アートワーク (表面)

f:id:moutakusan:20210816224357p:plain
USB切替器アートワーク (裏面)

基板を3Dビューアで見るとこんな感じです。

f:id:moutakusan:20210816225449p:plain
3Dビュー (表面)

手前の灰色の箱二つがUSB Type-B (PC側)、奥の箱がUSB Type-A(デバイス側)、左側の箱がトグルスイッチです。
PC側のUSBポート二つとトグルスイッチの両サイドにはそれぞれシルクで名前が書いてあって、トグルスイッチで倒した方のUSBポートが有効になるような感じで描きました。

机の上において使うときに邪魔にならないように、サイズは5cm x 5cmと、かなり小型にしました。

裏面はこんな感じ。

f:id:moutakusan:20210816230042p:plain
3Dビュー (裏面)

USBコネクタの足からUSBスイッチIC(IC101)のラインが太くなっているとこはポイントの一つです。
ここはUSBの信号線(D+/D-)で、差動インピーダンスをUSBの規格値である90ohmに近づけるようにラインを引いています。
インピーダンスの計算はこちらのサイトを使いました。

インピーダンス計算 - 基板クイック試作 - PCBWay

基板の製作と部品実装、そして完成!

今回はFusionPCBで基板を製作しました。

www.fusionpcb.jp

FusionPCBへの基板の発注方法については、また別の記事で紹介できたらと思います。

発注してからおよそ二週間で基板が手元に届きました。
それがこちらです。

f:id:moutakusan:20210825225354p:plain
きれいな青色の基板が届きました

青色の基板にしました。
きれいな青色です。

今回は4枚に面付けしました。
割るとこんな感じです。

f:id:moutakusan:20210825225758p:plain
USB切替器の生基板

5cm x 5cmしかないので、実際に触ってみるとめちゃくちゃ小さいです。

早速、部品を基板に実装しました。

f:id:moutakusan:20210826213034p:plain
表面
f:id:moutakusan:20210826213112p:plain
裏面

全部手ではんだ付けしたんですが、部品が小さくて難易度が高く、全部つけるのに1時間くらいかかりました。
USB切り替え用のIC(TS3USB30E)のピンなんて0.5mmピッチでしたからね。
かなり大変でした。

[追記]その後の成長↓

最後に周辺の4つの穴にスペーサーをつけて完成です!

f:id:moutakusan:20210825230815p:plain

f:id:moutakusan:20210825230907p:plain

作業机に置くとこんな感じ。 f:id:moutakusan:20210825231013p:plain

いい感じです!

お次は肝心の動作確認です。

動作確認してみます

キーボードをつないで動作確認

まずは、キーボードをつないでデスクトップPCとノートPCを切り替えられるか確認しました。
その様子がこちらです。

f:id:moutakusan:20210825234740g:plain
USB切替器にキーボードを接続して動作確認

ちゃんとトグルスイッチを切り替えることで、キーボードの接続先のPCを変えることができました!

キータイプ時の遅延というのも一切感じないです。
USB切替用のICには、信号の切替のみを行うパッシブタイプと信号を一度受けて叩き直すリドライバタイプがありますが、今回使用しているICは前者のため、より遅延が少ないっていうのもあるかもしれないです。
というか、パッシブタイプの場合は切り替えのみなので遅延は0のはずです。

HDDをつないで動作確認

今回はUSB2.0 High-Speed信号を通せるUSB切替器の自作を目指しました。
USB2.0が達成できているかの確認のために、外付けUSB HDDをUSB切替器あり/なしでPCに接続したときの通信速度の変化を調査しました。
通信速度の測定にはCrystalDiskMarkを使用しました。

crystalmark.info

その結果がこちらです。
f:id:moutakusan:20210826221341p:plain USB切替器あり/なしともに通信速度は約40MB/s(=320Mbps)出ており、USB2.0High-Speedで通信を行っていそうです。
ということで、USB2.0 High Speedモードでの通信が達成できていました!

スイッチサイエンスマーケットプレイスに委託

スイッチサイエンスには同人ハードウェアを委託頒布してくれるマーケットプレイスという仕組みがあります。
今回作ったUSB切替器も委託頒布してもらうことにしました。
方法は簡単で、まずはこちらのページを参考にメールを送るだけでOKです。
あとは担当者とやり取りしながら進めていくと、こういう風に製品ページを作ってくれて委託頒布してもらえるようになりました。
www.switch-science.com
これで私も同人作家の仲間入りです。

おわりに

今回はUSB2.0 High Speed対応の小型USB切替器を作りました。
自分で回路から設計したものが、基板になって、さらに実際に動いてというのはすごく感動しますね。
今回作ったUSB切替器はかなり実用的で、まだ使い始めて数日ですが、すでに手放せない予感です。

長い記事を最後までお読みいただきありがとうございました。
読んでくれた人の参考になってくれればうれしいです。

今回はこれで終わります。



おしまい。

AliExpressで買ったRTCモジュール(DS1302)をArduinoで動作確認

f:id:moutakusan:20210627234919p:plain:w400

RTCモジュール(DS1302)をAliExpressで購入したので、Arduinoにつないで動作確認しました。

RTCモジュールについて

購入時の価格は1個当たり$0.62でした。とんでもない安さです。

ja.aliexpress.com

本編とは関係ないですが、並行輸入したやつはamazonとかでも売ってたりします。
割高になりますが、すぐ来るのがメリットです。
Aliexpressは2週間から2か月とかかかりますからね。

せっかくなんで数個買ったんですが、送られてきたものは一つずつ個包装になってました。

f:id:moutakusan:20210619160110p:plain
個包装されてた。お菓子みたい。

さっそく開封! f:id:moutakusan:20210619160304p:plain f:id:moutakusan:20210619161821p:plain

作りは問題なさそうですね。端子側の基板カットが攻めすぎている気もしますが、実害はないでしょう。

乗ってるRTC ICはちゃんとDS1302と書いてあります。Maxim純正品なワケありませんが。
Maxim純正品だとICだけで1個当たり$1.86以上しますからね。あくまでもお遊び品です。

ともかく動かしてみましょう。

プログラム

Arduino IDEの"ライブラリを管理"メニューから検索できる、"RTC by Makuna"ライブラリを使うことにします。

f:id:moutakusan:20210627075452p:plain
RTC by Makuna

すると、スケッチ例もいくつか取り込まれるので、今回はDS1302_Simpleっていうやつを使って動作確認することにします。名前からして一番単純なので。

回路

前記のスケッチ例の接続に合わせて、ArduinoとDS1302をつなぎます。
こんな感じ。 f:id:moutakusan:20210627220647p:plain  

で、実際につなぐとこんな感じ。
f:id:moutakusan:20210627234919p:plain

電池はCR2032を使用していますが、DS1302ではトリクルチャージ機能がついており、充電式のボタン電池LIR2032を使うこともできます。
トリクルチャージ機能はデフォルトではOFFになってますので、CR2032を使う場合は特に設定する必要はありません、というか、してはいけません。
ざっくりと書いとくと、下記の図の感じでAddress0x90に0b0101XXXXを書き込めばトリクルチャージ機能がONになります。

f:id:moutakusan:20210627230520p:plain
トリクルチャージ機能の概略図

詳しくはデータシートをご確認ください。
繰り返しになりますが、くれぐれもCR2032ではトリクルチャージ機能を使わないようにご注意ください。

あと、ここで使ってるArduinoは普通に売ってるArduino UNOとかではなくて、ATMEGA328PをArduino化したものです。
詳しくはこちらの記事をご覧ください。

geekyfab.com

動作確認

つないだら、さっそく動かしてみましょう。

シリアルモニターを開き、通信速度をコード上の値(57600bps)に合わせ、書き込み実行アイコンをクリックして書き込みます。
すると、こんな感じでシリアルモニター上に現在の時刻が流れ始めました。

f:id:moutakusan:20210627224746p:plain

ちゃんと動いてそうですね。

RTCということで、30分ほどUSBケーブルを抜いてArduinoの電源をOFFにし、その後再び電源を投入してちゃんと時計が動いているか確認してみます。 f:id:moutakusan:20210627232301p:plain うん、大丈夫そうですね。ちゃんと動いてそうです。

あとは精度がどの程度かは気になるところですが、しばらく時間をおいてみてみないとわからないので、おいおい確認しようと思います。

というわけで、1個当たり$0.62の激安RTCモジュールはそれなりに使えそうなことがわかりました。



今回はこれで終わります。




おしまい。

ESP32とLEDマトリクスでテトリス風アニメーション時計を作る




64x32 LEDマトリクスとESP32でテトリス風時計を作ってみました。


この記事では、次のページを参考にしました。

GitHub - witnessmenow/WiFi-Tetris-Clock: A WiFi clock made of falling tetris blocks. For the ESP8266 or ESP32

材料、電源、配線について

材料、電源、配線については次の記事と同様になります。 geekyfab.com

詳しくは上記記事の"今回使った部品"から"LEDマトリックスとESP32を接続する"を参考にしてください。

コード

githubのコードをベースに修正していきます。

まず、無線LANのssidとpaswordの情報を記入します。

// Initialize Wifi connection to the router
char ssid[] = "SSID";     // your network SSID (name)
char password[] = "PASSWORD"; // your network key

次にタイムゾーンを日本に変更します。

//#define MYTIMEZONE "Europe/Dublin"
#define MYTIMEZONE "Asia/Tokyo"

次にOEピンの指定を使っているESP32ボードに合わせて修正します。

//#define P_OE 26 //TinyPICO
//#define P_OE 21 //Huzzah32
//#define P_OE 2 // Generic ESP32
#define P_OE 16 // ESP32-DevKitC

次に使用しているLEDマトリクスに合わせて、PxMATRIX display()を修正します。

// PxMATRIX display(32,16,P_LAT, P_OE,P_A,P_B,P_C);
PxMATRIX display(64,32,P_LAT, P_OE,P_A,P_B,P_C,P_D);
//PxMATRIX display(64, 32, P_LAT, P_OE, P_A, P_B, P_C, P_D, P_E);

また、前回同様にマルチプレクサにディレイをかける対策を追加します。

void setup(){
<中略>
    display.setMuxDelay(1,1,1,1,1)
<中略>
}

最後に使っているESP32ボードに合わせてdisplay.begin()を修正します。

//display.begin(16, SPI_BUS_CLK, 27, SPI_BUS_MISO, SPI_BUS_SS); // TinyPICO
display.begin(16); // Generic ESP32 including Huzzah

これでコードの修正は完了です。
修正後のコードは下記に置いています。

github.com

で、早速ESP32にコードを書き込んで動かしてみました。

テトリミノが降ってきて時間を表してくれました。カッコイイ!
今度、LEDマトリクスの周りを装飾して、置時計風にして部屋に飾ってみようと思います。



今回はこれで終わります。


おしまい。


GEEKY Fab.では思い出のゲームで遊ぼうをテーマにハードウェアを作ってます。
よかったら↓から見ていってください。


64x32LEDマトリックスをESP32で動かしてみた




Aliexpressで64x32LEDマトリックスが安く売っていたので、買ってみました。
64x32 matrix LED sign RGB P4 led module video wall P2.5 P3 P4 P5 P6 P8 P10 indoor screen full color display|full color led display|led displaycolor led display - AliExpress

Adafruitが出してる64x32 RGB LEDマトリックスの互換品だと思われます。
これをESP32とつないで動作させ、ドット絵とかちょっとした映像とかを映してみました。

今回はESP32で64x32LEDマトリックスを動作させるために必要な部材、接続方法、プログラムを紹介しています。
おまけでは「ひげのおじさん」と「うざい犬」のドット絵をLEDマトリックスで映したところを紹介しています。



この記事では以下のサイトを参考にさせていただきました。
GitHub - 2dom/PxMatrix: Adafruit GFX compatible graphics driver for LED matrix panels
RGB LED Matrix With an ESP8266 : 7 Steps (with Pictures) - Instructables

今回使った部品

今回使用した主要パーツは御覧の通りです。

パーツ 購入先
64x32 RGB LEDマトリックス Aliexpress
ESP32 DevKitC 秋月電子通商
5V 10A ACアダプタ (変換コネクタ付き ) Amazon(販売終了)

ACアダプタについて

ACアダプタの購入先は販売終了になっていました。同等性能のACアダプタは例えば、

とか使えるんじゃないかなと思います。安全規格も取ってるっぽいですし。
ただ、こちらは変換コネクタが付属してないっぽいので、別で購入必要かもしれません。
変換コネクタはどこでも売ってますが、例えばコレ(秋月電子リンク)とかコレ(Aliexpressリンク)とかですかね。

もし、電源の扱いに慣れてる方なら

とかでもいいと思います。

64x32 RGB LEDマトリックスについて

外観はこんな感じ。

64x32 LEDマトリックス 表面

64x32 LEDマトリックス 裏面

向かって左側が信号入力コネクタ、右側が信号出力コネクタ、真ん中が電源コネクタとなっています。
出力コネクタはLEDマトリックスを複数枚連結させるときに使います。

裏面の信号入出力コネクタ部にはピンアサインが記載されてなかったので一応ストアに聞いたところ、下記表をもらいました。

Adafruitのものと同じですね。
ピンの説明を加えた表を下に書いておきます。

No. ピン名 説明 No. ピン名 説明
1 DR1 赤データ1 2 DG1 緑データ1
3 DB1 青データ1 4 GND GND
5 DR2 赤データ2 6 DG2 緑データ2
7 DB2 青データ2 8 GND GND
9 A 光らせる行の選択用 10 B 光らせる行の選択用
11 C 光らせる行の選択用 12 D 光らせる行の選択用
13 CLK クロック 14 LAT シフトレジスタのラッチ用
15 OE シフトレジスタのEnable用 16 GND GND

GND以外の1~7ピンにRGBデータ信号を入れて、9~15ピンで制御することでLEDマトリックスに好きな映像を出力することができます。

LEDマトリックスとACアダプタを接続する

ACアダプタとLEDマトリックスの電源ハーネスとは、ACアダプタに変換をかませてこんな感じで接続します。
プラスが赤、マイナスが黒です。注意してください。

ACアダプタと電源ハーネスの接続
ハーネスの逆側は普通にLEDマトリックス裏面の真ん中のコネクタに接続です。

LEDマトリックスとESP32を接続する

今回はこちらのLEDマトリックスのライブラリを使用しようと思うので、readmeを参考にしながら下表のように接続していきます。

  • 入力コネクタ-出力コネクタ間接続

    入力コネクタ 出力コネクタ
    DR2 DR1
    DG1 DR2
    DG2 DG1
    DB1 DG2
    DB2 DB1
  • 入力コネクタ-ESP32間接続

    入力コネクタ ESP32 GPIO
    A 19
    B 23
    C 18
    D 5
    LAT 22
    OE 16
    CLK 14
    DR1 13
    GND GND

接続するとこんな感じです。

信号線配線

余談ですが、こちらのライブラリの面白いところは、入力コネクタと出力コネクタを接続することですべてのシフトレジスタを直列につなげてしまって、大きな一つのシフトレジスタとして扱ってしまっているところです。

つまりこういうこと
ですので、普通ならAdafruitのチュートリアルのようにRGB端子それぞれに信号線を接続する必要があるんですが、こちらのライブラリではDR1だけに信号線を接続するだけで済んでしまいます。

LEDマトリックスをESP32で光らせるためのプログラム

LEDマトリックスのライブラリのgithubからzipでダウンロードしてArduino IDEにインストールしましょう。
zipファイルからのインストールは スケッチ → ライブラリをインクルード → .ZIP形式のライブラリをインストールから行えます。

ライブラリのインストール

また、Adafruit GFX Libraryも必要なので、同じ手順でインストールしておきます。

では早速サンプルプログラムを動かしてみましょう。
ライブラリのReadmeのはじめでも見ることができる、"black_lives"を動かしてみます。

LEDマトリックスの仕様によってはサンプルプログラムに修正を加える必要があります。
念のため、修正を加える必要がある可能性のあるところを順番に見ていきます。

まずは、使っているLED Matrixのpixel数に合わせてサンプルプログラムの下記部分をコメントアウト/アンコメントします。

//PxMATRIX display(32,16,P_LAT, P_OE,P_A,P_B,P_C);
PxMATRIX display(64,32,P_LAT, P_OE,P_A,P_B,P_C,P_D);
//PxMATRIX display(64,64,P_LAT, P_OE,P_A,P_B,P_C,P_D,P_E);

今回使用しているのは64x32なので、デフォルトのままでOKです。

次に、LED Matrixのスキャンレイアウトに合わせてdisplay.begin(16)の引数を修正します。
今回使用しているLED Matrixは1/16なので、こちらもデフォルトのままでOKです。

これで準備完了です。
LED Matrixに電源を入れて、ESP32をUSBで接続し、プログラムを書き込んでみましょう。

すると…

表示がとびとび

映ってはいますが、表示がとびとびでおかしいですね。
この問題についてはReadmeのTroubleshootingの項にも書いてあって、使われてるマルチプレクサが低速な場合に起こることがあるらしいです。

対策としては、コード上にdisplay.setMuxDelay(1,1,1,1,1)を追加して、マルチプレクサに1us程度のディレイをかければ治るみたいです。
で、display.setMuxDelay(1,1,1,1,1)void setup()内に追加してみた結果がこちらです。

ちゃんと動いた!

無事、ちゃんと動かすことができました。
しっかりとフルカラー出ており、遅延も問題なし。
LEDの明るさについてもまぶしいくらいです。

おまけ (ドット絵を表示させてるところ)

ひげのおじさん

githubには髭のおじさんのドット絵のデータが上がっていましたので、表示させてみました。

It's-a me!!

UNDERTALEのうざい犬

UNDERTALEのうざい犬を作ってみました。
64x32のドット絵を書いて、変換サイトで変換して作りました。

うざい犬

「うざい犬」のデータはこちらです。

// Converted using the following site: http://www.rinkydinkelectronics.com/t_imageconverter565.php
uint16_t static uzaiinu[2048] ={
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,   // 0x0010 (16) pixels
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,   // 0x0020 (32) pixels
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,   // 0x0030 (48) pixels
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,   // 0x0040 (64) pixels
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,   // 0x0050 (80) pixels
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,   // 0x0060 (96) pixels
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,   // 0x0070 (112) pixels
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,   // 0x0080 (128) pixels
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,   // 0x0090 (144) pixels
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,   // 0x00A0 (160) pixels
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,   // 0x00B0 (176) pixels
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,   // 0x00C0 (192) pixels
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,   // 0x00D0 (208) pixels
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,   // 0x00E0 (224) pixels
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,   // 0x00F0 (240) pixels
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,   // 0x0100 (256) pixels
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,   // 0x0110 (272) pixels
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,   // 0x0120 (288) pixels
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,   // 0x0130 (304) pixels
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,   // 0x0140 (320) pixels
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xF800, 0xF800, 0x0000, 0x0000, 0x0000,   // 0x0150 (336) pixels
0x0000, 0xF800, 0xF800, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,   // 0x0160 (352) pixels
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,   // 0x0170 (368) pixels
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,   // 0x0180 (384) pixels
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xF800, 0xF800, 0xF800, 0xF800, 0x0000, 0x0000,   // 0x0190 (400) pixels
0xF800, 0xF800, 0xF800, 0xF800, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,   // 0x01A0 (416) pixels
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,   // 0x01B0 (432) pixels
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,   // 0x01C0 (448) pixels
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800,   // 0x01D0 (464) pixels
0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,   // 0x01E0 (480) pixels
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,   // 0x01F0 (496) pixels
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,   // 0x0200 (512) pixels
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800,   // 0x0210 (528) pixels
0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,   // 0x0220 (544) pixels
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,   // 0x0230 (560) pixels
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,   // 0x0240 (576) pixels
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800,   // 0x0250 (592) pixels
0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,   // 0x0260 (608) pixels
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,   // 0x0270 (624) pixels
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,   // 0x0280 (640) pixels
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800,   // 0x0290 (656) pixels
0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,   // 0x02A0 (672) pixels
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,   // 0x02B0 (688) pixels
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,   // 0x02C0 (704) pixels
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800,   // 0x02D0 (720) pixels
0xF800, 0xF800, 0xF800, 0xF800, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,   // 0x02E0 (736) pixels
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,   // 0x02F0 (752) pixels
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,   // 0x0300 (768) pixels
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800,   // 0x0310 (784) pixels
0xF800, 0xF800, 0xF800, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,   // 0x0320 (800) pixels
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xFFFF, 0x0000, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x0000, 0xFFFF, 0x0000, 0x0000,   // 0x0330 (816) pixels
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,   // 0x0340 (832) pixels
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xF800, 0xF800, 0xF800, 0xF800,   // 0x0350 (848) pixels
0xF800, 0xF800, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,   // 0x0360 (864) pixels
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x0000, 0x0000,   // 0x0370 (880) pixels
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,   // 0x0380 (896) pixels
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xF800, 0xF800, 0xF800,   // 0x0390 (912) pixels
0xF800, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,   // 0x03A0 (928) pixels
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x0000,   // 0x03B0 (944) pixels
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,   // 0x03C0 (960) pixels
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xF800, 0xF800,   // 0x03D0 (976) pixels
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,   // 0x03E0 (992) pixels
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,   // 0x03F0 (1008) pixels
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xFFFF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,   // 0x0400 (1024) pixels
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,   // 0x0410 (1040) pixels
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,   // 0x0420 (1056) pixels
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xFFFF, 0xFFFF, 0x0000, 0xFFFF, 0xFFFF, 0x0000, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,   // 0x0430 (1072) pixels
0xFFFF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xFFFF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,   // 0x0440 (1088) pixels
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,   // 0x0450 (1104) pixels
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,   // 0x0460 (1120) pixels
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,   // 0x0470 (1136) pixels
0xFFFF, 0xFFFF, 0xFFFF, 0x0000, 0x0000, 0x0000, 0xFFFF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,   // 0x0480 (1152) pixels
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,   // 0x0490 (1168) pixels
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,   // 0x04A0 (1184) pixels
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xFFFF, 0xFFFF, 0xFFFF, 0x0000, 0x0000, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,   // 0x04B0 (1200) pixels
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,   // 0x04C0 (1216) pixels
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,   // 0x04D0 (1232) pixels
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,   // 0x04E0 (1248) pixels
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xFFFF, 0x0000, 0xFFFF, 0x0000, 0xFFFF, 0xFFFF, 0x0000, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,   // 0x04F0 (1264) pixels
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,   // 0x0500 (1280) pixels
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,   // 0x0510 (1296) pixels
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,   // 0x0520 (1312) pixels
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xFFFF, 0xFFFF, 0x0000, 0x0000, 0x0000, 0x0000, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,   // 0x0530 (1328) pixels
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,   // 0x0540 (1344) pixels
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,   // 0x0550 (1360) pixels
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,   // 0x0560 (1376) pixels
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,   // 0x0570 (1392) pixels
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,   // 0x0580 (1408) pixels
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,   // 0x0590 (1424) pixels
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,   // 0x05A0 (1440) pixels
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,   // 0x05B0 (1456) pixels
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,   // 0x05C0 (1472) pixels
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,   // 0x05D0 (1488) pixels
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,   // 0x05E0 (1504) pixels
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,   // 0x05F0 (1520) pixels
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,   // 0x0600 (1536) pixels
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,   // 0x0610 (1552) pixels
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,   // 0x0620 (1568) pixels
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,   // 0x0630 (1584) pixels
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,   // 0x0640 (1600) pixels
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,   // 0x0650 (1616) pixels
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,   // 0x0660 (1632) pixels
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,   // 0x0670 (1648) pixels
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,   // 0x0680 (1664) pixels
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,   // 0x0690 (1680) pixels
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,   // 0x06A0 (1696) pixels
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,   // 0x06B0 (1712) pixels
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,   // 0x06C0 (1728) pixels
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,   // 0x06D0 (1744) pixels
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,   // 0x06E0 (1760) pixels
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,   // 0x06F0 (1776) pixels
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,   // 0x0700 (1792) pixels
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,   // 0x0710 (1808) pixels
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,   // 0x0720 (1824) pixels
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xFFFF, 0xFFFF, 0x0000, 0x0000, 0xFFFF, 0xFFFF, 0x0000, 0x0000, 0x0000, 0x0000,   // 0x0730 (1840) pixels
0xFFFF, 0xFFFF, 0x0000, 0x0000, 0xFFFF, 0xFFFF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,   // 0x0740 (1856) pixels
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,   // 0x0750 (1872) pixels
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,   // 0x0760 (1888) pixels
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xFFFF, 0x0000, 0x0000, 0x0000, 0xFFFF, 0xFFFF, 0x0000, 0x0000, 0x0000, 0x0000,   // 0x0770 (1904) pixels
0xFFFF, 0xFFFF, 0x0000, 0x0000, 0xFFFF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,   // 0x0780 (1920) pixels
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,   // 0x0790 (1936) pixels
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,   // 0x07A0 (1952) pixels
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xFFFF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,   // 0x07B0 (1968) pixels
0xFFFF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,   // 0x07C0 (1984) pixels
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,   // 0x07D0 (2000) pixels
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,   // 0x07E0 (2016) pixels
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,   // 0x07F0 (2032) pixels
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,   // 0x0800 (2048) pixels
};


今回はこれで終わります。
おしまい。


[追記]
こちらで紹介した64x32LEDマトリックスを使って、テトリス風アニメーション時計を作りました。
geekyfab.com
今回紹介した内容からコードを変更するだけで作れるので、おすすめです。

ATMEGA328PをArduinoとして動かしてみる

何番煎じの内容だよって感じですが、ATMEGA328PをArduinoとして動かしてみました。
とっても簡単でした。


実装にあたっては下記サイトを参考にさせていただきました。

Arduino as ISP and Arduino Bootloaders | Arduino

ATMEGA328P を Arduino として使う

Arduinoで作った回路の小型化(Arduino互換機の製作)(2) - しなぷすのハード製作記

回路を作る

Arduino UNO R3のオリジナルの回路図がこちらになります。

https://www.arduino.cc/en/uploads/Main/Arduino_Uno_Rev3-schematic.pdf

この回路図のZU4 (ATMEGA328P-PU)がArduinoとしてメインで動いています。
他にICはU1,U2,U3,U5が乗っていますが、それぞれ12V->5V変換IC、5V->3.3V変換IC、USB->Serial変換IC、オペアンプ(電源選択のためのコンパレーターとLED駆動のためのボルテージフォロワとして使用)であり、純粋にArduinoとして動かす分には不要です。

というわけで、今回作るArduino互換機の回路はこんな感じにします。

Arduino互換機 回路図

ブレッドボードに乗せるとこんだけ。(動作確認目的なので、C2とSW1は省略)

自作Arduino互換機
 

Arduino bootloaderを書き込む

ATMEGA328PをArduinoとして動かすにはArduinoのBootloaderを書き込む必要があります。
手元にProMicroがあるので、こちらを使って書き込みをしてみようと思います。

まずはProMicroにBootloader書き込み用のスケッチ(Arduino ISP)を書き込みます。

Bootloader書き込み用のスケッチ
次にProMicroとブレッドボードで作ったArduinoの回路とを下表のように接続します。
念のため接続はProMicroにUSBを接続していない状態で行います。

信号 ProMicro Pin名 Arduino(ATMEGA328P) Pin No.
電源 VCC 電源
GND GND GND
SCK 15 19
MISO 14 18
MOSI 16 17
RST 10 1
               ※基板上に印字されているピン名

ProMicroを接続したところ (右上のLEDマトリックスは何かの残骸)

最後に”ツール”タブの”ボード”と”書き込み装置”でそれぞれ”Arduino UNO”と”Arduino as ISP(ATmega32U4)”を選んでから、”ブートローダーを書き込む”をクリックし書き込みを実行します。

ボードと書き込み装置を選んでからブートローダーを書き込むを実行

これでATMEGA328PはArduinoになりました。

スケッチを書き込む

Arduino UNOにはUSBポートがついていて直接PCと接続してスケッチを書き込めるようになっています。
これは、UNOに乗っているATMEGA16U2がUSB→Serial変換を行ってくれているからです。
今回のようにArduinoを自作した場合は、自分でUSB→Serial変換などを用意してATMEGA328Pへ接続する必要があります。*1 *2
今回は秋月電子通商さんのモジュール基板 AE-UM232Rを使用しました。

akizukidenshi.com

接続はArduino UNO R3の回路図を参考に次のようにつなぎます。
RST端子への接続は100 nFのコンデンサが間に入ります。(AE-232R→コンデンサ→ATMEGA328Pの接続になります。)

信号 AE-UM232R Pin No. Arduino(ATMEGA328P) Pin No.
電源 14 電源
GND 7 GND
Tx→Rx 1 2
Rx←Tx 5 3
RST 2→100nFコンデンサ 100nFコンデンサ→1

接続すると、普通のArduino UNOのようにスケッチの書き込みができます。

試しにATMEGA328Pのピン19にプルダウン抵抗とLEDを接続してLチカのサンプルプログラムを書き込んでみると、問題なく動きました。

自作Arduino互換機でLチカ

今回作った構成だと1セット当たり300円しないくらいなので、何かをつくったときに気軽に組み込めますね。

今回はこれでおわりです。


Arduino互換機とゼロプレッシャーソケットを使ってBootloader書き込み装置を作りました↓
geekyfab.com


GEEKY Fab.ではなんかいろいろ作って頒布してます。
よかったら↓から見ていってください。

*1:今時はあんまりない気がしますが、PCにシリアルポートがついていればそちらでもOKです。その場合はRS232Cをブレッドボードに取り付けられるようにする基板とか売ってるのでそちらをお使いください。

*2:一回書き込むだけであればBootloaderを書き込んだ接続のままArduinoIDEの"スケッチ"→"書き込み装置を使って書き込む"で書き込めます。

Aliexpressでキーボードキットを購入して自作キーボードに挑戦してみる ~スタビライザー取付編~

キーボードを作ったものの、スタビライザーを付けていなかったためスペースキーがすごく押しにくいので、やっぱりスタビライザーを付ける話です。

前回↓ geekyfab.com

スタビライザーを購入

スタビライザーをAliexpressで買うと届くまでに二週間はかかるので、今回は遊舎工房さんで購入しました。こちらのリンクの2Ux4, 6.25Ux1ってやつです。

MXスイッチ スタビライザーyushakobo.jp

で、届いたのでスペースキーのキースイッチを外して早速つけようと思ったんですが、どうにもつかない。
どうやらプレートを付ける前につけるのが正解のようですね…。必要になったらあとからつければいいや、という目論見が外れました…

キーキャップとキースイッチをすべて外す

ということで諦めてキーキャップとキースイッチを全部外すことにします。ホットスワップモデルにしてて助かりました。半田付けしてたらたぶん諦めてました。

キーキャップは取外し用の工具が同封されていたので簡単に外せましたが、キースイッチを外す用の工具は持っておらず、これがけっこう大変でした。というのもキースイッチは前後の爪がプレートに引っかかる形で固定されているからです。
無理やり外そうとするとキースイッチ本体の上蓋が緩み、中のばねが飛び出してパッカーンと四分五裂してしまうかもしれません(体験談)。
なので、キースイッチを外すときは↓の動画のように前後の爪の部分にピンセットなどを交互につっこみ、少しずつ緩めるように外しましょう。

 

f:id:moutakusan:20201128154413g:plain
キースイッチを外すときは慎重に

スタビライザーを取り付ける

すべてのキースイッチを外し終えたら、ケースの蓋を開けて基板にスタビライザーを取り付けます。
スタビライザーを取り付けるときは、下の画像のように、爪がある方を先に基板の穴に挿入して爪を基板に引っ掛けてから、返しのある方をもう一方の穴に挿入するようにしましょう。

f:id:moutakusan:20201128155412p:plain
スタビライザーの付け方

f:id:moutakusan:20201128154807p:plain
基板にスタビライザーを取り付けたところ

スタビライザーを取り付けたら、指でキーキャップが刺さる部分を動かしてみてスムーズに動くことを確認しましょう。
スムーズに動かなければスタビライザーが傾いていることが原因かもしれません。それぞれの足がちゃんと基板の穴に入っているか確認しましょう(これも体験談)。

さて、スタビライザーを全部取り付けたので、プレートをはめて、ちゃんと動くかどうか確認しました。結果…

f:id:moutakusan:20201128160203p:plain
キーが押されたまま戻ってこない…

はい。キーが押されたまま戻ってきてくれませんでした。シフトキーもエンターキーもスペースキーも。

なんで戻ってきてくれないの?

調査の結果、下記が原因であることが分かりました。

① プレートとスタビライザーの金属バーが干渉している。
② そもそもクリア軸のキースイッチの押し返す力が弱すぎる。

①に関してはプレートとスタビライザーの相性の問題かと思います。どうしても解消できませんでした。キーボードキットを買ったショップで売ってるやつなら、干渉しなかったのかしら?次に作ることがあればこちらで試してみます。

s.click.aliexpress.com

②に関しては、スタビライザーを使っているところには赤軸や黒軸といったもっと強めのキースイッチを選べば解消できるかと思います。
が、家にはクリア軸しかなく、新しく注文するのも時間がかかるので、面倒だなと思っていた私はひらめきました。

「ばねを二倍にすれば強さも二倍になるんじゃ…」

ということで、余っていたクリア軸を分解し、中のばねを取り出し、別のキースイッチの中に入れました(ばねの長さがそのままだとめちゃくちゃ入れにくかったので、ばねは半分に切りました)。

f:id:moutakusan:20201129071101p:plain
バラバラにされて、中のばねが半分に切られたキースイッチ。あるいは合成素材。

これによりばねの長さが1.5倍となり、キースイッチが押し返してくる強さも体感1.5倍くらいになりました。
で、早速このスーパークリア軸で動作確認をしたところ、

  • スペースキーは動くようになった!
  • その他キーの動きもよくなったが、時々引っかかって戻らなかった。

という結果になりました。その他キーについてはこの後も頑張りましたが、先ほどの①による抵抗が大きくどうしようもなかったので、スタビライザーは無しにすることにしました。もともとなくてもいいと思ってたのもあります。
スペースキーが問題なく動いてくれるようになっただけでも万々歳です。

f:id:moutakusan:20201129080530g:plain
スペースキーの端を叩いてもまっすぐ押下されるようになった

ということで、これで自作キーボードは完成です。めでたしめでたし。

おわりに

キーボードを組み立てて形にするところまではとっても簡単だったんですが、スタビライザーはめちゃくちゃ苦労しました。
これから作る方はキースイッチを付ける前にちゃんとスタビライザーをつけましょう。スタビライザーなんていらないでしょ、必要になれば後から付ければいいでしょ、とか考えてたら私みたいにとても苦労するかもしれません。

そういうわけなので、同じようにKPrepublic Storeでキットを買う方はkit3か4 (Stabilizer付、switchなし)とキースイッチを別で買うのがいいかなと思います。

s.click.aliexpress.com

s.click.aliexpress.com

kit3/4についてくるスタビライザーなら大丈夫かはわかりませんが、少なくともストアからサポートor返品対応は受けれるかなと思います。むしろ問題ないかだれか人柱になって確認してほしい…

ちなみに、ホットスワップモデルはUS配列限定です。無印の方はJIS配列対応可能らしいので、JIS配列が良い方は無印の方を選びましょう。私も本当はJIS配列が良かったですが、届いてから気づきました。確認不足です。

s.click.aliexpress.com



そういえば使い心地ですが、とーっても軽いです。ほぼ指を乗せるだけで打鍵できる感じ。スムーズに打てるととても気持ちいいです。あとは無刻印、US配列になれる時間が必要です…
 

f:id:moutakusan:20201129081141p:plain
完成した自作キーボード(テンキーレス、クリア軸、US配列、無刻印)

それでは今回はこれで終わります。お疲れ様でした。


おしまい。



自作キーボードを二台のPCで共有するためにUSB切替器を作りました。
geekyfab.com

Aliexpressでキーボードキットを購入して自作キーボードに挑戦してみる ~組立編~

前回の続きで、自作キーボード用のキット(XD87 HS)とキーキャップを組み立てていきます。
最初に書いておくと、めちゃくちゃ簡単でした。

↓前回 geekyfab.com

まずは、購入したケースはベースと蓋がカチッと組み合わされた状態なので、同封されていたピックで開けていきます。

f:id:moutakusan:20201122223912p:plain
ケース

f:id:moutakusan:20201122224012p:plain
同封されているピックを使って外していく

次にケース(ベース側)についてる基板から伸びてるハーネスを、キーボード基板上のコネクタに接続し、キーボード基板をケース(ベース側)にはめます。

f:id:moutakusan:20201122224412p:plain
ハーネスを接続する

f:id:moutakusan:20201122224623p:plain
そしてベースにはめる

次はプレートをケース(蓋側)にはめます。

f:id:moutakusan:20201122224945p:plain
プレートをケース(蓋側)にはめる

そして、基板をはめたケース(ベース側)とプレートをはめたケース(蓋側)をはめ合わせます。

f:id:moutakusan:20201122225438p:plain
ケースをはめ合わせる

次に各ソケットにスイッチを挿入していきます。ソケットは結構堅かったです。ぐりぐりしながら挿入すると上手くいきました。

f:id:moutakusan:20201122225713p:plain
スイッチを挿入していく

ときどき足が曲がっているスイッチがあったので、まっすぐにしてから挿しましょう。

f:id:moutakusan:20201122230222p:plain
ときどき足が曲がっていた

全部挿すとこんな感じ

f:id:moutakusan:20201122230322p:plain
スイッチを全部挿したところ
  私はここで全部のキースイッチが反応するかテストをしました。テストにはこちらのキーボードテスト用サイトを使わさせていただきました、

あとはキーキャップをつけて完成!

f:id:moutakusan:20201122233611p:plain
完成!!
かっこいい!Escの赤とEnterキーのメッセージ刻印がいい感じのアクセントになっています。
ちなみに、「we stand together」の刻印が入ったEnterキーキャップはキットにおまけ?で同封されていました。コロナ禍を共に乗り越えよう的な意味かと受け取り、いいなと思ったのでつけてみました。

  かなり簡単にできたなと思ってたのですが、問題がありました。スペースキーを押すと…

f:id:moutakusan:20201122232959p:plain
スペースキーの端を押すと、スペースキーが跳ね上がる
スペースキーが跳ね上がってしまい、上手く押せません。本来ならこういうことが起こらないようにスタビライザーを付けるのですが、前回書いた通りスタビライザーが付いていないキットを注文してしまったうえ、まぁ大丈夫だろうと思ってスタビライザーを付けずに組んでしまいました。これではさすがに使いにくいのでスタビライザーを付けたいと思います。

ということで、続きます。
geekyfab.com


自作キーボードを二台のPCで共有したい人にはこちらもおすすめ。
geekyfab.com

Aliexpressでキーボードキットを購入して自作キーボードに挑戦してみる ~購入編~

キーボードはずっとPC付属のものを使ってきたんですけど、そろそろちょっといいやつが欲しくなってきました。
それでお店に行っていろいろ触ってみたんですけど、正直あんまり違いわからなかったんですよね。
メカニカルキーボードだと軸の色で押し心地が違うことはわかったし、それは実感できたけど、軸が一緒ならもう全然わからない。

どうせ違いがわからないなら、自分で作るのが愛着がわくしいいかなと思って作ってみようと思ったのが今回の成り行きです。

今回は購入編になります。
組立は次回の記事で書きます。

Aliexpressで自作キーボードキットを選んでみる

調べてみたところ、自作キーボードには以下のパーツが必要なようですね。

  • キーキャップ
  • スイッチ
  • プレート
  • スタビライザー
  • 基板
  • ケース

とはいえ、初めてなのでキットがいいかなと思い、今回はキットを中心に探しました。
で、たどり着いたのがAliexpressで売っていたテンキーレスのXD87 HSキット↓です。

s.click.aliexpress.com

どのキットを買えばいいんだろう

選択肢としてkit1~kit7があり、それぞれの説明が製品ページの下の方に書いてありました。
ざっくりと以下の感じ。

  • kit1とkit2:基板 + プレート + ケース(黒/白)
  • kit3とkit4:基板 + プレート + ケース(黒/白) + スタビライザー
  • kit5:基板 + プレート + ケース + Gateronスイッチ
  • kit6:基板 + プレート + ケース + Gateronスイッチ + LED
  • kit7:基板 + プレート + ケース + Gateronスイッチ + LED + USB type Cケーブル

光らなくていいんでkit5を選択。
あと、kit5, 6, 7には一見スタビライザーが付いてなさそうだったけど、XD87(無印)のQ&Aを見ると下記のようなやりとりを発見しました。

Q: Does kit 6 or 7 come with stabilizers? It is not in the description
A: any kit come with stabs

 こちらにも付属していると期待しておきましょう。 届いたキットを確認したところ、スタビライザーは付属していませんでした。
チャットでショップに聞いてみましたが、やはりついてないとのことです。
Q&Aはあくまでユーザーが回答したものだから、正しい回答が欲しいなら直接聞いて欲しいとのこと。
チャットのレスポンスも早かったですし、他のショップでも次からそうすることにします。

もう一つ迷ったのが、kit5,6,7を選んだ時のケースとスイッチの色指定の方法ですね。 元ページでは

Kit5=XD87 PCB +Stainless steel plate+Plastic Case(Pls mark Black or White one)+90 Gateron Swithces(Pls mark type)

って書いてあるんですけど、注文確定まで選択できるタイミングはなかったです。
なので、注文後にMy Ordersのページの購入製品のところからストアへのメッセージを送れるチャット画面に飛べるので、そこで希望の色を連絡しました。

スイッチの色はどうしようか

Gateronスイッチの色は「キーボードスイッチいろいろ」を参考にさせていただき、Cherry MXの赤軸よりさらに軽いクリア軸というやつを選択しました。

ちなみに、GateronっていうのはCherry MXっていうやつの互換スイッチらしいですね。Cherry MXの特許が切れたから互換スイッチが多く出回るようになっただとか、なんとか。

ホットスワップ

そういえば、今回買ったKPrepublic Storeにもう一つほぼ同じ内容のキットがあったんですけど、こっちはホットスワップ用のパーツが付いてないタイプのようですね。

s.click.aliexpress.com

ホットスワップっていうのは、スイッチを簡単に挿抜できる機構のことみたいです。
ホットスワップ用のパーツがあらかじめ基板に実装されているため、はんだ付け不要でスイッチを付けることができて、製作も楽になりますね。

PCが電源ONのときでも周辺機器を認識できる意味のホットスワップとは別の意味みたいですね。ややこしい。

キットにはキーキャップが付属していないので、キーキャップは別でこちらを購入しました。

s.click.aliexpress.com

届きました

はい。届きました。
キットの方が注文から約2週間、キーキャップの方が約3週間くらいで来ました。

キットの中身はこんな感じ。

f:id:moutakusan:20201117222428p:plain
キーボードキット 左からケース、基板、プレート、スイッチ
他に、ケースを開けるためのピックとおまけのキーキャップが一個、予備のねじが四本ついてました。

基板の表面はこんな感じ。ねこちゃんがかわいい。

f:id:moutakusan:20201117224526p:plain
基板表面
基板の裏面はこんなん。ホットスワップ用の部品が各スイッチの位置に実装されています。
f:id:moutakusan:20201117224715p:plain
基板裏面
基板上にはAtmel製のATMEGA32U4が実装されていました。Arduino LeonardoとかProMicroでおなじみの、USBデバイスとしてふるまえるAVRマイコンですね。
f:id:moutakusan:20201117223848p:plain
マイコンはATMEGA32U4
基板の下の窓みたいになっている部分は内層の銅箔が全部抜かれていて、光にかざすとねこちゃんが透けて見えます。
表面のねこちゃんは、ねこちゃんのかたちに銅箔を抜いて書かれてるみたいですね。
周辺のランドはLED実装用っぽいので、光らせるとねこちゃんが光って見えるのかしら。遊び心が合って素敵です。
f:id:moutakusan:20201117225220p:plain
ねこちゃんが透けて見える

キーキャップはこんな感じ。調子に乗って無刻印にしてしまいました。キーキャップの取外し用の治具も付いてきました。

f:id:moutakusan:20201117225943p:plain
キーキャップ
ちゃんとお行儀よく並んでパッケージングされてました。

次回、組み立てていきたいと思います。



組立編につづく
geekyfab.com

5x7ドットマトリクスLEDで文字を出力してみる

なんかのときに秋月で買った5x7 ドットマトリクスLEDが家にあったんで光らせてみました。

今回はArduino (ProMicro)で5x7ドットマトリクスLEDを光らせて文字を出力するまでの手順を紹介しています。
原理確認のために、5x7ドットマトリクスLEDをゆっくりと光らせた動画も載せてますので、興味があればそちらだけでも見ていってください。→動画位置までジャンプ

ドットマトリクスLEDについて

ドットマトリクスLEDのデータシートを確認すると、中身の回路はこんな感じです。

f:id:moutakusan:20201103210417p:plain
5x7ドットマトリックス回路図

光らせ方の原理は前回作ったキーマトリックススイッチと同じですね。

geekyfab.com

キーマトリックススイッチのスイッチ部をLEDに置き換えたものと言えます。

COL①~⑤を順番にHighにしていって、タイミングを合わせて光らせたい場所のROW①~⑦をLowにして電流を流すことで、特定のLEDだけを光らせることができます。 例えば左上端のLEDだけを光らせたければ、COL①がHighのタイミングでROW①をLowにすればいいですね。
(ROW②~⑦は電流が流れないようにHighか開放状態にします)

これを人の目にもとまらぬ速さで全LEDに対して行うと、残像効果でまるで全LEDが同時に光っているように見えるという算段です。

この記事の最後に、ドットマトリクスLEDをゆっくり光らせたときの動画も載せてます。
そちらを見れば、わかりやすいかも。→動画位置までジャンプ

回路を描いてみる

ドットマトリクスLEDを光らせるための回路はこんな感じにしました。

f:id:moutakusan:20201103220236p:plain
5x7ドットマトリクスLED点灯回路
抵抗はLEDに流れる電流を制限して、LEDの明るさを調整するためのものです。
抵抗値は、LEDに流したい電流値とデータシートに書いてあるLEDの順方向電圧から計算します。
今回は、電流を適当に10mAとして、順方向電圧が3.2Vくらいになるようなので、
  (5-3.2)V/0.01A = 180ohm
の抵抗を使用しました。

コードを書いてみる

COL①~⑤をHighに走査して、タイミングを合わせてROW①~⑦をLOWにします。
とりあえず、"A"と出力してみましょうか。

const int columnPinNumber[] = {9,10,14,15,16};
const int rowPinNumber[] = {2,3,4,5,6,7,8};

// "A"
bool LEDMatrix[7][5] ={
  {0,1,1,1,0},
  {1,0,0,0,1},
  {1,0,0,0,1},
  {1,0,0,0,1},
  {1,1,1,1,1},
  {1,0,0,0,1},
  {1,0,0,0,1}
};

void init5x7DotMatrixLED(int columnPinNumber[5], int rowPinNumber[7]);
void bright5x7DotMatrixLED(int columnPinNumber[5], int rowPinNumber[7], bool LEDMatrix[7][5]);
void openDrain(int pin, bool state);

void setup() {
  init5x7DotMatrixLED(columnPinNumber,rowPinNumber);
}

void loop() {
  bright5x7DotMatrixLED(columnPinNumber,rowPinNumber,LEDMatrix);
}

//5x7 Dot Matrix LED初期化関数
void init5x7DotMatrixLED(int columnPinNumber[5], int rowPinNumber[7]){
  for(int i=0; i<=4; i++){
    pinMode(columnPinNumber[i],OUTPUT);
    digitalWrite(columnPinNumber[i],LOW);
  }

  for(int i=0; i<=6; i++){
    openDrain(columnPinNumber[i],HIGH);
  }
}

//5x7 Dot Matrix LED 点灯関数
void bright5x7DotMatrixLED(int columnPinNumber[5], int rowPinNumber[7], bool LEDMatrix[7][5]){
  for(int i=0; i<=4; i++){
    digitalWrite(columnPinNumber[i],HIGH);
    for(int j=0; j<=6; j++){
      openDrain(rowPinNumber[j],1-LEDMatrix[j][i]);
      delayMicroseconds(476);     //=60Hz
      openDrain(rowPinNumber[j],HIGH);
    }
    digitalWrite(columnPinNumber[i],LOW);
  }
}

//オープンドレイン動作関数
void openDrain(int pin, bool state){
  if(state == HIGH){
    pinMode(pin,INPUT);
  }
  else if (state == LOW){
    pinMode(pin,OUTPUT);
    digitalWrite(pin,LOW);    
  }
}

オープンドレイン動作関数について少し補足です。
Arduinoの出力ピンはハイインピーダンス(開放)出力ができないため、ピンを入力に切り替えて無理やりハイインピーダンスにする必要があります。
そんなことをやっているのがオープンドレイン動作関数さんです。

動かしてみる

では、実際に回路を組んで動かしてみましょう。

かなり簡単な回路なんですが、一点だけ、ドットマトリクスLEDのピン配置がなぜかデータシートに書かかれていませんでした。
いや、書かれてはいるんですがデータシートに書かれてるような識別マークは手元のものには書いてないし、どちらにしろ1ピンの位置しかわからない内容だし…

ともかく、裏面から見ると透明な樹脂のしたにうっすらと”1”と”12”の表記があり、下図のように時計回りに割り当てられていると推測できます。

f:id:moutakusan:20201107153429p:plain
5x7ドットマトリックスLED ピン配置

で、実際に回路を組んでコードを書き込むと…

f:id:moutakusan:20201107154735p:plain
”A”が表示された!!

”A”が表示されました!やったー!

何が起こってるか見てみる

5x7=35個のLEDを12本のピンで制御してるなんて不思議ですね。
原理は初めに説明した通りなんですが、本当に?って思いはありますよね。

ということで、コード中の一つ当たりの点灯時間を476usから100msくらいに伸ばしてみましょう。
すると、こうなります。

f:id:moutakusan:20201107161520g:plain
スロー点灯
一つずつ順番に光らせている様子が見ることができましたね。
これを目にもとまらぬ速さで繰り返すことで”A”を表示させていたようです。


今回はこれで終わります。

おしまい。


[追記]
64x32ドットマトリクスLEDの光らせ方の紹介記事も公開しました。
こっちではカラーのドット絵とかも出力してます。 geekyfab.com

4x4キーマトリックススイッチを作ってみる その2

 前回、4x4キーマトリックスの回路を描いて、ユニバーサル基板上に実装してみました。

geekyfab.com

 今回はプログラムを書いてキーマトリックスが動作することを確認していきたいと思います。

…の前に、前回作った回路の導通チェックをしているとおかしいところがあったんで、半田付けを修正しました。修正後が↓になります。

赤丸のとこが修正箇所
…まぁ、接続が間違ってたんでつなぎ変えたんですけど、Afterの写真だけ見てもわかりませんよね。

Arduinoにつないでみる。

 Arduino(ProMicro)に接続したキーマトリックスの回路図はこんなんです。

ProMicroにキーマトリックスを接続

単純にGPIOポートにキーマトリックスのKEYIN、KEYOUTを接続しただけです。

部品表はこちら。

緒言 部品 購入先リンク
U1 ProMicro Amazon
SW1~16 6x6x5mm タクトスイッチ Amazon
D1~4 1N4148 秋月電子
R1~4 15kohm 1/4W 1% 金属被膜抵抗 Aliexpress
- ユニバーサル基板 秋月電子
- ピンヘッダ 秋月電子

コードを書いてみる

 KEYOUT1~4を順番にHIGHにしていって、どのタイミングでKEYIN1~4のどれがHGIHになるかを見ればいいわけです。ですので、動作確認用のコードはこんな感じにしました。

const int KEYIN[] = {18,19,20,21};
const int KEYOUT[] = {10,14,15,16};

unsigned long previousMillis = 0;  
const long interval = 50;          
int columnNum=0;
int sw[4][4]={0};

void setup() {
  for(int i=0; i<=3; i++){
    pinMode(KEYIN[i],INPUT);
    pinMode(KEYOUT[i],OUTPUT);
    digitalWrite(KEYOUT[i], LOW);
  }
  Serial.begin(9600);
}

void loop() {
  unsigned long currentMillis = millis();
  
  if(currentMillis - previousMillis >= interval) {
    previousMillis = currentMillis;
    digitalWrite(KEYOUT[columnNum], HIGH);
    for(int rowNum=0; rowNum<=3; rowNum++){
      sw[columnNum][rowNum]=digitalRead(KEYIN[rowNum]);
      delay(10);
    }
    digitalWrite(KEYOUT[columnNum], LOW);
    columnNum++;
    columnNum &=3;
  }

  if(columnNum==3){
    for(int i=0; i<=3; i++){
      for(int j=0; j<=3; j++){
        Serial.print(sw[i][j]);
      }
      Serial.println();
    }
    Serial.println();
    Serial.println();
    delay(500);
  }
  
}

 一列ずつ順番にスイッチの状態を見ていって、4x4の配列sw[4][4]にスイッチの状態を書き込んでるって感じですね。で、結果をシリアル出力で見てます。

動かしてみた

 回路図に沿ってキーマトリックスとProMicroを接続し、書いたコードをProMicroに書き込みます。

ProMicroと接続してコードを書き込む

 走らせてみると、こんな感じで反応してくれました。

0100
0000
0000
0000


0000
0000
0010
0000


0000
0000
0000
0000

.
.
.

 ちゃんと動いてくれました。よしよし。

おわりに

 キーマトリックスは昔からあるものなので、技術情報も多く、あまり苦労せずに回路やコードを書くことができました。ユニバーサル基板のサイズを攻めすぎたせいか、配線が悩ましく、半田付けには少し苦労しました。
 キーマトリックスの製作はこれにて一旦完了です。お疲れ様でした。


おしまい。


GEEKY Fab.では思い出のゲームで遊ぼうをテーマにハードウェアを作ってます。
よかったら↓から見ていってください。