2019年12月28日土曜日

エルゴノミック Realforce を作ろう(4)4x4キーパッド編

製作した 4x4 キーパッド
前回の 3x3 キーパッド編では、とりあえず静電容量無接点スイッチとして機能することは確認出来た。だけど、-100mV 程度の微妙な負電圧がオペアンプの入力端子に印加されていると思われるのが気になった。

今回はその点をなんとかしつつ、4x4 キーパッドを作ってみた。

しかし、今回はこれまでのようなお手本回路図はないので、先人が検証済みの回路をコピペしていきなり PCB 発注とはいかない。さすがに今回はテスト回路をちゃんと作って動作を確認しなければ・・・。

それなら、SPICE でまずシミュレーションしてみようと思い、ググると、実は KiCAD には SPICE が付いてきているらしい!と分かる。早速動かしてみる。

前回のキー押下検出回路


まずは、前回のキー押下検出回路を SPICE で走らせてみた。SPICE を走らせるには、オペアンプ モデルの指定と、シミュレーション用電源を置く必要がある。あと、GND をどこかに付けないと、ちゃんとした結果にならなかった。SPICE 用に直した回路図はこちら。

前回の 3x3 キーパッドで使用した回路の SPICE シミュレーション回路図
ここで、
  • C1 は Topre キースイッチの静電容量
  • C2 は押下検出用コンデンサ
  • R1 はパッドやアナログマルチプレクサの ON 抵抗
  • R2 は C2 の放電用抵抗
  • R3, R4 は非反転増幅器の負帰還抵抗で、ゲインは21倍
となっている。

また、シミュレーション用に、電圧源 Vdd1 は 3.2V の直流電源で、電圧源 Vcol1 は、
  • 5us 後に 100ns で 3.2V に立ち上がり
  • その 20us 後に 100ns で 0V に立ち下がる
という、col 線のストローブ信号を模擬するパルス電源だ。

レギュレータから期待する電源電圧は 3.3V だけど、以下でグラフを読む時に分かりやすいように、3.3V ではなく、代わりに 3.2V とした。

また、オペアンプには、実際に使用した NJU77701 のモデルを以下のサイトからダウンロードして読み込んだ。

NJU77701 1回路入り34MHz、35V/us、低ノイズ入出力フルスイング高速CMOSオペアンプ (RFノイズ耐性オペアンプ)

そして、早速 SPICE を走らせてみる。

赤:C2 電位、青:readout 出力
赤線は検出コンデンサ C2 の電圧で、前半の立ち上がりは前回の想定通り。後半は、やはり確かに負の電圧が現れている。そして、肝心の readout 出力(青線)は・・・、全然動いてません(汗)

いやはや、オペアンプがレールツーレール、フルスイングのものだからとほぼ 0V 近辺の入力で動かしていたとはいえ、SPICE シミュレーションでは動いていない回路になっていたとは。実物のオペアンプはよくちゃんと動いてくれたものだ・・・。

では、気を取り直して、検出コンデンサ C2 の電位が負にならない方法を考える。

中間電位を作る


col 線を上げ下げした時に、オペアンプへの入力電圧が一時的にも負にならないようにしたい。そのためには、中間電位を作って、検出コンデンサ C2 の電圧波形を上下対称にしたらよさそうだと考えた。

つまり、普段の何もしてない時の検出コンデンサ C2 の電位を、GNDの代わりに、電源とGNDの中間の電位にしてやればよい。

でも、中間電位はどうやって作るんだろう!?
抵抗分圧でよいのか?でもそれだと、電圧源としては内部抵抗が大きいから、抵抗ではなくて、コンデンサで分圧するのか?でも、コンデンサだけでは、分圧された電圧が安定せずに、勝手な電圧で落ち着いてしまう気がするから、やっぱり抵抗で電流をある程度流して、分圧電圧をカチッと決めないといけないのではないだろうか?そうか、こういう時に、ボルテージフォロワを使うのか。でも、今使ってるオペアンプは x5 以上の回路利得が実用的と書いてあるからボルテージフォロワには向いてない気がするし、オペアンプをもう一個使う程、今回駆動したい回路は電流が流れる回路でもない。何より、素子数をあまり増やしたくはない。ブツブツ。
いくらかの頭の中の逡巡の末に、まず抵抗分圧で作ってみることにした。

分圧抵抗は小さい方が安定しそうだけど、あまりたくさん電流を流したくもない。まぁ、LED と同程度ならよいかと思って、とりあえず 1kΩ にしてみる。消費電流 1.6mA。

中間電位を R16, R17 で作る(C13, C14 を付加後の回路)
これでシミュレーションしてみると、col 線のスイッチング時に、中間電位が若干引きずられて振られていた。

赤:C12 の下端、緑:中間電位(R16 と R17 の接続点)

そこで、コンデンサも並列に入れてみることにした(上記の回路図)。容量は、アナログマルチプレクサの電源パスコンも兼ねて、なんとなく 0.1μF にする。キースイッチの容量は、押下時でも 5pF だから、十分吸収出来そうだ。

C13, C14 を追加してもう一度走らせると、以下のように col 線のストローブ ON/OFF 時のスパイクは消えていたので、とりあえずよしとする。

C13, C14 を付加後(赤:C12 の下端、緑:中間電位)

非反転増幅器による出力波形

おし。では、出力電圧 readout1 の波形を見てみる。

赤:C12 の下端、緑:中間電位、青:readout1 出力
このグラフを見ると、readout1 はかなり鈍っているのと、ピークに遅れがある。前回の実測波形だと、ここまでは激しく鈍ってはいなかったので、オペアンプの SPICE モデルのパラメータが安全側に選ばれているのだろうか?

あと、readout1 は初期状態で中間電圧の 1.6V にはなっていなくて、1.45V になっている?!中間電位よりも -0.15V 下がっているらしい。この点についてはもう少し詳しく考えてみた。

出力電圧のオフセット!?


この結果から逆算して考えてみる。まず、オペアンプは前回の教訓から CMOS タイプなので、入力バイアス電流は 1pA 程度で無視できる。負帰還抵抗 R14 と、反転入力の抵抗 R13 は合わせて 10.5kΩ なので、これらを流れる電流は -0.15V/10.5kΩ = -14.3μA になる。

一方、検出コンデンサ C12 にかかる電圧は、定常状態ではゼロに放電されているはずだ。したがって、オペアンプの入力端子間の電位差は、反転入力の R13 を流れる負帰還電流により、470Ω x -14.3μA = -6.7mV になっている。

回路図中の他の素子値を色々変えてみたけど、この -6.7mV というのは、ほとんど変化しなかった。つまり、これはオペアンプの特性のようだ。調べてみると、これはオペアンプの入力オフセット電圧というもののようだ。データシートでは 1.5mV 以下となっているので、SPICE モデルでは、少し大きめに出ているのだろうか。

中間電位への影響


あともう1つ。負帰還電流によって、中間電位も影響を受ける。今の場合だと、-14.3μA の電流が中間電位のところから流れ出て行く。放電抵抗 R12 の先はハイインピーダンスなので、そちらからは負帰還電流は流れてこないから、負帰還電流は上と下の分圧抵抗から半分ずつ流れてくることになる。これにより、中間電位は -14.3μA / 2 x 1kΩ = -7.15 mV 下降する。

実際に、上記のグラフを拡大してみると、中間電位が 1.593V になっていることが分かる。

