Raspberry Pi Zero WHで気温センサBME280を動かすときの罠

前提

https://github.com/SWITCHSCIENCE/samplecodes/tree/master/BME280/Python27 を動かすときに。

最初に結論

  • 依存パッケージはsudoで入れよ
    sudo pip install -r requirements.txt
  • I2Cを有効化せよ
    sudo raspi-config
  • プログラムはsudoで実行せよ
    sudo python bme280_sample.py

以下は蛇足。どういう経緯で結論に至ったか。

ImportError: No module named smbus2

pip install -r requirements.txt

すれば済む話に見えるが、実は

sudo pip install -r requirements.txt

の方がいい。理由は後述。

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

pip install requirements.txt
python bme280_sample.py

するとこうなる。

理由はデフォルトでI2Cが無効化されているからで、解決策は Check! Raspberry Pi で I2C を使いたい(トラブルシューティング)にある通り

sudo raspi-config

だ。なお上記記事は2016年のもので、2020年現在(Raspberry Pi OS 5.4.79+)では若干違う。I2Cの設定は 3 Interface Options の中にある。

さて、I2Cを有効化して改めて

python bme280_sample.py

するとどうなるかというと、こうなる

OSError: [Errno 13] Permission denied: '/dev/i2c-1'

じゃあsudoにすりゃいいんだろと思って

sudo python bme280_sample.py

すると

ImportError: No module named smbus2

になる。

pythonのモジュールシステムにはあまり詳しくないが、sudoで起動するpythonは別の場所から依存パッケージを探してるのかな?というわけで

sudo pip install -r requirements.txt

すると動くようになった。

初心者の壁は環境構築/スケーティング巧者/酒蒸しと化したちゃお

12/16(月)

初心者の壁は環境構築

今日はプログラミングを人に教える機会があった。コードを解説するのは簡単なのだが、OSや言語のバージョンの問題を解決するのは(リモートだったこともあり)非常に難しかった。

今回のケースではPythonのIDLEがMacにプリインストールされている2.7を見てしまっていて、pipすら入っていなかった。一方で3系もanacondaでインストールされており、pip installで入れたつもりのパッケージはそちらに入っていた。

Pythonの環境構築は(ググって見つかる記事の質の低さ・不統一さを含めて)難易度が高い。プログラミングを教えるならそういうところを含めてサポートする必要がある。デバッグ実行の方法やlinterの設定などもそこで教えれば学習効率も上がりそうだ。

ちなみに僕は環境の切り替えが必要になったことがないのでpyenv+pipだけでやっている。

スケーティング巧者

既に書いたテーマかと思ったが、検索したらまだ書いてなくて驚いている。

僕はフィギュアスケートを見るのが好きだ。ユーリ!!! on ICEの影響だ。

フィギュアスケートのシングルではジャンプの配点が高い。度重なるルール改正で若干のトレンドは変動するものの、やはり高難度ジャンプを複数回成功させるのが強い。

しかしながら。スケートを演技としてみると滑りの上手さ、スケート靴の操り方の上手さが印象に大きく響く(もちろんこれらの技術も採点対象ではあるが、配点は小さい)。一蹴りで長く進むとか、加速が速いとか、滑りが美しい弧を描いているとか、上半身の動きが足元の影響を受けないとか。

パトリック・チャン

新採点時代の選手で言えば、スケーティングといえばパトリック・チャンだ。若い頃からスケーティングの技術は抜きん出ており、2011年シーズンから4回転を取り入れ、以降世界選手権を3連覇した。2014年ソチオリンピックでは羽生結弦に敗れ銀メダルとなった。2010年以前の発展期・2011~ソチの絶頂期・ソチ以降の円熟期でそれぞれ素晴らしい演技を残している選手だが、ここでは円熟期の演技として2017年世界選手権SPを紹介する。

ステップシークエンスから再生されるようになっている。01:36辺りのチェンジエッジ→ロッカー→カウンター(自信なし)は非常にエッジが深い。エッジが深いというのは傾きが大きいということであり、高く評価される。01:48辺りも複雑なステップを踏んでいるのに、軌跡と体重移動によって減速どころか加速している(ファンの間では靴にエンジンなどと言われる)。全体を通して上半身も脱力してしなやかに動いている。スケート靴の接地が柔らかく、流れを損なわない。難易度の高い足技を、明確なエッジで、かつ簡単そうに滑っている。このステップシークエンスはレベル4+GOE2.1、つまり当時のルールで理論上最高の評価を得ている。

