ブログ

ορεσικα ψομαναι κυσο βλογ

Nexus 6P 早期シャットダウン問題(と対処法)

寒いと落ちるNexus 6P

バッテリーの残りが20~30%あるのに、突然Nexus6Pがシャットダウンするという問題が世界中で起こっている。私のも昨年の12月半ばあたりからその症状が出始めて、今では残り60%でも寒いとシャットダウンするという鬼畜仕様になっている。

世界中の叫び

https://code.google.com/p/android/issues/detail?id=227849

大まかにまとめると、寒い場所で落ちやすい、電力消費の大きいときに落ちやすい、優先度smallってフザケンナさっさと直せ、という感じでみんな怒ってる。特に、車で事故って写真撮ったり電話したりしてるときに落ちて困った、という報告はかなり気の毒である。死者がでたらどうすんだゴルァという書き込みもある。

今日は40%くらいまでは持った。本当に、ありがとうございます。

f:id:XX-Prime:20170124220307p:plain

一旦冷えてからスリープ解除すると強制シャットダウンというお馴染みの流れ。寒いと動かなくなるのは爬虫類だけで十分である。

Nexusヘルプセンターに連絡

support.google.com

Nexusヘルプセンターの右上に お問い合わせ というリンクがあり、(昼間だけ)電話での連絡を依頼することができる。これを依頼して症状を説明した所、交換対応という結果になった。保証はすでに切れているが、特別に対応してもらえた。一年後にまた爬虫類状態になる可能性は極めて高いが、このまま使い続けるよりはマシである。

まとめ

同じ問題に苦しんでるかたは連絡を依頼してみてはどうだろうか。向こうから自発的に連絡してくるほどgoogleのサポートは優しくないようだ。

ジャンパケーブルオスメス問題

なんか作るときにジャンパケーブルが必要になって

  • オスーメスのケーブルが欲しいのにオスーオスしかない
  • オスーオスのケーブルが欲しいのにメスーメスしかない
  • メスが欲しいのにまわりにオスしかいない

などの問題が生じて発狂することがよくあるが、少なくともケーブルの問題を解決するそこそこうまい方法はある。

ケーブルはメスーメスしか買わない

オスーオス、オスーメス、メスーメスの三種類のジャンパケーブルがあるが、メスーメスだけあれば十分である。

バラ売りされているジャンパケーブルは地味に高価なので、無用なケーブルを用意するのは馬鹿げている。

さらに、

digitalparts.net

のようなリボン状のメスーメスケーブルを買えば比較的安く大量の本数を入手できる。割いて使うこともできるので、I2C用に4本だけまとめて切り離して使う、などバラ売りのケーブルより便利である。

オス化

akizukidenshi.com

のような両端が長いピンヘッダを用意しておく。これも1つずつ割いて使えるので、オスが必要な方に挿せばオスになる。メスからオスが生まれるのは生物界と同じである。

まとめ

オスのジャンパケーブルって要らなくね?

Rの代入演算子 <- をtypoして恐ろしいことが起こった

問題

Rで

x <- c(1, 2, 3)

は、xという変数に右辺のベクトルをアサインする式だが、この <- という演算子

y <-- c(1, 2, 3)

と打ち間違えると何が起こるか分かるだろうか?そんな演算子ねーよボケ、とエラーを吐いて停止するだろうと人間なら期待するが、R処理系は世にも恐ろしいことをやってのける。

答え

上の式のアサイン(?)は何の警告もなく完了し、yの値を出力すると

> y
[1] -1 -2 -3

と、各要素を-1倍した反対向きのベクトルがアサインされる。もう少し分かりやすく言うと、パリティ反転されたベクトルがアサインされる。同一文字を2回間違って入力することはたまにあるが、アサイン演算子のマイナス記号を2回入力したのを気づかないまま解析を進めると、この世ではあり得ない結果がどんどん出てきてデバッグに時間を盗られて夜中の2時56分にこのような下らない記事を書く羽目に陥る。

まとめ

この鬼畜仕様は何か意味なり歴史があるのだろうか?

追記

z <--- c(1, 2, 3)

> z
[1] 1 2 3

と、もう一回パリティ反転されてもとに戻ったw

w <-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- c(1, 2, 3)

パリティはどうなるだろうねえ。

Beaglebone Green Wireless (BBGW) とADXL345で振動解析(補足)