t = 0 付近の拡大図(赤:C12 の下端、緑:中間電位、青:readout1 出力)

出力オフセット電圧のまとめ


これらを書き下すと、オペアンプの入力オフセット電圧を \(v_{io}\) として、出力電圧のオフセット\(v_{oo}\) は、
\[v_{oo}=\frac{R_{13}+R_{14}}{R_{13}}v_{io}+\frac{R_{16}R_{17}}{R_{16}+R_{17}}\cdot\frac{v_{io}}{R_{13}}
=\left(1+\frac{R_{14}+R_{16}/2}{R_{13}}\right)v_{io}\]で与えられる。ただし、R16=R17とした。

すなわち、出力電圧のオフセットはオペアンプの入力オフセット電圧 -6.7mV が原因となって、
  • 負帰還抵抗を通じて、非反転増幅器のゲイン倍される成分
  • 負帰還電流が中間電位から流出して、それを押し下げる成分
がある。

特に後者は、非反転入力の抵抗 R13 が分圧抵抗 R16, R17(内部抵抗に相当)と同程度かより小さいと、より大きく影響を受ける。したがって今の場合、負帰還抵抗はもう少し大きくした方が、中間電位への影響を減らせると思われる。実際、R13=10kΩ、R14=200kΩ としてみると、

負帰還抵抗を大きくした後(赤:C12 の下端、緑:中間電位)
と中間電位がより安定して、電位降下もほぼ見られなくなった。ちなみに中間電位の電位降下は
\[\frac{R_{16}R_{17}}{R_{16}+R_{17}}\cdot\frac{v_{io}}{R_{13}}=\frac{1\,{\rm kΩ}}{2}\cdot\frac{-6.7\,{\rm mV}}{10\,{\rm kΩ}}=-0.34\,{\rm mV}\]と計算され、実際に十分に小さいことが分かる。

また、同様に出力オフセット電圧に実際の値を代入してみると、
\[v_{oo}=\left(1+\frac{R_{14}+R_{16}/2}{R_{13}}\right)v_{io}=\left(1+\frac{200\,{\rm kΩ}+1\,{\rm kΩ}/2}{10\,{\rm kΩ}}\right)(-6.7\,{\rm mV})=-141\,{\rm mV}\]となる。負帰還抵抗の値を大きくすることで、出力オフセット電圧も若干小さくなった。

反転増幅器による出力波形


そういえば、何で非反転増幅器になっていたんだろうと思ったので、反転増幅器でも試してみた。対応する回路図はこんな感じになる。

反転増幅器に切り替える(素子値は元に戻す)
早速 SPICE を走らせてみると。。。

反転増幅器の出力(赤:C22 の上端、青:readout2 出力)
なんじゃこりゃ〜〜!出力波形が振動している!?C22 の検出電圧も、その影響を受けてか振動している。あと、出力の振幅がとても小さい。

素子値を色々変えてみると、どうやら負帰還抵抗の値が小さ過ぎるようだ。これらを10倍の R23=4.7kΩ、R24=100kΩ にしたら、こんな感じの波形に少し落ち着いた。

負帰還抵抗を 10 倍に変更 R23=4.7kΩ、R24=100kΩ(赤:C22 の上端、青:readout2 出力)

元の値の R23=470Ω、R24=10kΩ だと、放電抵抗 R22(出力インピーダンス)の方が、反転入力の抵抗 R23(入力インピーダンス)よりも大きくなっているので、測定器(反転増幅器)が測定対象(検出コンデンサ C22 と放電抵抗 R22)を乱してしまい、それにオペアンプの時間遅れのフィードバックもかかって、出力がグワングワンしてしまったようだ。

さらに R23=10kΩ、R24=200kΩ にしてみると、出力はより安定した。

負帰還抵抗を 20 倍に変更 R23=10kΩ、R24=200kΩ(赤:C22 の上端、青:readout2 出力)
うん、これなら使えそうだ。

出力オフセット電圧


さて、反転増幅器でも、やはり出力にオフセット電圧が現れている。先程と同じように考えてみる。

入力オフセット電圧がかかるのは、今回は放電抵抗 R22 と反転入力の抵抗 R23 とを合わせたものになっている。それらを足した 10kΩ + 10kΩ に入力オフセット電圧の -6.7mV がかかる。この電流が中間電位から電流を引き出して、中間電位が下がるので、出力電圧のオフセットは、
\[v_{oo}=\frac{R_{22}+R_{23}+R_{24}}{R_{22}+R_{23}}v_{io}+\frac{R_{26}R_{27}}{R_{26}+R_{27}}\cdot\frac{v_{io}}{R_{22}+R_{23}}=\left(1+\frac{R_{24}+R_{26}/2}{R_{22}+R_{23}}\right)v_{io}\]となる。ただし、 R26=R27 とした。実際の値を代入すると、
\[v_{oo}=\left(1+\frac{200\,{\rm kΩ}+1\,{\rm kΩ}/2}{10\,{\rm kΩ}+10\,{\rm kΩ}}\right)\cdot(-6.7\,{\rm mV})=-73.9\,{\rm mV}\]となる。非反転増幅器の時のほぼ半分になる。

上のグラフの t=0 付近を拡大すると(中間電位も追加した)、

R23=10kΩ、R24=200kΩ の時の拡大図(赤:C22 の上端、緑:中間電位、青:readout2 出力)
となっており、出力のオフセット電圧が実際に -73mV 程度であることが見てとれる。

また、中間電位はほぼ 1.6V のままでブレていない。これは、中間電位の電位降下は
\[\frac{R_{26}R_{27}}{R_{26}+R_{27}}\cdot\frac{v_{io}}{R_{22}+R_{23}}=\frac{1\,{\rm kΩ}}{2}\cdot\frac{-6.7\,{\rm mV}}{10\,{\rm kΩ}+10\,{\rm kΩ}}=-0.17\,{\rm mV}\]と十分に小さいからだ。

比較


では、非反転増幅器と反転増幅器の出力波形を比較してみる。負帰還抵抗は、両回路とも同じに揃えて、R13 = R23 = 10kΩ、R14 = R24 = 200kΩ とした。

非反転増幅(赤:C12 の下端、青:readout1 出力)、反転増幅(紫:C22 の上端、水色:readout2 出力)
出力オフセット電圧は、上記で調べたように、反転増幅器の方がおよそ半分小さくなっている。しかし、この波形を見ると、キーの押下検出をする際に、
  1. 出力オフセット電圧を考慮しつつ、正(あるいは負の)のピーク値の高さ(低さ)を調べる
  2. 出力オフセット電圧は無視して、正負のピーク値の差の大きさを調べる
では、あきらかに後者の方が安定しそうだ。

そこで正負のピーク値の差を見てみると、非反転増幅器(青)では 0.42V 程度で、反転増幅器(水色)では 0.40V 程度で、わずかに非反転増幅器の方が大きい。実際、反転増幅器では、負帰還電流が C22 からも流れ出して、C22 の電圧(紫)が早く減衰している。

また一方、中間電位については、反転増幅器の方が若干ブレが少なかったが、どちらも問題ないレベルだった。

以上のことを考慮して、今回は検出コンデンサの電圧が負帰還電流で乱されない、非反転増幅器を使うことにした。

4x4 キーパッドの実装


ということで、中間電位 Vmid を作って、4x4 のキーパッドを作成する。
4x4 キーパッドの回路図
今回も row 線の抵抗は実験の意味を込めてバラバラにしてみた。そして、作製した PCB がこちら。

