ぶていのログでぶログ

思い出したが吉日

bashからfishにした

今まで頑なにbashを使ってきたけどこの度fishに変更しました。 なお、tmuxのデフォルトシェルは変更したけど、ログインシェルはbashのまま!!*1

なんでbashにこだわっていたの?

Linuxサーバではデフォルトでbashが入っている。 手元の環境でもbashを使っていれば、どの環境でも違和感なくオペレーションができるはずという信念からbashを使っていた。

しかし、最近ではサーバ上でオペレーションするよりも手元でオペレーションしている頻度が圧倒的に高い。 また、サーバ上でbashを使っているとはいうが、本当にデフォルトのbashでしかなく、bash固有の機能を使っているわけでもないしキーバイドが同じであれば違和感なくオペレーションできるはず。

デフォルトのbashはお世辞にも使いやすいとはいえず、最近のモダンなシェルの機能を使いたくなったのが今ここだった*2

なんでfish?

当初、乗り換え先はzshを検討していた。 ノウハウも多くネットを検索したり、同僚に聞けばいろいろ情報が得られると思っていた。 しかし、zshも結局いろいろカスタマイズしないと、満足いく環境にならないだろうと言う懸念があった。

そんなときfish-3.0がリリースされたという話を聞いた。 fish-3.0ではなんと &&|| が使えるようになった!という話を聞いて興味をもったのでfishにした。

fishshell.com

fishに入れた設定

デフォルトのままで十分使いやすかったので、今は最低限の設定だけいれている。 特にbash時代に手癖になるほど使っていた自作コマンドのgcdeachだけはfishに移植した。

gcdはghqで管理しているリポジトリディレクトリにcdするコマンドで、eachはxargsの便利版だ。 あれこれ調べた結果以下のようなaliasコマンドで定義している。

alias gcd='set -l s (ghq list | fzf-tmux -1) && cd (ghq root)/$s; :'
alias each='string match -q -e "{}" -- $argv || set -a argv {}; xargs -r -L1 -I{} $argv;:'

ここでポイントなのが、最後に : をつけるところ。 これをつけなくても動作はするのだが、aliasしたコマンドに引数を渡すとエラーになってしまう。 これは、内部的にaliasしたコマンドの最後に $argv を追加するからである。 この追加された $argv を無効化するために : コマンドを呼び出している。

aliasコマンドを作るときにbashスクリプトとの違いを知るために以下のサイトを参考にした。 まさに私に必要な情報で大変にありがたい 🙏

qiita.com

まとめ

fishに変更してからまだ1日くらいしか経ってないがかなり満足している。 デフォルト設定でも十分便利で使いやすい。 1つ不満があるとしたらコマンド履歴をインクリメントサーチできない(bashでいうところのCtrl-r)ところ。 これは、pecoなどを使ったコマンドなんかで代用できるようだ。 本家のissueにも上がっていて3.1で何かしら動きがありそう?なので期待している。

github.com

*1:何も起こらないと思うけどチキって変更していない

*2:もちろんbashの設定を作り込めばいいのだろうけど、そこまでbashにこだわる理由もそこにかける時間もないのであった

M5StackでMicroPythonを使うときのTips

この記事はM5Stack Advent Calendar 201820日目の記事です。


先日SabaBoxというM5Stack + MicroPythonを使ったプロダクトを作ったことを紹介しました。 今日は、SabaBox作成時に気がついたことなどを書いていきたいと思います。

ファームウェア

M5StackでMicroPythonを使うには専用のファームウェアを書き込む必要があります。 MicroPythonファームウェアは以下のリポジトリに存在します。

github.com

MicroPythonファームウェアにはオンライン版とオフライン版があります。 オンライン版は、M5CloudというM5Stack社が運営するクラウドIDEを使ってM5Stackを開発することができるバージョンです。 オフライン版は、USBを接続してシリアル通信で開発するバージョンです。 オンライン版のファームウェアはファイル名のプレフィックスm5cloud であり、オフライン版はm5stackとなっています。 自分が使いたいバージョンを選んでダウンロードするとよいです。