本当に回転運動か?

前回は、電動歯ブラシの振動を加速度センサで計測して、FFT解析の結果ほぼx-z軸のみにデルタ関数っぽいパワースペクトルが出たので、回転する偏心おもりによって振動が作り出されていると推測した。

FFT解析前のデータを二次元プロットしてみたところ、さらにそれを裏付けるきれいな図が得られた。

f:id:XX-Prime:20161215231944p:plain

RStudioにデータを取り込んで素朴なplot関数でx軸とz軸の加速度データを繋いだ図が上図で、たしかに回転運動をしていることが見て取れる。

上図では時間の情報が圧縮されて消えているため、plot_lyライブラリを使って、時間軸をz軸にとった三次元グラフも確認のために描いてみた。

f:id:XX-Prime:20161215232410p:plain

円筒形の表面に測定点が張り付いているような三次元プロットが得られた。光学の円偏光と同じパターンで、回転運動をしていることがよくわかる。

まとめ

FFT解析の後にやっと生データをプロットするあたりが腐れ外道。

Beaglebone Green Wireless (BBGW) とADXL345で振動解析

動機

振動検査システムはかなり高額なものが一般的で、センサ部分だけで10万円以上するものも多い。そこで、なるべく安価に、あまり精度は追求せずに振動を常時監視できるシステムを作りたい。機器の予防保全などの、本当に役に立つ方向への応用が考えられる。愚にもつかないお手軽なゴミデモシステムを作って「これがIoTです」とか言ってる連中が巷に溢れている現状にはため息が出るけど、そういうのは Industries of Trash と呼んであげる。

BBGW

Beaglebone Green WirelessはBeaglebone Black互換機のBeaglebone GreenにWi-FiBluetoothの無線通信機能が追加された最新の派生型である。UDOO NEOと同じ無線チップが実装されているので、うるっせえ技適の問題もない(はず)。

xx-prime.hatenablog.com

Beaglebone Green Wirelessはなぜか日本では販売されていないが、製造元のSeeedStudioから直接購入できる。

https://www.seeedstudio.com/SeeedStudio-BeagleBone-Green-Wireless-p-2650.html

現時点で5115円である。日本国内で外部アンテナをつけるかつけないかは勇気の問題である。

Beaglebone Green WirelessにはGroveコネクタが実装されているので、多種多様なセンサを簡単に確実に接続できる。Groveの振動センサ(加速度センサ)は感度に応じて3種類(±1.5g, ±16g, ±400g)あるようだが、特に要件が定まっていないので真ん中の±16gのものを選んだ。

Grove - 3 Axis Digital Accelerometer(±16g)

Grove - 3 Axis Digital Accelerometer(±16g) - Seeed Wiki

実店舗だと秋葉原のマルツ2号店で入手できた。千石電商は通販で手に入るが実店舗にはなぜか無いので店の中で落胆することになる。

www.marutsu.co.jp

これはAnalog Devicesの3軸加速度センサADXL345を実装しているGroveモジュールで、BBGWのI2Cコネクタに接続するだけでハードウェアの準備はOK。

f:id:XX-Prime:20161206213800j:plain

2つあるGroveコネクタのうち右のコネクタはUARTなので、眠いときに間違って挿して動かないと目が覚める。

ADXL345のスペックシートは以下。

http://www.analog.com/media/jp/technical-documentation/data-sheets/ADXL345_jp.pdf

どうしてもはんだ付けをしないと気がすまないド変態は、ADXL345のブレイクアウトボードを使う手もある。

www.marutsu.co.jp

なぜかGroveモジュールより高い。こっちだとアドレスピンの設定でSPIで通信できたり柔軟に使い倒せるが、スペックシートを読んで設定を理解する必要がある。ろくに読まずに謎の不安定動作で半日程度潰したが、今ではこっちも同じように安定して使えている。

ソフトウェア

ADXL345のライブラリはいろいろな言語で実装されているが、一番使いやすく理解しやすかったのが以下のpythonのものだった。

github.com

きれいで読みやすく、改造もしやすいサンプルコードが同梱されている。さすがadafruit。

BBGWにインストールするには、githubのmdに書いてある通り

sudo apt-get install git build-essential python-dev
cd ~
git clone https://github.com/adafruit/Adafruit_Python_ADXL345.git
cd Adafruit_Python_ADXL345
sudo python setup.py install