4x4 キーパッド PCB の表面

4x4 キーパッド PCB の裏面
Topre スイッチのパターンについては、今回は
  • スルーホールをビアにして、レジストで覆われるように変更
  • col 線を横に離して、半円形が崩れないように変更
  • なんとなく同じ点を向くようにそれぞれ回転
としてみた。また、PCB の裏面にはパーツを置かないようにして、ジャンパー以外の導体が剥き出しにならないようにしてみた。これは、最終的に PCB 2枚構成のキーボードにしたいと思って試してみた。

そして、出力電圧を実測してみる。測定のシーケンスとしては、各キーごとに、
  1. マルチプレクサで  row 線を選択する
  2. 100μs 待つ
  3. ADC を開始する
  4. 5μs 待つ
  5. col 線を High にする
  6. 20μs 待つ
  7. col 線を Low にする
  8. ADC が 60 サンプル取得するのを待つ
とした。ADC は 12MHz で動作しており、1サンプルあたり14クロックでサンプリング。そのうち、偶数サンプルのみを以下のグラフでは描画している。したがって、グラフ上でのサンプリング周波数は 0.43MHz になる。

まず、キー非押下時の電圧波形。
全キー非押下時の出力電圧波形(各キー波形の間に、1600 の値を 1 サンプル挿入)
キー毎にバラツキはあるけど、期待通りに中間電位の 2,048 付近を境に、上下に振れている。row 線毎に放電抵抗を変えており、最初の 4 つが row0 で 7.5kΩ、次の 4 つが row1 で 10kΩ、さらに次の 4 つが row2 で 12kΩ で、最後の 4 つが row3 で 18kΩ になっている。実際、徐々に放電が緩やかになっている。

次に、キー押下時の電圧波形。4x4 になると、全キーをちゃんと押下するのはなかなか大変。
全キー押下時の出力電圧波形(各キー波形の間に、0 の値を 1 サンプル挿入)
ふむふむ。振幅がちゃんと大きくなっているゾ。よしよし。

最後に、比較のために、col0, col1, col2 のキーのみを押下した場合の波形がこちら。
col0, col1, col2 キーのみを押下した時の出力電圧波形
キーの押下・非押下でかなり顕著な振幅の違いがあることが分かる。

あと、やっぱり SPICE では出力電圧波形が鈍り過ぎな気がする・・・。 

まとめ


長くなってしまったけど、なんとかオペアンプ入力の一時的な負電圧を解消することができ、SPICE でもちゃんとシミュレーションが出来る回路になった。

けど、まだもう一つ回路的な課題があり、次回はそちらを検討する予定・・・。





2019年12月21日土曜日

エルゴノミック Realforce を作ろう(3)3x3キーパッド編

製作した 3x3 キーパッド
前回で Topre スイッチの検出回路の内容はおおよそ分かったので、今回も前回と同様に、こちらのサイト

Guidelines for designing a custom Topre keyboard

を参考に、というかほぼそのまま?!、3x3 キーパッドを作ってみる!


3x3 キーパッドの回路図

3x3 キーパッド(デバッグ用にピンヘッダをいくつか配置してみた)
前回からの差分としては、検出用のオペアンプを1つにするために、各 row 線を選ぶためのアナログマルチプレクサ 74HC4051 が増えている。

また、各 row 線の抵抗は、パラメータ調整のための実験として、3つとも変えてみた。

んで、いきなり早速 PCB を発注してしまう気の早い人(笑)確かに PCB を買う方が、下手するとユニバーサル基板より安いけど、ブレッドボードで組んでテストする前にいきなり発注するのも、送料がバカにならない。でもガマンできずに発注〜♫


3x3 キーパッドの PCB

そして届いたのが、こちらの3x3の半円形 Topreスイッチの並んだ基板。

3x3 キーパッド PCB の表面
PCB の発注時にはまだ中古 Realforce を手に入れておらず、上記サイトにあるフットプリントライブラリを使って基板を設計した。写真は、その後入手した Realforce と並べて撮影。

う〜ん、しまった。col線を表面で直接配線してしまったので、半円形コンデンサを貫いてしまっている。カッコ悪い・・・。本家はきちんと裏面で配線して、表の半円形は綺麗に残されている。次回は改善することにする。

3x3 キーパッド PCB の裏面
そして、本家 Realforce は裏面をベタ GND にはしていない。GND との容量を抑えるためなのだろうか・・・?


動作確認


さて、とりあえずハンダ付けして、つないで、ファームウェアをちゃらちゃらっと書いて、ADC の出力を観測してみる。

が、あっさりおかしい(汗)

非反転増幅器のゲインが高過ぎたらしく、出力が常に Vdd に張り付いてしまっていた。ということで、ゲインを x150 から x20 に下げてやり直し・・・。


キー非押下時の出力波形


波形が取れるようになったので、まず、キーを押してない時の、各キーに対するオペアンプの出力電圧波形を計測した。
キー非押下時の出力電圧波形

この波形は何を測定したものかと言うと、各キーごとに、
  1. マルチプレクサで  row 線を選択する
  2. 100μs 待つ
  3. ADC を開始する
  4. 8μs 待つ
  5. col 線を High にする
  6. ADC が 54 サンプル取得するのを待つ
とした時に、得られた波形を 9 個分つなげたものだ。各キー波形の順番は、最初の3つがrow0、次の3つが row1、最後の3つが row2 で、それぞれの中では、col0, col1, col2の順番になっている。

また、54 サンプルというのは、3x3=9 キーで、間に 1 サンプルのゼロを入れて、arduino のシリアルプロッタの横幅= 500 サンプルに収まるようにした数。各波形の間で 1 サンプルだけゼロに落ちているところが各キーの切れ目になっている。

使用しているマイコン STM32F042 の ADC は、48MHz のバスクロックの 1/4 で駆動させて、1サンプルあたり 14 クロックのモードに設定している。したがって、サンプリングレートは、48/4/14=0.85MS/s になる。1サンプルあたり 1.17μs。

また、縦軸については、ADC の精度が 12-bit なので、4,096 が 3.3V に対応する。


キー押下時の出力波形


では次に、キーを押したら波形はどう変わるか?9 個全部のキーを押して、オペアンプの出力電圧波形を計測してみる。
全キー押下時の出力電圧波形

おぉ〜!1つ1つの波形が大きくなっている!比較のために、col0 と col1 の 6 キーだけを押して、もう一度計測してみよう。
col0, col1 のキーのみ押下時の出力電圧波形

ふむふむ。結構明らかな違いがある。この違いを検知するようにファームを書けば、キーの押下は検出出来るゾ!


謎のオフセット電圧


だけど、row ごとに、高さの違うゲタがあるのは何なんだろう?元のサイトでキー毎にキャリブレーションが必要だと書いてあったけど、それはこのゲタのためなのだろうか?(注:おそらく違う)

このオフセット電圧があると、全部のキー波形を上手く ADC の範囲内に収めるために、押下時の振幅を制限するように素子値を調整したり、row 毎に押下検出のスレッショルドを調整したりしないといけない。何よりも原因を知っておかないと気持ち悪い・・・。

オフセットの高さが row 毎に違っているのは、各 row の放電抵抗の値を変えておいたからだろう。そこで、各 row 線の素子値と波形のオフセット電圧を並べてみる。

