chibi:bitの050エラー問題を調べてみた(解決編)


2018年の9月に、こんな記事を書きました。

chibi:bitの050エラー問題を調べてみた
https://qiita.com/toyowata/items/19a434d59f4276b9e23c

内容は記事を読んでもらうとして、最後の部分で私はこんな事を書いています。

加速度センサなどのデバイスはchibi:bitでも同じものを使っていると思うので、なぜ実行時に挙動が異なるかは不明です。

・・・すみません、嘘でした。

調査不足のため、同じ部品を使っていると思い込んでいました。なお、chibi:bitの回路図は非公開ですが、micro:bitの回路図はこちらで公開されています。

調査方法

残念なことに、スイッチサイエンスが提供しているchibi:bit向けの開発サイト http://chibibit.io/ide/ は、最新版の主要なブラウザでは動作しない状態が続いています。これは、非HTTPSサイトでのAppCache使用の問題だと思われます。

本家Makecode for micro:bitのサイトで作成したプログラムは、簡単なものであればchibi:bitで動作します。しかし、加速度センサを利用するブロックを使うと、実行時に必ず050エラーが発生します。まずは、これを手がかりに調べてみます。

microbit-dal の加速度センサのコードの初期化部分を見てみます。まず、この部分でMMA8653の判定を行います。

この他にも幾つかのデバイスの判定(最新のハードウェアでは、加速度センサと電子コンパスが一つになっている部品を使っているため)を行い、どのデバイスも検出されない場合はunavailableとなり、デフォルトのMicroBitAccelerometerインスタンスが生成されます。

ここでは、MicroBitAccelerometer::requestUpdate()メソッド呼び出し時にmicrobit_panicが発生し、050エラーが起こるようになっています。

で、実際のMMA8653の判定処理はここで行われています。

WHOAMIレジスタの値が期待値と異なる場合は1以外が返され、MMA8653が接続されていないと判断されます。

そこで、実際にchibi:bitでどのような値が読み出せるのかを確認してみます。

まず、yottaでC++アプリをビルドできる環境を構築します。手順は前の記事を参照してください。用意したテストコードはこちら:


#include "MicroBit.h"
#include "MMA8653.h"

MicroBit uBit;

int main()
{
    uBit.init();

    int ret = uBit.i2c.readRegister(MMA8653_DEFAULT_ADDR, MMA8653_WHOAMI);
    uBit.serial.printf("MMA8653 WHOAMI value = 0x%0x\n", ret);

}

ビルドして作成されたHEXファイルをターゲットボードに書き込んで結果を比較してみました。

micro:bitの場合

MMA8653 WHOAMI value = 0x5a

chibi:bitの場合

MMA8653 WHOAMI value = 0x4a

なるほど。WHOAMIレジスタの値が異なっています。よく見ると部品のマーキングもよく見ると少し違います。


加速度センサーのメーカーNXPのデータシートを読むと、WHOAMIレジスタの値が記載されています。これにより、chibi:bitで使用されている加速度センサはMMA8653ではなく、MMA8652である事が分かりました。

chibi:bitのための変更方法

MMA8652とMMA8653は、ほぼ互換品っぽいので(違ったら教えてください)WHOAMIレジスタ値の判定処理をパスすれば、動作するはずです(実際、以前のバージョンでは問題なく動作していたので)。これは、上記のMMA8653::isDetected()メソッドを変更する事で実現できます。microbit-dalをforkして、以下のように変更してみました。

予想通り、問題なく動きました。加速度センサのサンプルを実行させた結果がこちらです。

なお、microbit-samplesのmodule.jsonは、以下のように変更しています。

"dependencies": {
    "microbit": "toyowata/pxtgc-0-chibibit"
},

これで、最新版のライブラリを使いつつ、C++サンプルコードをchibi:bitで動作させることが出来ました。

Makecode for microbitをローカルで動かす

さて、C++サンプルコードが動いてもそれほど嬉しくないので、Makecode for micro:bitの環境で動かすことを考えてみます。原因は、ランタイムライブラリのmicrobit-dalにある事は分かりましたが、「互換品に実装されている加速度センサーに対応させる」というプルリクエストを投げても通らないと思います。幸いなことにMakecodeは全てオープンソースとして公開されているので、ローカルの環境で動作させてみます。

ビルドの方法は、こちらに記載があります。
https://github.com/microsoft/pxt-microbit/blob/master/README.md

$ git clone https://github.com/microsoft/pxt-microbit
$ cd pxt-microbit
$ sudo npm install -g pxt
$ sudo npm install

pxtarget.jsonのcompileServiceの部分を以下のように変更します。

    "compileService": {
        "yottaTarget": "bbc-microbit-classic-gcc",
        "yottaCorePackage": "microbit",
        "githubCorePackage": "toyowata/microbit",
        "gittag": "pxtgc-0-chibibit",
        "serviceId": "microbit",
        "dockerImage": "pext/yotta:latest"
    },

ビルドして、サーバーを起動します。

$ pxt serve --localbuild

自動的にブラウザが開き、Makecodeが起動します。設定メニューから、「このアプリについて...」を選択すると、コンポーネントのバージョンが表示されます。

microbit runtimeのバージョンが、先ほどpxtraget.jsonで指定したものであることが確認できます。GitHubからcloneする時には特にタグなどはしてしなかったので、本家で公開されているものよりも新しいバージョンのコンポーネントが使われています。
加速度センサーのブロックを含んだコンポーネントでも問題なくchibi:bitで動作することも確認できました。

この環境を外部のWebサーバーにホスティングすれば、chibi:bitで動作するMakecodeを使用できる事が出来ると思います。

以上です。

参考にした情報

https://qiita.com/nemui_/items/ed753f6b2eb9960845f7
https://www.usagi1975.com/080220182039/