でOK。pipでもインストールできるが、サンプルコードがインストールされないので色々わかった人用。読みやすいコメントが入ったサンプルコードこそがADXL345初心者には何よりも貴重である。

サンプルを動かす

Adafruit_Python_ADXL345/examplesにあるsimpletest.pyがサンプルコードで、0.5秒おきに三軸加速度の値がコンソールに出力されるものである。

これをそのまま動作させると残念ながら

IOError: [Errno 2] No such file or directory: '/dev/i2c-1'

と出て動かないが、修正は極めて簡単で、simpletest.pyの

# Create an ADXL345 instance.
accel = Adafruit_ADXL345.ADXL345()

の部分を

accel = Adafruit_ADXL345.ADXL345(busnum=2)

に変えるだけである。この修正方法もサンプルコードの中にヒントとしてコメントされているので誰でも割とすぐ気づくだろう。引数なしでADXL345のインスタンスを作るとbusnum=1になってBBGWのGrove I2Cのバスとは違う所を読みに行ってしまうのが最初のエラーの原因である。なお、サンプルコードのヒントでは address=0x54 とI2Cアドレスの指定方法も書かれているが、Grove ADXL345モジュールのI2Cアドレスは0x53で固定なので、I2Cアドレスを明示的に指定したい場合は引数に(デフォルト値である)address=0x53を書く。

これでセンサの読み取りを実行できる。

$ python simpletest.py
Printing X, Y, Z axis values, press Ctrl-C to quit...
X=0, Y=0, Z=0
X=0, Y=9, Z=285
X=0, Y=8, Z=285
X=1, Y=8, Z=286
X=0, Y=10, Z=287
X=-1, Y=9, Z=286
X=1, Y=8, Z=285
X=0, Y=9, Z=286
X=0, Y=8, Z=286
X=-1, Y=9, Z=286
X=0, Y=9, Z=284
^CTraceback (most recent call last):
File "simpletest.py", line 52, in <module>
time.sleep(0.5)
KeyboardInterrupt

0.5秒ごとに加速度の値がコンソールに表示される。Z方向に重力がかかるように置いたのでXとYは小さい値である。Zの値が不思議であるが、これはADXL345のスペックシートを読むとわかる。引用すると:

最大分解能での出力の各 LSB は、3.9 mg すなわちオフセット・レジスタの LSB の 1/4 です。

mgはミリグラムではなくて、地球表面の重力加速度gの1/1000を意味している。

ライブラリはこれを忠実に守っているので、コンソールへの出力数値1が 3.9mg、つまり地球の重力加速度の 3.9 / 1000 倍を意味している。上のZ出力値の最頻値 Z = 286 に当てはめると

Z = 3.9*286 mg = 1115.4 mg = 1.1154 g

と約1gになり、ここが地球の表面であることを再確認できた。さすがにぴったり1にはならないので、キャリブレーションは自分でやれってことなのだろう。

連続で読み取ってみる

サンプルコードでは無限ループの中で

time.sleep(0.5)

があり、時間的にだいぶ緩やかな読み取りを行っているが、無慈悲にもこれをコメントアウトしてみると、すさまじい勢いで加速度の値がコンソールに出力される。サンプリング周波数がそこそこ大きそうだと期待できる。

生データとFFT解析結果をファイル出力

simpletest.pyにごく僅かに手を加えて、生データとFFT解析結果をcsvファイルとして出力するようにしてみた。データ解析ライブラリpandasが便利すぎて感動した。

gistc6b0aab240190a6e0635b4bd8e2e6d8b

これを実行すると、

Number of samples: 1024
measurement takes 1.351067 sec
FFT takes: 0.02015 sec
Sampling frequency: 757.919481417 Hz

のようにサンプリング周波数がコンソールに出力され、生データとFFT解析結果がそれぞれrawoutput.csv、fftoutput.csvファイルとして出力される。1024サンプルの取得に1.35秒しかかかっておらず、サンプリング周波数は約750Hzである。測定のたびに若干変動するが、この速さなら色々な振動を解析するのに十分な時間分解能だろう。

なお、ファイル中のtimeは、測定開始時刻と測定終了時刻とサンプル数から計算した値であり、正確なサンプリング時間を意味しているものではない。サンプル一回ごとにシステム時刻を取得するのは無駄だと思うのでこうしている。

サンプリング周波数を向上させる