rowR出力オフセット電圧入力オフセット電圧V/R
row018kΩ 935 = 0.75V33.8mV1.88μA
row133kΩ1849 = 1.49V66.8mV2.02μA
row243kΩ2465 = 1.99V89.1mV2.07μA

出力オフセット電圧が、ADC の読みに対応する。オペアンプのゲインは 1+10kΩ / 470Ω = 22.3倍なので、出力オフセット電圧を 22.3 で割ったものが入力オフセット電圧。さらにこれを抵抗値 R で割ったものが、右端のカラムになっている。

う〜ん、どうも入力オフセット電圧と抵抗の比をとると、どれも 2μA 程度になるようだ。どこかから電流源的に電流が漏れているということ?

アナログマルチプレクサ 74HC4051 のデータシートを見ると、漏れ電流は 0.1μA 程度のようだ。だから、これでは無さそう・・・。

それなら、col 線から、つまりマイコンの GPIO の Low レベル出力から電流が漏れ出てきたりするのだろうか?確かに元のサイトの回路図には、各 col 線が抵抗とコンデンサの並列接続で終端されている。何の意味があるのだろうと思って、ガン無視していたけど、実は何か漏れ電流を抑えるための意味があったのかも知れない。

ということで、PCB 裏面のレジストを少し削って、抵抗とコンデンサを付けてみた。こんなこともあろうかと(嘘)col 線をピンに出して置いてよかった。

col 線のピンヘッダ用パターン

レジストを削って、無理やり抵抗とコンデンサをハンダ付け
ベタ GND にハンダ付けしようとしているので、ハンダが鉛のように重だるくて溶けない!ハンダ付け用パッドのサーマルパターンは、ある程度細くベタ GND とつなぐことで、ハンダ付けをし易くしているんだな、と思い知った・・・。

だけどしかし、これをしても漏れ電流には何の変化も無かった・・・。col 線の終端インピーダンスとは関係なかったようだ。


となると?


後はオペアンプ?と思って調べていると、オペアンプにはオフセット電流というものがあるらしいと分かった。素人過ぎてスミマセン。


バイポーラ オペアンプ


元のサイトに、「オペアンプは高速なものを使え!」と書いてあったので、今回購入したのは、秋月で「高速・単電源・SOT-23パッケージ」で検索して出てきた、こちらのもの。

単電源高速オペアンプ NJM2716F

今回の検出信号の時定数は数usと1MHz程度の帯域で、ゲインが 20 倍なので、利得帯域幅積として、 20MHzぐらいあるものを選んだ。上記ページによると、このオペアンプの特性は、以下のようになっている。
  • 高スルーレート:40V/μs
  • 入力バイアス電流:2.5μA 以下
  • ユニティゲイン周波数:30MHz
入力バイアス電流が 2.5μA 以下とある。データシートでは、典型値は 1.0μA で、最大では 2.5μA と書いてあった。ひょっとしてこれだろうか?!電流値もちょうど符合する。

今回は 0 ~ 200mV 付近の領域で使うので、レールツーレールのまさしく下のレールの部分だから、この最大値を踏んでしまったのだろうか?

NJM2716 のデータシートの回路図を見ると、入力段が PNP 型バイポーラトランジスタの差動増幅になっている。今回の用途では、ベース電圧が常に 0V 付近なので、スペックの最大に近い 2μA が流れ出てくるのかも知れない。まさか 2μA の漏れ電流でこんなに差が出るとは!


CMOS オペアンプ


オペアンプの入力バイアス電流は、CMOSタイプなら 1pA とかでほとんどゼロらしい。再度秋月で検索すると、こちらが見つかった。

低雑音 フルスイング高速CMOSオペアンプ NJU77701F (4個入)

こちらの特性は、
  • 入力バイアス電流:1pA
  • スルーレート:35V/μs
  • 利得帯域幅積:34MHz
となっている。1pA というこは、2μA の実に 200 万分の 1 だ。こんなに違うの?

ということで、何かのついでにアキバに行って買ってきた。PCB は大体 5 枚届くので、大体いつも使わずに余っている。なので今回はオペアンプを変えつつ、新しい基板に実装し直した。そして、測定したものがこちら。
キー非押下時の出力電圧波形(CMOS オペアンプ)

うん、いい!(笑)オフセット電圧が消えている!

では先程と同様に、キー押下時の出力電圧波形も計測する。
全キー押下時の出力電圧波形(CMOS オペアンプ)

さらに同様に、col0, col1 だけ押したもの。
col0, col1 のキーのみ押下時の出力電圧波形(CMOS オペアンプ)
こうしてどのキーも電圧範囲が揃ったので、振幅値に余裕を持たせて素子値を調整できるようになった。このグラフから見ると、ADC の読みが 800 以上なら、キーが押下されているとみなしてよさそうだ。

元のサイトでは、OPA350A というオペアンプを使ったと書いてあった。これも CMOS タイプのようなので、今回のオフセット電圧は現象として現れてはいなかったと思われる。


Topre スイッチの静電容量(実測)


次に、出力波形のピーク電圧から、Topre スイッチの容量を計算してみよう。C1=330pF だから、スイッチ容量を k とすると、出力ピーク電圧は
\[v_{peak}=\frac{k}{C_1+k}E\cdot\frac{R_{12}+R_{13}}{R_{12}}\]となっている。よって、
\[k\simeq C_1\frac{R_{12}}{R_{12}+R_{13}}\frac{v_{peak}}{E}=330\,{\rm pF}\cdot\frac{470}{470+10k}\frac{v_{peak}}{3.3}=\frac{v_{peak}}{0.223}\,[{\rm pF}]\]
キー非押下時

rowADC の読み出力ピーク電圧容量
row0279, 237, 2460.23V, 0.19V, 0.20V1.00pF, 0.86pF, 0.89pF
row1127, 203, 2590.10V, 0.16V, 0.21V0.46pF, 0.74pF, 0.94pF
row2174, 341, 2080.14V, 0.28V, 0.17V0.63pF, 1.23pF, 0.75pF

キー押下時

rowADC の読み出力ピーク電圧容量
row01324, 1421, 11821.07V, 1.15V, 0.95V4.79pF, 5.14pF, 4.27pF
row11257, 1422, 12751.01V, 1.15V, 1.03V4.55pF, 5.14pF, 4.61pF
row21450, 1407, 13651.17V, 1.13V, 1.10V5.24pF, 5.09pF, 4.94pF

これを見ると、それなりにバラツキはあるものの、非押下時は 1pF 前後、押下時は 5pF 前後となっている。


時定数


また、時定数 \(T=C_1R\) もグラフから求めてみよう。ADCの読み取りデータを y(n) として、
 \[T=10\cdot 1.17\,\mu s/\log\left(\frac{y(20)-y(4)}{y(30)-y(4)}\right)\] という感じで、オフセットを引いて、適当な2点でどれだけ減衰したかの比をとる。C1=330pFと各 R から決まる時定数も併記する。

rowR\(T=C_1R\)測定 T
row018kΩ5.9μs6.1μs
row133kΩ10.9μs12.3μs
row243kΩ14.2μs16.4μs

どうやら若干大きめの時定数になっているようだけど、一応合っていると言えそうだ。


col を Low に戻すと?


さて、ここまでは、col 線を High にした時の波形を見てきたが、実際にはその後に Low に戻している。元のサイトのやり方ではむしろ、High にした後、割とすぐに Low に戻すようにしている。