この2つ以外にpsram版というのも存在します。 これは、M5Stack FireなどのRAMを拡張した機種を使うときに使うと良いようです。

書き込み

MacLinuxファームウェアの書き込みを行なう場合にはesptoolを使います。 これはPython製のツールであるため、pipでインストールできます。

pip install esptool

esptoolをインストールしたらM5StackをPCに接続します。 接続するとデバイスファイルが追加されると思います。 ここでは /dev/ttyUSB0 が追加されたこととします。 デバイスファイルを確認したらファームウェアを書き込みます。

# フラッシュ
esptool.py --chip esp32 --port /dev/ttyUSB0 erase_flash

# ファームウェアの書き込み
esptool.py --chip esp32 --port /dev/ttyUSB0 write_flash --flash_mode dio -z 0x1000 firmware.bin

パーミッションエラーになる場合は適宜sudoを使うなりしてください。 Linuxの場合、生えてくるデバイスファイルの所有グループがdialoutになるため、ログインユーザをdialoutグループに所属させると良いと思います。

シリアル接続

MicroPythonファームウェアの書き込みが完了するとリセットがかかります。 起動後に、M5Stackデバイスにシリアル接続を行なうとMicroyPythonインタープリタ画面に接続できます。 シリアル接続を行なえるコマンドはいくつかありますが、私はGNU screenを使用しています。 GNU screenでシリアル接続を行なうには以下のようにコマンドを実行します。

screen /dev/ttyUSB0 115200

コマンドを実行後、Enterキーを押すと >>> と表示されると思います。 この画面はインタープリタになっているので直接Pythonのコードが実行できます。 以下のように入力するとM5StackのLCDhello world と表示されると思います。

>>> from m5stack import lcd
>>> lcd.print('hello world!')

シリアル接続から切断するには、GNU screenの場合Ctrl-a -> :quit と入力します(またはCtrl-a -> \)

ソフトリセット

プロンプトを表示した状態で Ctrl-D を押すと、ソフトリセットができます。 何かがおかしくなったときに使います。

>>> (Ctrl-Dを押す)
ESP32: soft reboot
ets Jun  8 2016 00:22:57

rst:0xc (SW_CPU_RESET),boot:0x17 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:2
load:0x3fff0018,len:4
load:0x3fff001c,len:4636
load:0x40078000,len:0
load:0x40078000,len:12948
entry 0x4007852c

Internal FS (SPIFFS): Mounted on partition 'internalfs' [size: 2424832; Flash address: 0x1B0000]
----------------
Filesystem size: 2221568 B
           Used: 16128 B
           Free: 2205440 B
----------------

Device ID:840d8e25c144

FreeRTOS running on BOTH CORES, MicroPython task started on App Core (1).

 Reset reason: Soft CPU reset
    uPY stack: 19456 bytes
     uPY heap: 80000/9984/70016 bytes

MicroPython ESP32_LoBo_v3.2.16 - 2018-05-15 on M5Stack with ESP32
Type "help()" for more information.

エディタモード

プロンプトモードでCtrl-e を押すとエディタモードになり、ファイルに書き込めます。 書き込み先は main.py になります。 エディタモードを終了するにはCtrl-dを入力します。

複数ファイルの書き込み

エディタモードを使えばmain.pyに書き込むことはできますが、複数のファイルを使うことができません。 ampy というツールを使うとファイルを書き込むことができます。 ampyもpythonのツールなのでpipでインストールができます。 パッケージ名がampyではないので注意が必要です。

pip install adafruit-ampy

ampyはシリアル接続を抜けた状態で使用します。 たとえば、ローカルにあるmain.pyをM5Stackにアップロードするには以下のように実行します。

ampy --port /dev/ttyUSB0 put main.py

第3引数を省略すると /flash 配下にアップロードされます。 また、--portでポートを指定してますが AMPY_PORT 環境変数を設定しておけば省略できます。

export AMPY_PORT=/dev/ttyUSB0
ampy put main.py