山本草太

パトリック・チャンは引退してしまったが、山本草太はこれからの選手だ。滑らかで伸びるスケーティングに加えて姿勢が美しく、気品がある。手足も長い。今シーズンは怪我から復帰し、4回転サルコウや4回転トウループを成功させている。

ハン・ヤン

彼も怪我から復帰してきた。滑りがずっと速い。圧倒的な幅と高さの3回転アクセルと、深いアウトエッジに乗ったお手本のような3回転ルッツも魅力的だ。

彼らのような美しい滑りを持つ選手が勝てるルールであってほしいのだが、スポーツとしては難しいジャンプが跳べるかどうかで判断するほうが健全だろうし難しい。

酒蒸しと化したちゃお

土日はハッカソンで休まらなかったので今日は休暇を取っている。いつも通り銭湯に行った。今日の入浴剤は祝い酒の湯。確かに日本酒の匂いがした。アルコールは入っていたんだろうか。いや、そうすると子供の入場を制限しないといけないのか?

きのこの山/Scalaでアンパックもどき

きのこの山

きのこの山というお菓子を何かと比較する不遜な輩が多くいるようだ。

きのこの山はチョコレートとカリカリが分離している。万事において分離しているというのは大事なことだ。均質ではなく、高いエントロピーの中で異質なものが混じり合う中にこそグラデーションが生まれる。そしてグラデーションの中にこそ精妙な味わいが生まれてくる。

カレーをかき混ぜてはいけないし、丼料理をつゆだくにしてはいけないし、醤油にわさびを溶いてはいけない。それが俺の美意識。

Scalaでアンパックもどき

関数に複数の引数を渡すとき、コレクションをそのまま渡したいことがある。たとえばPythonであれば*を使ってアンパックできる。

Scalaでこれをやりたくで3分ググったところη-expansionを使った方法が見つかった。

(plus _)plusメソッドを関数に変換した後、さらにtupledメソッドによって1つのタプルを引数とする関数に変換している。

正確にはアンパックではないことに気づき、タイトルに「もどき」をつけた。

ラーメンを食べられなかった

※この記事は『金麦』を飲んで書かれた。

今日は仕事がしんどかったので帰りに不健康なラーメン(僕の中ではこの言葉は家系ラーメンを指す。なぜなら二郎系は野菜たっぷりで健康的だから)を食べて帰ろうと思った。同僚が「この辺にぃに美味いラーメン屋、あるらしいっすよ」と言っていたのでそこに行った。しかし残念なことに夜はライスが有料だった。

僕は家系ラーメンではライスは2杯〜3杯食べる。にんにく系の味と豆板醤系の味をそれぞれ楽しみたいからだ。

結局ラーメンは食べずに帰宅して焼きそばを食べた。最近は粉ソースではなくさらなる高級感を求めて液体ソースを使っているが、これも特段美味いということはない。そもそも相当な量を入れないと味がしない。そしてコストパフォーマンスが低い。

温度記録サーバはとりあえず公開できた。僕の自宅の気温・湿度・気圧を記録し続けるだけのサービスだ。

https://gyokuro.chao.tokyo/temperature

ちなみに過去ログには以下のような形式でアクセスできる

https://gyokuro.chao.tokyo/temperature/1994/05/17

サーバはScala + Play FrameworkをDockerでデプロイ、センサはRaspberry Pi + BME280でPythonのRequestsライブラリを使ってサーバにログを送信している。計測環境は鉄筋コンクリートでエアコンや換気扇で温度管理していて、Homo sapiensが1匹住んでブログを書いたりしている。

JavaScriptのbindとは何なのか

Reactのドキュメントで出てきた疑問だが、ReactというよりもむしろJSの知識だ。

同期に教わってみると意外とシンプルだった。bindは何かというよりも、むしろ本当の問題は「thisとはなにか」というところにある。thisは実行時のコンテクスト[note]スコープのようなもの?難しい[/note]であって、関数を呼ぶ方法によって変化する。

class MyClass {
  getX() {
    return this
  }
}

const myclass = new MyClass()

// クラスから呼び出すと、想定通りに動く
console.log(myclass.getX())
// MyClass{}

// 一度関数単体で取り出してしまうと、thisがなんだったか忘れてしまう
const unboundGetX = myclass.getX
console.log(unboundGetX())
// undefined