Low に戻すと出力波形はどうなるか? 線形回路なので、High にした時と同じ過渡波形が、符号が反転して下向きに重ね合わされるはずだ。

やってみようこ!こういう時は、むしろオフセットがある方が分かりやすいので、まずバイポーラ オペアンプで試してみる。
  1. マルチプレクサで  row 線を選択する
  2. 100μs 待つ
  3. ADC を開始する
  4. 8μs 待つ
  5. col 線を High にする
  6. 20μs 待つ
  7. col 線を Low にする
  8. ADC が 54 サンプル取得するのを待つ
という風に計測してみる。キーは col0 と col1 だけ押下した。
20μs 後に col 線を Low にする(バイポーラ オペアンプ)

確かに下にもブレる。したがって、col 線を Low に戻した後、次のキーをスキャンする前には、こうしてブレた row 線が落ち着くのを待つ必要がある。

キースキャンを速くするには、col 線を Low に落とすのを早くするのが1つの手だ。元のサイトでは、これに加えて別途 drain 端子を付けて、コンデンサ C1 を直接放電している。

この drain も試してみたけど、コンデンサ C1 が 0V に一瞬で放電はするものの、その後にバイポーラ オペアンプのバイアス電流による電圧オフセットまで充電され直すので、結局それが完了するまでの時間がかかり、早くならなかった。


負電圧!?


では、CMOS オペアンプの時はどうなるだろう?波形を計測すると、以下のようになった。
20μs 後に col 線を Low にする(CMOS オペアンプ)

何か、波形がすっと落ち着いていて、むしろいい感じに見えるのだけど、実際の回路ではどうなっているのだろうか??

多分、コンデンサ C1 の電圧が一時的に負になって、オペアンプに入力されていると思われる・・・。

とはいっても、最大でも -100mV 程度だろうから、オペアンプの定格電圧は -0.3V なので、壊れることにはならない。でも気になる・・・。


何とかしたい。


ということで、次回に続く・・・。





2019年12月20日金曜日

エルゴノミック Realforce を作ろう(2)原理編

パーツには目処が立ったところで、次は回路を考えたい。とりあえず Topre スイッチを自作しているサイトの回路を参考にする。

Topre スイッチの押下検出はどうやるの?

静電容量式と言っても、その静電容量はせいぜい数 pF しかないようだ。タッチセンサの領域。STM32F042 マイコンの I/O ピンの容量が 5pF なので、浮遊容量と同程度ということ。デジタル回路もアナログ回路も作ったことがないので、そんな小さな容量変化を検知する回路を本当に作れるのか正直不安過ぎる。でも幸いにも、Realforce の回路は

tmk_keyboard/keyboard/hhkb/doc/

で調査されている。ただ、肝心の回路は TP1683/4 というカスタムチップに入っていて詳細はよく分からない。だけど、同じく DIY で Topre clone を作っている人がいた。

Guidelines for designing a custom Topre keyboard

とりあえずこれをマネして作りますよ〜!

Topre スイッチの静電容量


まず、静電容量無接点スイッチのそもそも話を考えよう。つまり、スイッチの容量から。

キースイッチのコンデンサは、押しつぶされて円形になったバネと、基板の半円形パターンの間に出来る。したがって、下の写真と図のそれぞれ右端のように、半円コンデンサが2つ直列接続された格好になる。

半円形パターンと、押してない時の円錐バネと、押下時の円錐バネ。
上の写真に対応する、円錐バネの状態によるキースイッチ容量の変化
一般に、平板コンデンサの容量は、電極の面積を S、電極間距離を d とすると、
\[C=\epsilon\frac{S}{d}\] で与えられる。ε は今の場合は空気中なので、真空の誘電率 \(\epsilon_0\) で大丈夫。

面積 S は、半円の半径を r=6mm として、
\[S=\frac{\pi r^2}{2}=56.5\,{\rm mm}^2\] ここで電極間距離 d が難しいけど、まずはバネの線径の半分で 0.125mm と見積もってみる。そうすると、半円コンデンサ1個で
\[C_1=C_2=\epsilon_0\frac{S}{d}=8.85\cdot10^{-15}\cdot\frac{56.5}{0.125}=4.0\,{\rm pF}\]
これが2つ直列だからこの半分になって、
\[\frac{C_1}{2}=\frac{C_2}{2}=2.0\,{\rm pF}\] となる。実測では、キーを押してないときは C0=1pF ぐらいで、押してる時は C1/2=C2/2=6pF 程度だったので、実効的な電極間距離 d はもう少し短くて、0.04mm 程度相当のようだ。

Topre スイッチの検出回路!


検出回路は、まず上記ページを参考にして、そこで紹介されている次の回路をそのまま使うことにする。

キー押下検出回路
キースイッチの容量 \(k\) にたまった電荷を、より大きなコンデンサ \(C\) で一旦受けて、その電圧をオペアンプの非反転増幅回路で増幅するようだ。

この回路図で、
  • k はキースイッチの容量で、1 ~ 5 pF
  • r は GPIO のパッド抵抗や配線抵抗などで、100Ω 程度
  • C は検出用コンデンサで、100 ~ 1000 pF
  • R は C の放電用で、10kΩ のオーダー
である。

非反転増幅にしているのは、これは微小電荷を扱う電流をあまり流さない回路なので、出力をハイインピーダンスで受けたいからではないかと思う。

この検出コンデンサ \(C\) にはどんな電圧波形が現れるのか?せっかくなので、回路方程式を立てて計算してみよう。もちろん、最終的な結果は元のページにも書かれている。

コアの部分だけ取り出すと、下図のようになる。

キー押下検出回路のコア部分
この回路図を見ると、色んなところで GND との間に数 pF オーダーの浮遊容量がどれだけ挟まっても、キースイッチの容量 \(k\) に並列でない限りは、あまり影響は無さそうだと考えられる。


回路方程式を立てる


では、\(t=0\) で SW1 を投入したときの過渡波形 \(v_C(t)\) を調べよう。回路方程式は、
\begin{eqnarray}
E&=&ri_k(t)+v_k(t)+v_C(t) \\
i_k(t)&=&k\frac{dv_k}{dt} \\
i_C(t)&=&C\frac{dv_C}{dt} \\
i_k(t)&=&i_C(t)+\frac{v_C(t)}{R}
\end{eqnarray}となる。初期電荷をすべてゼロとしてラプラス変換すると、
\begin{eqnarray}
\frac{E}{s}&=&rI_k(s)+V_k(s)+V_C(s) \\
I_k(s)&=&skV_k(s) \\
I_C(s)&=&sCV_C(s) \\
I_k(s)&=&I_C(s)+\frac{V_C(s)}{R}
\end{eqnarray}が得られる。

検出コンデンサの端子電圧


上記の式を \(V_C(s)\) について解く。まず、第2, 3式の電流 \(I_k, I_C\) を第1, 4式に代入・消去して、
\begin{eqnarray}
\frac{E}{s}&=&(1+skr)V_k(s)+V_C(s) \\
skV_k(s)&=&sCV_C(s)+\frac{V_C(s)}{R}=(\frac{1}{R}+sC)V_C(s)
\end{eqnarray}この第1式の両辺に \(skR\) をかけて、第2式を代入する。
\begin{eqnarray}
kRE&=&[(1+skr)(1+sCR)+skR]V_C(s)
\end{eqnarray}これより、検出用コンデンサの端子電圧が
\begin{eqnarray}
V_C(s)&=&\frac{kRE}{1+(CR+kr+kR)s+krCRs^2}
\end{eqnarray}と求められる。