使用できるAPI

使用できるAPIリポジトリのREADMEに記載されています。 …が記述が古かったりしてたまに間違っていたりします。 そういう場合は、私はQiitaとかを検索して確認していました。。 ぐぐるとMicroPythonのAPIドキュメントがヒットしますが、M5Stack MicroPythonが使用しているバージョンと乖離があり使えないことが多いです。。

非公開?なAPI

READMEに書いてあるAPIにも使用できるAPIがあります。 例えば、スレッドとかです。 これは以下のWikiにのっています。

github.com

これはM5Stack MicroPythonがBASEにしているファームウェアで、このファームウェアで使えるAPI群になります。 Curlやスレッドあたりは興味深いで機能です。

スレッド使用時の注意

スレッドは大変便利なのですが、使用方法を間違えるとCPUパニックを起こします。。 例えば、スレッドの中からファイルに書き込みを行なうと確実にCPUパニックを起こします。。

CPUパニックを起こすとリセットがかかります。

無限ループになった時の回避方法

CPUパニックが起きるコードをアップロードしてしまい無限ループに陥ってしまった場合は、起動時にボタン1(左のボタン)を押しているとセーフモードになります。

セーフモードではmain.pyが自動実行されないので、main.pyを安全なものに書き換えて再起動すると回避できます。

おわりに

MicroPythonファームウェアを使う時のTipsをまとめてみました。 MicroPythonを使うとより簡単に作りたいものを作ることができると思います。 MicroPythonはPython3ベースになっているため、非常に書きやすいと私自身感じました。

この記事がM5Stackで開発しようとしている人の助力になればと思います。

業務で使っているPCをLinuxデスクトップにしてから半年が経った

この記事はGMOペパボ Advent Calendar 2018の19日目の記事です。


会社PCをLinuxデスクトップにしてから半年が経ったので感想とかTipsとか書きます。

なぜLinuxデスクトップにしたのか?

以前はMacBookProを使ってました。たしか、2015年後期モデル。 半年前にそのMacBookProのレンタル期限が切れたので、新しいMacBookProに更新するかどうか悩んだ。 でも、キーボードはペチペチだし、ESCキーもないし、Appleにロックインされるのが嫌だったのでLinuxにすることにした。 Windows Subsystem for Linuxも考えたけど、ネイティブでLinux使いたかったのでWindowsは選択しなかった。

実際どうなのか?

普通に使える。けど、会社の環境のおかげかも知れない。 ペパボでは、G suiteを使っているのでブラウザがあればドキュメントのやり取りができるし、メールもできる。 MacWindowsが絶対に必要ということがないのも、普通に使えている要因かもしれない。

普通に使えると書いたけど、ハマりどころもたくさんある。 後述するけどマルチディスプレイ関連とか、カーネルアップデートしたら起動してこないとか、なんか挙動がおかしいとかあって、そういうのを自分でなんとかしようという気持ちがないとLinuxデスクトップを使っていてつらいかもしれない。 逆にそういうのが許せるなら、カスタマイズでいろいろできて楽しいはず。

使っている機種とディストリビューション

Dell New XPS13(9370)を使っている。 MacBookProと遜色ないスペックだったし、Ubuntuデスクトップの動作確認が取れていたりしたのでNew XPS13を選択した。

ディストリビューションはUbuntu18.04。だけど、今はアップデートしたのでUbuntu18.10を使っている。 Linuxデスクトップの常用は始めてだったので、Ubuntuデスクトップなら情報が多いだろうと思って選択した。

Windowsとのデュアルブート