// bindを使うとthisを指定しながら関数を実行できる
const boundGetX = myclass.getX.bind(myclass)
console.log(boundGetX())
// MyClass{}

筆者はPythonを先に学んでいたのでJSの上記の仕様には違和感があった。しかしPythonのクラスのメソッドは常にselfを引数に取る(必ずselfが第一引数として渡される)一方でJSはそうではない。どちらも意図的なデザインなのだろう。

class MyClass:
    def getX(self):
        return self

myclass = MyClass()

# クラスから呼び出すと想定通り動く
print(myclass.getX())
# <__main__.MyClass object at 0x7f2a12223588>

# 関数単体で取り出しても想定通り動く
unboundGetX = myclass.getX
print(unboundGetX())
# <__main__.MyClass object at 0x7f2a12223588>

厳密な話を知りたい人はこの辺読んでください。アロー関数の話もしたいね。

Mastodon諦めました/Spotify諦めました

今日はコンピュータに嫌われた一日だった。悲しい。

Mastodon

再びマストドン立てようと思ったんだがメールが送れないのと他インスタンスとの通信ができないトラブルを解決できず諦めた。どちらも初めて出くわした。

前者は名前解決なんちゃらのエラー、後者はどうやらSSLと関係があるようだったが僕の知識では理解できなかった。そもそもMastodonは恐ろしく複雑だ。使いやすくする努力はされているが少しでも不具合が起きるとそれを解決するためにはとんでもない知識と労力が必要になる。

Spotify

Spotifyでローカルの音楽ファイルを再生したかったのだが、mp3にしか対応していなかった。そこで急遽音楽フォルダ内を全部掘ってmp3じゃないファイルをmp3に変えるスクリプトを書いた。

しかしそうして生成したファイルをSpotifyで再生しようとすると、再生ボタンを押した瞬間にSpotifyアプリが終了する。ターミナルからアプリを開いているとログが残るが、終了時に表示されるのはこれだ。

[0228/053947.271857:ERROR:input_method_base.cc(146)] Not implemented reached in virtual ui::InputMethodKeyboardController *ui::InputMethodBase::GetInputMethodKeyboardController()Using InputMethodKeyboardControllerStub
Segmentation fault (コアダンプ)

うーん。軽く調べてみるとChromiumのバグの疑いが強く、2018年11月辺りに報告が頻発している。しかしローカルの曲を再生するときだけこうなるのでSpotify側にも問題がありそうだ。

修論がいよいよ切羽詰まってきて昨日までは随分と焦っていたが、今日は起きてからずっと平穏な気持ちだ。修論の切迫感も友人との世間話もどこか遠くの世界のものに感じられた。奇妙だ。覚悟ができたとか諦めがついたとかそういう見方もできるだろうし、あまりにヤバすぎて脳が感情にストップをかけているという見方もある。今こうしてブログを書いている僕にしてみれば苦しみが和らいでいるという事実が大事で、理屈はどちらでもいい。

グラフをmatplotlibで作っている。ExcelやLibreOfficeなどのGUIソフトで作るのも直感的で悪くないが、様々な形式のデータに対してグラフのフォーマットを一定に保つという点ではmatplotlibが向いている。むしろGUIソフトはマウス捌き次第で違うものが出来上がってしまうという点で苦手だ。

さすがにもう実験はやらないので実験用にしていたディスプレイを防音室から出して作業用にした。このディスプレイはWQHDだが、普段使うノートPCの外部出力はFHDまでしか対応していないので以前は画面中央のFHD分だけ使われていた。今日久しぶりに接続したときにもそうなると思っていたら、なんとWQHDが全面使えた。不思議だ。調べてみるとノートPCの仕様書には外部出力はFHDまでと書いてあるが、iGPUのIntel HD Graphics 4000はWQHDに対応している。

むしろ酷いのはノートPCの内蔵液晶だ。1366x768では今どき大した作業はできない。2013年に使い始めた頃は不便に思ったことはなかったが、今では全く不十分だ。PC環境を整える上で最も優先すべきは人間と直接ふれあう部分、具体的にはマウス・キーボード・ディスプレイだと思う。ここのストレスは処理能力のストレスに比べて影響が大きいからだ。

ノートPCは大学入学時に入手したもので、スペックは以下のとおりだ。

  • Core i5-3210M
  • 16GB RAM(自分でフル増設した)
  • 128GB SSD(光学ドライブを抜いて増設した)
    • 幸いにも光学ドライブはSATA3接続だったのでSSDを刺してもボトルネックは生じない
  • 500GB HDD(最初に入っていたのが壊れたので取り替えた)