近似の導入


ここから先は、上記の式で \(s\) の極を求めるのだけど、そのまま解析的に求めるのは難しいので、ここで一部近似を行う。最初の仮定から、
\begin{eqnarray}
\frac{k}{C+k}&\simeq&\frac{5\,\rm pF}{330+5\,\rm pF}=0.015 \\
\frac{r}{R}& \simeq&\frac{100\,\rm Ω}{10\,\rm kΩ}=0.01
\end{eqnarray}程度と見積もれるので、これらの2次以上は微小量として無視することにする。特に、両者を掛け合わせたものは、
\begin{eqnarray}
\delta=\frac{rk}{R(C+k)}&\simeq&0.00015=1.5\cdot10^{-4}
\end{eqnarray}であるから、これは 1 に比べて十分に小さく、無視して構わないとする。

s 式の極


上記 \(V_C(s)\) の式で、\(s\) の極の逆数を \(s_1, s_2\) とおく。 すなわち、\begin{eqnarray}
V_C(s)&=&\frac{kRE}{(1-s_1s)(1-s_2s)} \\
&=&\frac{kR}{s_1-s_2}\left(\frac{s_1}{1-s_1s}-\frac{s_2}{1-s_2s}\right)E
\end{eqnarray}ただし、ここで \begin{eqnarray}
s_1+s_2&=&-(CR+kr+kR)=-R(C+k)-kr \\
s_1s_2&=&krCR
\end{eqnarray}が成り立つ。

平方完成


これを解くには二次方程式の解の公式を使えばよいけど、ここでは丁寧に順を追って進められるように、原理原則に戻って平方完成で解いてみる。そこで少し技巧的だけど、次式のように変形する。
\begin{eqnarray}
 (s_1-s_2)^2&=&(s_1+s_2)^2-4s_1s_2 \\
&=&(-R(C+k)-kr)^2-4krCR \\
&=&R^2(C+k)^2+2R(C+k)kr+k^2r^2-4krCR \\
&=&R^2(C+k)^2\left[1+\frac{2kr-4krC/(C+k)}{R(C+k)}+\frac{k^2r^2}{R^2(C+k)^2}\right] \\
&=&R^2(C+k)^2\left[1-2\frac{rk}{R(C+k)}\cdot\frac{C-k}{C+k}+\frac{r^2k^2}{R^2(C+k)^2}\right] \\
\end{eqnarray}ここで、最後の大括弧内の第3項は \(\delta\) の 2 次式だから無視し、平方根のテーラー展開
\[\sqrt{1+x}\simeq 1+\frac{x}{2}+O(x^2)\] を使うと
\begin{eqnarray}
s_1-s_2&\simeq&R(C+k)\left[1-\frac{rk}{R(C+k)}\cdot\frac{C-k}{C+k}\right] \\
&=&R(C+k)-rk\frac{C-k}{C+k}
\end{eqnarray}ただし、\(s_1>s_2\) となる解を選んだ。これより、
\begin{eqnarray}
s_1&\simeq&\frac{(s_1+s_2)+(s_1-s_2)}{2}=\frac{1}{2}\left[-kr-rk\frac{C-k}{C+k}\right]=-r\frac{Ck}{C+k} \\
s_2&\simeq&\frac{(s_1+s_2)-(s_1-s_2)}{2}=-R(C+k)+\frac{1}{2}\left[-kr+rk\frac{C-k}{C+k}\right] \\
&=&-R(C+k)-rk\frac{k}{C+k} \\
&=&-R(C+k)\left[1+\frac{rk}{R(C+k)}\frac{k}{C+k}\right] \\
&\simeq&-R(C+k)
\end{eqnarray}となる。ただし、最後の式では、最後から2番目の式の第2項が第1項に比べて、3次の微小量になるので無視した。

極の逆数 = 時定数


ここで2つの時定数を
\begin{eqnarray}
T&=&R(C+k) \\
\tau&=&r\frac{Ck}{C+k} \\
\end{eqnarray}とおく。これらを使うと、
\begin{eqnarray}
s_1&\simeq&-\tau \\
s_2&\simeq&-T \\
s_1-s_2&\simeq&T-\tau\simeq T
\end{eqnarray}となり、
\begin{eqnarray}
V_C(s)&=&\frac{kR}{s_1-s_2}\left(\frac{s_1}{1-s_1s}-\frac{s_2}{1-s_2s}\right)E \\
&\simeq&\frac{kR}{R(C+k)}\left(\frac{-\tau}{1+\tau s}-\frac{-T}{1+Ts}\right)E \\
&=&\frac{k}{C+k}\left(\frac{1}{s+1/T}-\frac{1}{s+1/\tau}\right)E
\end{eqnarray}と求まる。

検出コンデンサの過渡波形


最後に、上記 \(V_C(s)\) を逆ラプラス変換すると、
\begin{eqnarray}
v_C(t)&\simeq&\frac{k}{C+k}\left(e^{-t/T}-e^{-t/\tau}\right)E
\end{eqnarray}を得る。この式から、
  • 振幅が \(\displaystyle\frac{k}{C+k}E\)
  • t=0 で初期振幅はゼロ
  • 括弧内第 2 項は時定数 \(\tau\) で充電されて、急速に立ち上がる
  • 括弧内第 1 項は時定数 \(T\) で放電されて、緩やかに減衰する
ことが分かる。ここで、具体的な数値を当てはめてみると、
\begin{eqnarray}
&&\frac{k}{C+k}E=\frac{5}{330+5}\cdot 3.3=49\,{\rm mV} \\
&&\tau=r\frac{Ck}{C+k}=100\,{\rm Ω}\cdot\frac{330\cdot 5}{330+5}{\rm pF}=0.49\,{\rm ns} \\
&&T=R(C+k)=10\,{\rm kΩ}\cdot 335\,{\rm pF}=3.4\,{\rm \mu s}
\end{eqnarray}となる。

SPICE シミュレーション


下図は、同じくコンデンサ C の過渡波形を SPICE でシミュレーションしたもの。まず振幅が 49mV で一致していることが分かる。充電は速過ぎて見えないけど、放電の様子は、時定数 T の 0.7 倍の 2.4μs 付近で半分の 25mV 前後になっているから、やはり符合している。

v_C(t) の SPICE シミュレーション波形

充電時


時定数 \(\tau=r\frac{Ck}{C+k}\) は、kとCの直列コンデンサを、r で充電する形をしている。下図で、赤矢印の電流の流れに対応する。この式で R が無視できるのはなぜか?

τ は k と C の直列コンデンサを r で充電する際の時定数
両コンデンサを流れる電流はほぼ同じなので、両者の端子電圧は容量に反比例する。したがって、コンデンサ C には、コンデンサ k の k/C 倍程度の電圧しか現れない。その電圧が抵抗 R にかかるので、r から見た R の実効的な抵抗値は RC/k = 0.66 MΩ となり、ほぼ開放とみなせる。そのため、スイッチの投入直後は、抵抗 r を通じて k と C が直列に充電され、コンデンサ C は 49mV に、コンデンサ k は 3.25V に、急速に立ち上がる。

放電時