BBGWはデフォルトのI2C通信速度が100kHzだが、最高で400kHzまで上げることができる。基本的なやり方は

Change i2c bus frequency on Beaglebone Black | randymxj的茶馆er

の通りだが、BBGWでは編集するdtbファイルのパスが若干変わっており、

/boot/dtbs/4.4.9-ti-r25/am335x-bonegreen-wireless.dtb

である。I2Cの通信速度を400kHzにしてからadxl345_fft.pyを実行すると

 Number of samples: 1024
measurement takes 0.594841 sec
FFT takes: 0.016457 sec
Sampling frequency: 1721.46842602 Hz

と、2倍強にサンプリング周波数が向上した。すごい。adxl345のサンプリング周波数の限界が3200Hzなので、測定性能の良いレンジを使い切れていると思う。サンプリング定理の制限により、サンプリング周波数の半分の850Hz程度までの振動を解析できる。

測定例

出力csvファイルを(pandasでちょっとした加工の後に)pythonのmatplotlibで図示してみた結果を以下に列記する。FFTの解析結果は値が複素数なので、絶対値と位相をそれぞれ示す。

静止状態

生データ

f:id:XX-Prime:20161207150048p:plain

z軸に地球の重力加速度がかかるように置いた。振幅が100mg程度のノイズが見られる。

FFT 絶対値

f:id:XX-Prime:20161207150328p:plain

これもノイズ成分のみが見られる。後に示す振動状態の結果と比較しやすいようにy軸のスケールを調整してある。中央を境界に左右対称の形になるのは実数値をFFT解析したときに共通の結果であり、サンプリング定理で最高測定周波数の半分までしか意味のある解析ができないことも納得できる。

なお、データ上は周波数ゼロの直流成分に極めて大きなパワーが記録されているが、地球の重力によるものなので図では示していない。平均値からのズレをFFT解析すれば直流成分は消えるはずである。

FFT 位相

f:id:XX-Prime:20161207150913p:plain

位相には特に規則性もなく、ほぼホワイトノイズと見なせる。

電動歯ブラシに押し当てた状態

生データ

f:id:XX-Prime:20161207151434p:plain

x方向とz方向に、振幅1500mg程度の激しい振動が見られる。ヴィ〜〜ン。y軸方向の振動が小さいのは、おそらく電動歯ブラシのモーターの回転軸の方向がy軸に一致していたためだろう。電動歯ブラシの振動は、モーターの回転軸とずれた位置に重心をもつ重りを回転させて作り出している(と思われる)ので、y軸方向の振動は作れない。y軸方向にも振動するように、y軸と直交する方向に軸を向けたモーターを追加するなりすれば全軸が振動して歯垢除去能力が向上するかもしれない。柄が太くなるから無理か。

FFT絶対値

f:id:XX-Prime:20161207151918p:plain

約131Hzのところに鋭いピークがあり、電動歯ブラシの振動(モーターの回転)をうまく捉えることに成功している。これを60倍した値がよく聞く回転数で、7860rpmとなる。近所の薬局で購入した安物の電動歯ブラシなのでこの程度だが、高価な奴で試せばピークの場所や数が変わると推測される。なお、ここでも直流成分の大きなパワーは除外している。

FFT位相

f:id:XX-Prime:20161207152406p:plain

位相に特に規則性はない。

まとめ

Beaglebone Green Wireles と ADXL345 の組み合わせで、比較的安価に振動解析システム(の基本要素)を構成できることを実証した。BBGWのI2C通信のスピードアップを施すことで850Hz程度までの振動を解析可能なので、応用範囲は広そうである。

総額で1万円もかからない安価な測定システムとしては良い結果だと言えるだろう。BBGWにはまだ適切なエンクロージャがないが、タカチのケース加工サービスを利用すれば、発注量にもよるが一つで1000円を切ることも可能であろう。Edisonのエンクロージャを作ってみたときは8個で1万円いかなかった。

温湿度などの単純なデータとは違い、振動データはあっという間にデータ量が莫大になってしまうので、そのままクラウドに送るなどするのは考えにくく、いわゆるエッジコンピューティングで特徴量を計算する必要がある。BBGWの計算能力は振動解析には十分で、1024*3サンプルのFFT解析に0.01秒程度しか要さない。連続的に測定と解析を行って振動を監視することができる。FFT以外にも様々な時系列解析手法があり、BBGW上でそのまま動作するものも多いだろう。