読んでわかるように相当の愛着がある。しかし前述のディスプレイの狭さに加えてバッテリーが経年劣化によりフル充電からでも30分程度しか保たない、重い(2.5kg)、デカい(リュックに入らない)などの欠点もある。来年には新しいノートPCを購入するだろう。メーカーに特にこだわりはないがThinkPadのキーボードは打ち心地が素晴らしいのでLenovoかなあ。

JavaScript+Hyperappで心理学実験プログラムを作った

これです(github)。

僕の学科では学生が実験に参加しつつその実験についてレポートを書くという授業が多く行われている。そこで行う実験は古典的なものが多いのだが、大昔に書かれた実験プログラムがメンテナンスされずに使われ続けているということがある。

今回書いた記憶実験のプログラムもそうで、誰がいつどうやって作ったかわからないexeファイルが受け継がれ使われ続けてきた。しかし内部の処理がわからないので細かい仕様がわからず、いろいろ試してみて推測することしかできない状態だった。さらにいつ動かなくなるかもわからない。

そこでこのプログラムを移植(ソースコードがないので移植と言うかは微妙だが)しようという話になった。当初はPythonが候補に上がっていたが、多数の学生に授業中に同時に行わせるにあたり、Pythonをexeに固めたものは容量が大きくなりすぎダウンロードが長引く懸念があった(経験的には数十MB)。そこでJavaScriptでの制作を提案した。サンプルを作って披露したところゴーサインが出たので制作した。

動作は単純で

  1. x桁のランダム数列を3秒間表示
  2. 数列を消し5秒間待つ
  3. 参加者が数列を思い出して回答する
  4. 正誤を3秒間表示
  5. 桁数を変更し、1に戻る

というものだ。5の桁数変更のアルゴリズムには上下法や恒常法などがある。

上下法は正解すれば次は1段階難しく、不正解なら次は1段階簡単にするというアルゴリズムだ。これによって参加者の正解できる限界の桁数に収束する。メリットは試行数が少なく済むこと。

恒常法は一定の範囲の桁数をランダムな順番で課し、桁数を横軸に、正解率を縦軸にプロットすることで正解率を桁数を結びつける関数を得る。そして正解率50%(任意の値)に相当する桁数をその人の限界とする。メリットは関数そのものが得られるため多様な分析が可能であること。

心理学の実験は基本的にはwebではやらない。それは参加者の環境が統一できないからだ。MATLAB+Psychtoolboxが主流で、Python+Psychopy(pygame)もある。しかしポータビリティは低い。GUIを使うプログラムはDockerで動かすのは不便で、できてもパフォーマンスに不安がある。

そこまで環境にこだわらない実験や、今回のように同じ部屋で多くのPCで実験を行うときにはポータビリティの高いwebプログラミングによる実験は便利だ。そもそもGUIを扱うノウハウやライブラリという点ではJavaScript、というよりブラウザという環境が優れている。

Life is Tech

とかいうTシャツを来た中高生くらいの集団が夕食時に食堂にたくさんいた。なんの集団だろうと調べてみたら中高生にプログラミングを教えるスクールらしい。

そういえば、ドワンゴのインターンが始まったのもちょうど1年ほど前だ。自己流のいい加減なコードとそれっぽい文章を提出したら全国の激ヤバ猛者が集まるインターンになぜか参加を許可され、何を学んだか列挙できないほど豊かな体験をした。結局それが布石となって就職も決まった。

別にプログラミングじゃなくていいが、まとまった時間を何かに注ぎこむこと、同世代の強者を知ること、プロの技を教わること、そういう活動が自分の世界を広げる。

最近は研究しかしてないので書くことがない。学会の参加登録が済んだので今日は本の返却等細々した作業を片付けつつ、これから何しようかなあと考えていた。もちろん実験を進めねばならないのだが、そのまえに分析法や実験手続きを確立しておきたい。なるべく自動化。ただでさえ参加者のリクルートや謝礼手続きで手間がかかるので、実験と分析くらいは自動化したいものだ。

PypeRなるライブラリを使うとPythonからRを呼び出せる。複雑な統計分析はRを使う必要があるが、PypeRがあればPandasとも連携できるので捗りそうだ。

うーん、書けそうで書けない。疲れているんだろうか。それとも人生のネタが切れたんだろうか。酒が足りないのか?