一方、時定数 \(T=R(C+k)\) は、k と C の並列コンデンサを、R で放電する形をしている。下図で、2本の赤矢印の電流を合わせた流れに対応する。ここで先程と同様に、r を無視できるのはなぜか?

T は k と C の並列コンデンサを R を通して放電する際の時定数
充電直後は、C に49mV 分の電荷が蓄えられており、k にも 3.3V への差分として、3.25V - 3.3V = -49mV 分の負電荷があると考える。つまり、R から見ると、どちらにも同じ電圧 49mV 分の正電荷が蓄えられているとみなす。そして、これらが R を通じて放電されると考える。

この時、両コンデンサの電圧は同じであり、それらを流れる電流値は、両コンデンサの容量に比例する。したがって、コンデンサ k には、コンデンサ C に流れる電流の k/C 程度しか流れない。このことにより、Rから見た r の実効的な抵抗値は rk/C = 0.90Ω となり、ほぼ短絡とみなして問題ない。

これらの電荷が放電され終わると、C の電圧はゼロに、k の 3.3V への差分もゼロになって、つまり、k は 3.3V になって、定常状態に達する。

まとめると


ここでは、各時定数の1倍と、7倍経った時刻を目安に考える。それぞれ \(e^{-1}=0.37\) と \(e^{-7}=0.00091\) なので、これらは 37% 及び約 0.1% に減衰する時間に相当する。

\(t\)\(v_k\)\(v_C\)イベント
000SW1 スイッチ投入
\(\tau=0.49\,{\rm ns}\)2.05V31mV直列に充電中
\(7\tau=3.4\,{\rm ns}\)3.25V=3.30V - 49mV49mV充電完了
\(T=3.4\,{\rm \mu s}\)3.28V=3.30V - 18mV18mV並列に放電中
\(7T=24\,{\rm \mu s}\)3.30V=3.30V - 0mV0mV放電完了=定常状態

放電と言っても、コンデンサ k から見れば負電荷の放電なので、コンデンサ k は常に充電されていることになる。

まとめ

Topre スイッチの微小な容量 k に蓄えられた電荷を、その 100 倍前後の容量 C で一旦受け取る。それにより、電圧出力は容量比 k/(C+k) だけ低下するので、それをオペアンプの非反転増幅回路で増幅し戻す。

検出コンデンサに現れる電圧波形は、ピークが
\[v_C=\frac{k}{C+k}E\]の指数関数的減衰波形で、その時定数は、
\[T=R(C+k)\]となる。今回のモデルパラメータでは、それぞれ
\begin{eqnarray}
&&v_C=49\,{\rm mV} \\
&&T=3.4\,{\rm \mu s}
\end{eqnarray}である。

したがって、この過渡電圧波形の振幅 50mV を検出できれば、Topre スイッチの押下を検出できる。高速なオペアンプを使って、後段の非反転増幅器の増幅度を 20 倍ぐらいにしておけば、1V 程度と十分な出力になるので、マイコンの ADC でしっかり検知できる。

さて、ここで、もし検出コンデンサで一旦受けないと、どういう難しさがあるのだろうか?

例えば、5pF を直接 200kΩ の抵抗で受けると、時定数は 1μs。マイコンの ADC が 1MHz サンプリングなら、それほど悪い数字ではなさそうだ。この抵抗は大きい方が、時定数も大きくなり、抵抗にかかる電圧も高くなって、検出が楽に出来そうだ。

だけど、そうすると、GND との間の浮遊容量のインピーダンスが見えてきて、そちらに電流が流れてしまい、抵抗だけでは確実な出力を得るのが難しいのかも知れない。例えば、100kHz では、5pF の容量のインピーダンスはおおよそ 1/ωC = 320kΩ になる。検出用抵抗の 200kΩ とトントンだ。そこで、浮遊容量よりも十分にインピーダンスの低い、容量の大きなコンデンサで一旦受けるようにすると、検出が確実になるのかも知れない。

以上、久々に TeX を書いた・・・。




2019年12月14日土曜日

エルゴノミック Realforce を作ろう(1)パーツ編

自作キーボードを作ってみたいけど、やっぱりなんだかんだで、自分は Realforce が好きだなぁ、と思う。これがベストなのか?と聞かれるとよく分からないけど、何となく押し心地がよい。飽きずに意味なくカタカタしてしまう。

でも、Realforce は普通の normal staggered 配列なので、一旦エルゴノミックな配列のキーボードに慣れてしまうと、B を押す時に左手人差し指が痛くなってくる。

刻印が見えづらくなっているけど、B は両手どちらからも遠い

こんなことなら、高かったけど、μTRON キーボードを買っておくべきだったかなぁ、と販売終了の時は思った。あれなら静電容量無接点方式だし、キーピッチも 17mm と狭目にしてあって、コンパクトでよさそうだった。

実際、初キーボードではキーピッチを 18.40mm で作ってみたのだけど、いけると思ったのに、やってみるとキーキャップが隣同士で微妙に干渉して、結局キーキャップを1つ1つ手ヤスリで削るコトになった。19.05mm より小さいキーキャップも探したけどなかなか売って無いようだ。

キーキャップの縁がギリギリだし、手で削ったから、微妙にクネクネしておりますよ・・・。

やっぱり μTRON キーボードを買っておくべきだったか?ちなみに当時、クレバリーさんのキーボード専門店舗で少し触ってみた感じでは、自分にはちょっとキーピッチが狭いかな、と感じた。それとあと、やっぱり高かった(汗)

Realforce を自作しよう

そこで、どうせキーボードを自作するなら、Realforce の静電容量無接点方式、というのを作ってみたい!と思って調べ始めた。