会社的にも私的にも始めてだったので、なにかあったときようにWindowsとのデュアルブートにしている。 最近のWindowsはダイナミックボリュームになっていて、後からボリュームの縮小ができてとっても便利だなぁっと思いました(小並感

使用しているツール

くらいかなぁ。

HiDPIについて

New XPS13は4Kディスプレイなのだけど、DPIを100%にすると小さすぎて文字が読めない…。 逆に、200%にするとでかすぎる…。 この中間くらいにしたいのだけど、今のUbuntuのディスプレイ設定では選択できないのであった。。

f:id:buty4649:20181219215431p:plain
ディスプレイの設定画面

しょうがないのでxrandr*1を使っていわゆる小数点DPIを設定している。 例えば、以下のようにすると拡大率が140%になる。

$ xrandr --output eDP-1 --mode 3840x2160 --panning 5376x2160 --scale 1.4x1.4

--panning を指定するところがポイントで、これを指定しないと、画面の最大サイズは5376x2160なのに、デスクトップ領域が3840x2160までしか使えず悲しい気持ちになる…。

で、これで快適な生活をおくれるようになっただけど、この設定は永続化しないのでなんとかしないとならない。 そこで、autorandrというツールを使ってこの問題を解決した。 このツールはxrandrの設定を保持してくれて、よしなに設定を復元できる。 aptで入るのもとてもよい。

$ sudo apt install -y autorandr

# 今の設定を保存する
$ autorandr -s eDP-1

# 手動で設定を復元する
$ autorandr -l eDP-1
# または
$ autorandr -c

マルチディスプレイ問題

この問題が非常に悩ましい…。 外部ディスプレイを接続すると正しく表示されなくて非常に困る…。 autorandrでマルチディスプレイ用の設定を保存しても、たまにうまく設定が復元されず画面がおかしくなったりする…。 また、OSのディスプレイ設定画面でマルチディスプレイを設定できるのだが、デュアルモニタにするとpanningをちゃんと設定しないのかおかしいことになる。。 画面のクローン設定にしてもうまくいかないことが多いうーむ。。 そのため、勉強会とかで発表を行なうときにつらい気持ちになる…。

autorandrを使うことで一応は解決できることがわかっている。 さっきと書いていることが違うじゃないかと思うかも知れないが、autorandrの自動復元機能ではなくデフォルトで用意されているプロファイルを使う。 commonclone-largest というデフォルトのプロファイルがあるので、どちらかを使うとautorandrがいい感じにマルチディスプレイを設定してくれる。

ここらへんはさすがにMacWindowsのほうが出来がいいなぁっと思う。

cgroupの利用

例えばSlackとかで大量にリソースを食って他のアプリが遅くなるということを経験したことがあると思う。 Linuxの場合、cgroupを使えば手軽にリソース制限ができるのでこの問題が解決できる*2。 cgroupを使うのはちょっとめんどくさいがまつもとりーさんが作ったrconを使えば簡単にcgroupが扱えて便利。

# --type=renderで絞らないとGPUアクセラレーション用のプロセスも制限してしまいカクカクになってしまう
$ sudo rcon --cpu 50 --pids "$(pgrep -f "slack --type=render" | paste -sd" ")"

最後に

Linuxデスクトップ環境にしてからのあれやこれをつらつら書いてみた。 今回紹介できなかったけどSnapcraftを使えばrbenvが不要になるかもしれなかったり、Dockerがネイティブに使えるといったLinuxならではのメリットもあるはず。 つらいところもありますが、個人的にはLinuxデスクトップ環境に変えてよかったと思っています。

エンジニア全員にLinuxデスクトップ環境の常用を勧めるわけではないけど、こういう選択肢もあるよというのが伝われば幸いです。

*1:えっくすあーるあんどあーるって読むらしい

*2:というのを最近気がついた

SabaBox (mackerel-agent on M5Stack) を作った

この記事はMackerel Advent Calendar 2018の13日目の記事です。


みなさん、IoTしてますか! 今年のMackerel Advent Calendarのテーマは IoTとMackerel ということで[要出典]、私も作ってみました! それがこのSabaBoxです!

拡大したところ

Mackerelのロゴをドット打ちしたのがこだわりポイントです!*1

M5Stackとは

この真ん中にあるTFTディスプレイがついた箱がM5Stackです。 ESP32というWiFiBluetoothを持ったマイコンを搭載した便利な開発ボードです。 機能を拡張する基板をスタックしていくので、この名前がついているようです。 開発はArduino互換なので、慣れていればすぐにプロダクト開発ができるのがよいですね!

そして、なんとこのM5StackではMicroPythonが動くファームウェアが公式に配布されているのです*2

github.com

今回はLL言語でサクッと実装したかったので、このMicroPythonを使って実装しました。

SabaBoxのインストール

前述しましたがSabaBoxはMicroPythonを使って実装されているので、M5StackにMicroPythonファームウェアを予めインストールしておく必要があります。 なお、オンライン版とオフライン版がありますが、どちらでも動くはず…たぶん(オンライン版での動作は未確認)。

次にソースをコピーします。SabaBoxのソースは以下のリポジトリにあります。

github.com

ソースをコピーしたら、settings.json.sampleをコピーしsettings.jsonを作成します。 settigns.jsonには、Mackerel APIKey、SSIDとパスワードを設定します。 また、センサープラグインも指定する必要がありますが、サンプルではfetchごとにカウンターをインクリメントするだけのcounterプラグインが指定されています。

// settings.json.sample
{
    "mackerel": {
        "apikey": "<APIKEY>"
    },
    "wifi": {
        "<SSID>": "<PASSWORD>"
    },
    "plugins": [
        "counter"
    ],
    "autodisplayoff": 20
}

つぎに、SabaBoxのソースをインストールします。 インストールには、install.shを使うとちょっと便利です。 install.shは内部的にampyを使うので、事前にインストールしておきます。

$ pip install ampy

ampyをインストールしたらinstall.shの引数にはM5StackのUSBポートとSabaBoxにインストールプラグインファイルを指定します。 ここでは例として/dev/ttyUSB0とsample/counter.pyを指定しています。

$ cd /path/to/SabaBox
$ ./install.sh /dev/ttyUSB0 sample/counter.py

インストールが完了したら、M5Stackを再起動すればSabaBoxが起動するはずです。

SabaBoxで温度と湿度を計測する

サンプルのカウンターでは面白くないので、今回はスイッチサイエンスで買ったM5Stack用プロトキット(温湿度センサ付き)についてきた、温度湿度センサーを使ってグラフ化してみました。

f:id:buty4649:20181213232846p:plain
SabaBox(温度湿度のグラフ)

なんかそれっぽくなっている出ていますね!!!

課題

それっぽいグラフが出来ていますが、これをちょっと拡大してみます。

f:id:buty4649:20181213233114p:plain
SabaBox(温度湿度のグラフ)を拡大

なんか歯抜けになっていますね・・・・・・・・。 原因はわかっていないのですが、SabaBoxを稼働させていると10分ごとくらいにCPUパニックによる再起動がかかるのが原因です。 1分ごとのトリガーでセンサーのフェッチを行っているのですが、それとWiFiの接続状態とNTPのシンクタイミングでなんか死んでるのかなぁという予想をしています…が特定できてないです。 センサーくらいであればちょっと歯抜けてても問題ないだろうと思っているのでv1.0.0ではこのままリリースしました。 まぁ、本番のサーバで歯抜けが置きていたら大問題ですがね!!!!!!! HAHAHAHA

最後に

M5StackのMicroPythonを使ってmackerel-agentを作ってみました。 M5Stackのファームウェアがよく出来ているというのもありますが、MackrelのAPIもシンプルでドキュメントもしっかりしていて、SabaBoxのようなプロダクトを簡単に作れるのが良かったです。。

今回はM5StackにUSBケーブルを刺してそこから給電して動かしていましたが、M5Stackには標準でバッテリーパックが搭載されていたり、また、拡張用のバッテリーパックが売っていたりします。 拡張用のバッテリーパックを使って動作させると、9時間半くらい動作しました。 WiFiも電源もない場所に、SabaBoxをおいてデータだけ記録させ、ある程度蓄積したらWiFiのある場所に移動してデータをアップロードするみたいな使い方ができたら面白そうだなぁっと思っております。

*1:ロゴのアレがあれだったら修正します 🙏

*2:MicroPythonとは組み込み向けの小型のPython3ランタイム

最高のポインティングデバイスを求めて 〜ミニトラックボール編〜

この記事は自作キーボード #2 Advent Calendar 2018の7日目の記事です。 昨日は@ffilccooさんのキーボードカスタムについてでした。 市販のキーボードのカスタムについて書かれていて、ENDGAMEキーボードは時間と共に変化する!! これは本当にそのとおりだと思います。 昨日の記事以外にも素晴らしい記事を書かれているのですが、残念ながらジオシティーズ終了とともにサイトが消滅してしまうようです。。 消滅の前に他のサイトにお引越しされることを願っております。


こんにちは、トラックポイントオタクです! でも、今日はミニトラックボールの話をしたいと思います(ぇ

トラックポイントの悩み

私はトラックポイントがとても好きなので、すべての自作キーボードにつけたいとおもっています。 しかし、トラックポイントを自作キーボードに取り付けるには様々な課題があります。

  1. トラックポイントモジュールが単体で売っていない*1
  2. 結構基板がでかい
  3. ProMicroのピンを専有する
  4. トラックポイントキートップツライチにするには加工するしかない

私が思いついた限りではこれだけ問題があります。 これらを解決して、自作キーボードに取り付けるには様々な苦労があります*2

そこで、これらの問題を解決して汎用的に使えて自作キーボードに取り付けられるポインティングデバイス探しをはじめました。

ミニトラックボールマウスの試作

私が出会ったナイスなデバイスが、冒頭の画像にあるミニトラックボールです。 このミニトラックボールは、BlackBerryに使われていたものらしいです。 私が手に入れたモジュールは、ミニトラックボールにSTMマイコンを搭載してI2Cで通信できるものです。 私はスイッチサイエンスで購入しました*3

I2Cで通信できるので、HelixやErgoDashなどすでにI2Cを使っているPCBではそのまま接続できます。

ミニトラックボールマウス

早速このミニトラックボールとQMKを使ってマウスを作ってみました。 まだ試作中なのでブレッドボードですw

ソースはここにあります。

ミニトラックボールマウス by buty4649 · Pull Request #8 · buty4649/qmk_firmware · GitHub

ソースの解説

特に難しいことはしていないです。 rules.mkに POINTING_DEVICE_ENABLE = yes を追加してQMKのPointingi Device機能を有効にしています。 また、HelixやErgoDashで使っているi2c.c/i2c.hをコピーしてきて使っています*4

keymap.c に pointing_device_init関数とpointing_device_task関数を追加します。 前者でデバイスの初期化を行い、後者でマウスの処理を行います。

ミニトラックボールバイスとの通信はサンプルコードを参考に実装しています。 4軸のセンサーと通信を行い変化量を検出し、その量に応じてマウスの速度を決定しています。 センサーの変化量は、pointing_device_taskが呼び出される間隔が短いせいか私が試したときは0〜2でした。 それに比べて、マウスの速度の変化量は-128〜128のレンジであるため、4軸センサーの変化量をそのままマウスの速度にしても微動だにしません。 今の実装では、変化があった方向に対して50倍した値をマウスの速度にしています。

課題1: 操作性

マウスの速度の決定方法については前述したとおりです。 しかし、変化量が固定であるため、細かい操作や逆に画面端から端にマウスを移動するみたいなときに不便です。 変化量を調整するためのスイッチを新たに増設する案が思いつきますが、これはこれで不便です。 そのため、将来的には加速度を考えるようにして、改善したいと考えています。

課題2: 大きさ

実は結構大きいです。以下の写真は、なぜか手元にあった紫軸を並べています。

この画像からわかるように、キースイッチの2倍くらいの大きさがあり、適当なスイッチの代わりに配置するには大きいです。 そのため、ErgoDashにつけるときは親指部分につけようかと画策しています。

I2C通信はできないですが、ミニトラックボールだけを実装したちょっと小型なモジュールもあります(ICSH044A)。 以下の写真右側。

どちらの基板の方が使いやすいかは調査中…。 仮にICSH044Aを使う場合は、I2Cへ信号変換しないといけないので、その部分はBeetle Virtual Keyboardで作ろうと思ってます*5。 ICSH044Aはなぜか4色のLEDがついていて、その分だけ基板がでかくなっています。。 この部分を省いてより小型にならないかなぁ・・・。

課題3: I2C通信が失敗する

GROVE版の基板とProMicroの相性のせいかもしれませんが、一度I2C通信がエラーになると、電源を切るまでエラーのままです…。 エラーになったあとにi2c_reset_stateを呼び出しているけど直らずよくわからん…。

まとめ

トラックポイントの代わりとしてミニトラックボールポインティングデバイスとして利用する方法を紹介しました。 まだ、ErgoDashに取り付けられていなくて実運用にのっていないので、実際に運用をしはじめたら新たに問題が出てくるかもしれません。 その時は別途ブログで報告させてもらいます。

おまけ

この記事だけでは、自作キーボードアドベントカレンダーに投稿されている他の記事の熱量には足りない!!!!!!! っと思ったので、積んでいたHelixにトラックポイントをつけた話のその3とその4を同時に投稿しました! ご興味があれば、あわせて読んでいただけると嬉しいです 😊

buty4649.hatenablog.com

buty4649.hatenablog.com

この記事はErgoDashを使って書かれました。

*1:PS/2で通信する基板は古いThinkpadにしかついてなく供給の問題もある

*2:Helixに取り付けられたのは幸運でした

*3:今見たら在庫切れになってますね・・・

*4:当初 drivers/avr/i2c_* なライブラリが使えると思って試していたのですが、ProMicroでは使えないことに気がついて絶望した…

*5:そこそこ小さくてATmega32u4を詰んでいるので

自作キーボードHelixにトラックポイントを付ける その4

その1その2その3

書き忘れがなければこれで最後! これまでの連載でトラックポイントが動いているはず!

…なのだが、キー入力の取りこぼしが発生しているため何回かキーを打っていると入力されていないキーが出てくる。。 これによってパスワードが通らなくなったりしてかなりつらい…。 どうしたものか…。

なぜキー入力を取りこぼすのか

トラックポイント基板とProMicroの接続は、Interruptモードで接続しているというのはその2で紹介したとおりだ。 トラックポイント基板というかPS/2プロトコルが定期的にクロックを飛ばしていて、ProMicroがクロックを受けると割り込み処理が発生して信号を処理する。 キー入力中に割り込み処理が発生すると、キー入力処理はスキップされてしまい結果として、キー入力の取りこぼしにつながる。 QMKのドキュメントにUSARTモードがbestと書かれているのは、USARTではこういったことが起こらないからだろうと思った。

対処

では対処をどうするか。 解決策の1つとしては、ゆっくり打鍵するというのが考えられる。いわゆる運用カバー。 キーが入力されている時間が増えれば、割り込み処理が発生してもキー入力処理が実施される確率が高くなるため取りこぼしする可能性は低くなる。 欠点として、最高のキーボードを求めているのにゆっくり打鍵しないといけないというのは矛盾した行為になるということだw

もう1つの解決策として、無駄な割り込み処理をなくすと言う方法がある。 トラックポイントを操作していなくてもクロック信号が出ていて、これが取りこぼしに影響するなら、割り込み処理を停止してしまえばよいという発想である。

割り込み処理の無効/有効は、PS2_INT_OFF/PS2_INT_ONマクロで定義されている。 次にどこに処理を入れるかだが、私はPS/2マウスのタスクを定義している部分*1に直接書くことにした。 そして、通常は割り込み処理を無効にしておき、3回に1回割り込み処理を有効にするようにした。 このパラメータはあまり論理的根拠がなく、実運用で調整しながらこの値にした。 詳しいコードは以下を見て欲しい。

https://github.com/buty4649/qmk_firmware/pull/7

まとめ

割り込み処理の回数を制限することで、キーの取りこぼしが減り快適なタイピングが行えるようになった。 しかしこの変更は、tmk_core配下を直接書き換えていてあまりよろしくない。。 ちゃんと調査できていないのだが、マウス処理用のuser関数あたり*2をkeymaps.cに書いてその中で制御する方がより汎用性が高くなるとおもう。

その1〜その4までで、Helixにトラックポイントを付ける方法を紹介した。 この方法は、QMKを使っているほかの自作キーボードにも使えると思う。 これらの記事がトラックポイントを付けたいと思っている人の役に立てば幸運である。

*1:tmk_core/protocol/ps2_mouse.c

*2:存在していれば

自作キーボードHelixにトラックポイントを付ける その3

その1その2トラックポイント基板の準備とQMKの準備ができた。 今回はHelixへの組み込みについて書く。

今回書いた内容については、かなり試行錯誤して今の形になった。 もっとよいやり方はあるだろうが、今の私にはこれが限界だった。。 もし、Helixにトラックポイントを付けるという人がいたら参考程度に見てほしい。

底面アクリル+トラックポイント基板

表面

裏面

拡大

その1で書いた通り、トラックポイント基板(写真真ん中)は裏側からねじ止めしている。 トラックポイント基板の金属の枠部分は取り外しても良いのかわからなかったのでそのままにしている。 また、HelixのPCBに接触してショートしないようにカプトンテープをこれでもかと貼っている。

トラックポイント基板にリセット回路(写真右側)を取り付け、そこから左下のマウスボタン用の基板まで線を這わせている。 リセット回路やマウスボタン基板(写真左側)までの配線には、ポリウレタン線を使っている。

マウスボタン基板から、Vcc、GND、CLK、DATA線のみ足を出してショートピンソケットを取り付け、Helix PCBの接続出来るようにした。

Helix PCB

Helix PCB側の改造は、ProMicro付近のみである。

表面

裏面

Helix PCBは左右で対象になるように回路設計されている。 そのため、トラックポイント基板と接続するVcc、GND、CLK、DATAのピンは、本来であれば左手側で接続することになる穴から線を伸ばすことにした。 当初は、今のようにピンをまとめる形ではなく、PCB裏側にL字コネクタを直接半田する形式を取っていた。 この方式をやめたのは、マウスボタン基板から4本長さの違う線を出さなくてはならず、分解のたびに付けたり外したりするのが面倒だったのと、特に9/10ピンあたりのL字ピンがほかのピンに干渉することが理由である。

ProMicroの下側には、ランド付きの穴が空いており、これを利用してマウスボタン基板との接続を行うことにした。 使用する穴の位置は、ProMicroと干渉しない位置に設定した。

マウスボタン

最後にマウスボタン。 これはつけなくても、マウスボタンのキーコードを適当なキーに割り当てることで同様のことが行えるが、私のキーマップでは3キー分割り当てる余裕がなかったため、物理マウスボタンを別途作成した。 この物理マウスボタンは、底面につけたマウスボタン基板とつながっている。 各スイッチは、トラックポイント基板から出ているButton1/2/3用の信号線とGNDをショートするだけである。

物理マウスボタンは何度も作成しないした経緯がある。 この連載シリーズのその1のときは側面につけていた。 しかし、側面につけると物理マウスボタンを押し込んだときにHelixが動いてしまうという問題があった。。 また、このときに使っていたスイッチはタクタイルスイッチで、押し込むのにそこそこ力が必要というのも、Helixが動いてしまう問題に拍車をかけていた。 このような問題から、タクタイルスイッチからキースイッチに変えたり、側面からPCBと平行につけるように変更したりして、今の形に至る。 たしか、5世代目くらい。

ここまでのまとめ

今回は、物理的な組み込みについて紹介した。 今となってはもう少しやりようがあったなぁ…という感想。 また後から知ったのだが、私が使ったトラックポイント基板はThinkpad T40のものなのだが、X60の基板ならもう少し薄くて小さくなっている。 こちらを使えばもっとコンパクトにできたかもしれない。