やり残していること

C++のライブラリを使ってサンプリング周波数がどの程度まで向上するか若干興味はあるが、C++でコードを書いていると、そのあまりの非人道的な言語仕様に怒りが込み上げてくるので今はやっていない。クロスコンパイル環境を作ってMac上のEclipseからBBGWで実行ファイルを動かすくらいまではやったが、続きはC++大好きっ子のド変態に代わりにやって頂きたい。

また、BeableboneにはCPUとは独立して動作するPRUというプロセッサがあり、これを使うとOSのタスクスイッチの影響を受けずにリアルタイム処理に近いことができるようである。I2C通信をPRUで行えば、より安定したサンプリングが可能になり、解析結果も正確になるだろう。が、PRUの使い方がよくわからんのでこれも今はやっていない。

Beaglebone Green の Wi-Fi 設定 (Debian Jessie on SD card)

SDカード運用

BeagleBoard.org - latest-images

から Jessie for BeagleBone via microSD card をダウンロードしてddなりWin32DiskImagerなりでマイクロSDカードに書き込んで、BBGに刺してブートするとSDカードのJessieで起動できる。ここまではOK。

オンボードのeMMCはなるべく使いたくない。SDカードなら読み書きできなくなるまで使い果たしたら交換すればいいけど、eMMCはそうはいかない。けどeMMCをそこまで追い込んだことは今まで一度も無い。誰かやったことあるんだろうか?

Wi-Fi設定でハマる

BBGにWLI-UC-GNM2を刺すと自動認識してwlan0インターフェースが生成される。あいかわらず凄まじい発熱だ。ところで、熱は状態量ではない。熱はエネルギー移動の一形態で、温度で割ればエントロピーという状態量になる。エントロピーに関して、温度は積分分母である。熱力学第二法則によれば(以下五千文字省略)。

Jessie用のWi-Fi設定はconnmanでやれ、と/etc/network/interfacesに書いてある。

# WiFi use: -> connmanctl

よって、そのへんを調べながら以下のようにやってみた。

root@bbg0001:~# connmanctl
Error getting VPN connections: The name net.connman.vpn was not provided by any

VPNがどうのこうの言ってるがどうでもいい。 

問題は次。

connmanctl> scan wifi

を実行しても、何も起こらずに一瞬でコマンド入力待ちになる。本来なら少し時間がかかってAccess Pointsを探すはずなのに。案の定、

connmanctl> services

 

 と、何も表示されない。確か一ヶ月前くらいにここで諦めてwpa_supplicant.confを人力で編集するという鬼畜の所業に手を染めた。

再挑戦

さっきまた同じようにscanが失敗して鬼畜の道に身を落としかけていた所、以下が見つかった。

Re: [beagleboard] How to configure wpa_supplicant.conf to get wifi work?

8月10日のメールアーカイブで、3日前のものである。

答えは、scanの前に

#connmanctl> tether wifi disable
Disabled tethering for wifi

を行うというものだった。こんなもん自力で気づかん。これをやると

connmanctl> scan wifi
Scan completed for wifi

となって、アクセスポイントのscanに成功して、以下のようになる。

connmanctl> services
wireless-hell-bg wifi_XXXXXXXXXXXX_YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY_managed_psk

私のAPの素敵なSSID名がちゃんと表示された。SSIDを隠す意味は何も無いので晒す。

接続しようと

connmanctl> agent on
Agent registered
connmanctl> connect wireless-hell-bg
Error 'connect': Invalid argument

で失敗。connectの引数はSSID名ではなく、servicesで表示された右側の長い識別名であった。こっちの安全性は不明なので隠す。

connmanctl> connect wifi_XXXXXXXXXXXX_YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY_managed_psk
Agent RequestInput wifi_XXXXXXXXXXXX_YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY_managed_psk
Passphrase = [ Type=psk, Requirement=mandatory, Alternates=[ WPS ] ]
WPS = [ Type=wpspin, Requirement=alternate ]
Passphrase? XXXXXXXXXXXXX

入力したパスフレーズが思いっきり画面上に表示される鬼畜仕様なので、周囲に人が居ないのを確かめてからやりましょう。これでAPに接続完了。

まとめ

テザリングがデフォルトでONというのはなかなか鬼畜だ。