Realforce を分解した写真を見ると(自分のは分解して壊したくないので分解してない(^^;> )、そもそも Realforce のキーは、個別に分かれた単体パーツではないらしい。今思うと、「おい〜!そこからかいっ!」と自分で突っ込みたくなるけど、何も知らないって偉大だ(爆)

Varmilo という会社の製品には、静電容量無接点式の単体のキースイッチがある。

Varmilo EC Switch
VARMILO ELECTRO-CAPACITIVE NUMPAD

ただ、キースイッチ単独では販売していないようだ。ふうむ。まれに Varmilo のキースイッチでキーボードを組んでる方を見かけるけど、あれは Varmilo のテンキーとかストラップを買ってバラして作っているのだろうか?!

パーツの入手方法

さてさて、Realforce の各キーは、バネとラバードームとスライダとハウジングが、この順で基板の上に積み重なった構造をしている。これらを買ってこれば Realforce を作れそうだ。

左から、円錐バネ、ラバー ドーム、スライダ、ハウジング

スライダとハウジング


NiZ という、同じく静電容量無接点キーボードを製造販売しているサイトで、パーツとして購入できる。

2019 NEW NIZ EC switch

Topre (東プレ。Realforce、HHKB の製造元)互換だけど、本家 Topre 製との違いは、本家はハウジングのサイズが 14x14.6mm なのに対して、こちらは 14x14mm なのと、スライダが MX キーキャップ互換になっていること。HHKB 用のキーキャップを探さなくても、普通に売られている MX 用のキーキャップが使えるので選択肢が増える。あと、スライダに静音化リングが最初から付いている。

黒が本家 Realforce で、白が NiZ
本家 Topre 製はハウジングの底にでっぱりが付いていて、ラバードームの切り欠きと合わせてあったり、スライダがハウジングにカチッとはまって、ひっくり返しても落ちないようになっている。NiZ のスライダはスルッと抜けてしまうので、何度も床にぶちまけた(笑)

ラバードーム


上記 NiZ のサイトで、キーボード1枚分の全体のひとつながりラバードームシートを販売している。

EC Silicone Domes 35g 45g 55g

これを自分のキーボードに合わせて切り出して使うことができる。カッターではなかなかうまく切れないので、ハサミで切ると、夏休みの工作感が満載になる。

ファンクションキーの一部を切り取って使った後
また、以下のサイトでは、1つ1つバラバラのラバードームを販売している。

BKE Topre Dome Replacements

こちらはタクタイル感があるのが特徴のようだ。僕はリニアタイプが好きだから、後回しだけど、そのうち試してみたい。

バネバネバネ


あとはバネだ!、と思ったけど、だがしかし!!困ったことに、バネは売られていない。同じような形のバネを探しても見つけられなかった。でも1個だけなら、

Replacement Topre Conical Spring

で販売している。ちょくちょく売り切れになったり、補充されたりしているらしい。どうやら Realforce をバラして交換用パーツとして販売しているようだ。なかなかいい商売だなぁと思いながらも、自分の Realforce は分解したくないので(再)、今はありがたい。1個購入してみた。でもキーボード1枚分揃えるのは高過ぎてムリだ。

押してみるとかなり柔らかいフニャフニャばね

線径は 0.25mm のようだ
届いたこのバネのサイズを測ってみると、こんな感じ。
  • 内小径:3.5mm
  • 外大径:12mm
  • 高さ:5.5mm
  • 巻き数:2 + 8
  • 線径:0.25mm
この仕様で、バネ製造会社3社さんに見積もりをお願いしてみたら、A社:1個200円、B社:作れないとお断り、C社:1個100円との回答だった。う〜ん、Gateron とか Kailh のスイッチが1個50円程度と思うとちょっと高い。

まとめ

仕方ないので、ヤフオクやメルカリで中古 Realforce を買うことにした。送料・税込で5〜 6,000円ぐらいで買える。これだと1個あたり 50 円ぐらいだし、純正品のスライダとハウジングとラバードームも手に入る。ということで、とりあえずパーツはこれで集まった。

結論としては、Realforce の自作には、パーツ取り用のドナー Realforce が必要である!




2019年12月12日木曜日

STM32F042K6T6 のブレークアウト基板を作成する(後編)

PCB を修正する

前回作成した PCB は、USB の D+/D- がひっくり返っていたのを修正する。それ以外に今回は、
  • ピンに5V 端子を追加(合わせてGNDも追加)
  • シルクに各端子名を表示
  • パーツ配置を色々微調整
という改良を加えた。


基板も初の白色にしてみる。

ちゃんと各ピンに端子名を入れた。やっぱり必須・・・。

LED を焦がす


基板が届いたので、早速ハンダ付けをする。まず、レギュレータまでハンダ付けしたところでテストしてみたら、電源 LED が付かない!?電源 LED を3.3Vではなく、5V から取るように変えた時に、LED の向きを逆向きに変更したことを忘れ、前回の組み立て物を見てその通りに半田付けをしてしまっていた。。。

配線とサーマルパターンはなるべく太めに、と思って作っているのもあり、こういう時に、パーツのハンダ付けを外すのがまだ自分には難しくて、結局、LED を1個壊してしまった。。。

そして、全部ハンダ付けし終わった後、DFU 経由のファームウェア書き込みは、前回のようなトラブルもなく、すんなり出来た。だけど、2つあるLチカ用 LED のうち1つが光らない!?ハンダ付けするときに、ハンダゴテで熱し過ぎていたようだ。。。こちらもハンダの取り外し途中で壊してしまった。。。

この写真は直した後。ここで光っている左側の D2 が壊れていた。

壊れた LED を外すときに、基板の表面も焦がしてしまった。下の写真で、レジストが少し剥がれている。"D2" シルクの周りのレジストもほんのり焼けている。とほほ。

D2 と D2 の上側端子の間が少し茶色く剥がれている

まあでもこれで何とか動いたので、最後にピンヘッダをブレッドボードに刺した状態でハンダ付けして完了!

と思ったら、この最後の最後でも、残念なハンダ付けになってしまった。。。

5V と GND を追加したので左右で 1 ピンずつ多い

上の写真を手前から見たところ
左が前回の組み立てで、右が今回のもの。ピンが斜めっております。写真だとあまり分からないけど、実物だともっとめっちゃ斜めって見えますよ。おかげで、ブレッドボードに刺した時に、1つ隣の列じゃないと、ジャンパーワイヤーが刺さらないでござるよ。。。


特徴


さてさて、気を取り直して、この breakout ボードの特徴としては:
  • 3.3V 250mA
  • 電源 LED
  • Lチカ用 LED x2
  • I2C プルアップ付き(PF0, PF1)
  • BOOT0 スイッチ付き(PB8 w/ プルダウン抵抗)
  • リバーシブルに使えるよう、LEDと抵抗が表裏背中合わせ
というところ。BOOT0スイッチは、DFU 書き込み時以外は、普通にPB8のスイッチとして使えるし、I2Cのプルアップ抵抗は地味に使えそうと思って付けてみた。



J-Link のシリアル経由で printf 波形観察


では、この出来上がったブレークアウト基板で、ADC で取り込んだ波形を見てみよう。I2C のテストとして、液晶ディスプレイも付けてみる。

まず、STM32CubeIDE でピンの設定を行う。I2C と KEYSW, LED1, LED2 のピンは、このブレークアウト回路ではこの位置で固定になる。SWD と USART はデバッグ用。


また、コード側では、
/* USER CODE BEGIN Includes */
#include <stdio .h>
/* USER CODE END Includes */

/* USER CODE BEGIN 0 */
int __io_putchar( int ch ) {
    HAL_UART_Transmit( &huart1, (uint8_t*) &ch, 1, 0xffffffff );
    return 0;
}
/* USER CODE END 0 */
のように printf() で USART に出力されるように実装しておいて、ADC(DMA) の結果を printf() で出力する。

ただしここで、MX_DMA_Init() と MX_ADC_Init() は、以下のようにこの順序で呼ばれないと動かないらしい。今回は CubeMX の手順で何が違ったのか、main() 関数の先頭でこの2つの呼び出し順が逆になっていて、ADC が1サンプルしか取得されず、小1時間悩んでしまった。
  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_USART1_UART_Init();
  MX_DMA_Init();
  MX_ADC_Init();
  MX_I2C1_Init();

あとは、Nucleo ST-Link の J-Link 化を行い、SWCLK, SWDIO, NRST, GND をつなぎ、USART1 の TX, RX もつなぐ。I2C に SSD1306 液晶ディスプレイもつなぐ。そうしてできた、最終的なブレッドボード。

I2C でディスプレイに文字が表示できている

そして、printf で ADC の値を出力して、ArduinoIDE の シリアルプロッタを開くと、こんな感じに波形が出た。めでたし!
I2C の SDA 信号を観測したもの。

感想

今回も失敗だらけだったけど、でも、LQFPのハンダ付けは2回目で、前回よりは上手く出来た?と思う。

あと、今回は初めて白い基板で注文してみたけど、基板の配線をシゲシゲと眺めるのが好きなタチとしては、配線があまり見えなくて少しさみしかった。黒もあまり見えなかったんだよな。もごもご。。。

とはいえ、とりあえずブレークアウト基板は完成!?