MicroPython的午睡(5) LSM303AGRへアクセス、micro:bit

Joseph Halfmoon

マイコンボードによってはリビジョンにより搭載部品が異なる場合があります。このところMicroPythonしているBBC micro:bitも例外ではありません。v1系とv2では違いが大きいですが、v1系の中でもハッキリした違いがあります。加速度センサと電子コンパスの部分だと思います。お楽しみのデバイスの直接操作のためにちと調べてみました。

※「MicroPython的午睡」投稿順 Indexはこちら

さてBBC micro:bitのボードのバージョンについては micro:bitのDeveloper Community内の以下の情報が大変役に立ちます。

Hardware

URLを貼り付けさせていただいたのは、私の手元にあるv1.5のページです。上部に以下の切り替えスイッチがあります。

  • v2
  • v1.5
  • v1.3x

世に出回っている主要なバージョンは上の3つなのだと想像します。そして手元にあるのはv1.5(v2はいろいろ良くなっているので欲しいのですがまだ入手できておらず。)

さて搭載の加速度センサと電子コンパスについてみてみると以下のようになっていました。

加速度センサ 電子コンパス
v1.3x NXP MMA8653FC NXP MAG3110
v1.5 ST LSM303AGR 左に内蔵
v2 ST LSM303AGRまたはNXP FXOS8700 左に内蔵

デバイスの種類はいろいろですが全てI2C接続です。またI2Cバス上のアドレスなどは異なります。以降は手元で現物を調査できるv1.5を調べた結果です

なお、加速度センサあるいは電子コンパスとして通常利用する場合、micro:BitのMicroPythonは以下のクラスをサポートしているので、直接デバイスのレジスタにアクセスする必要はないです。

  • microbit.accelerometer
  • microbit.compass

以下はデバイスのデータシートをみながら直接制御したい場合用です。まずI2Cバスへの接続状況。Hardwareのページを見ればI2Cアドレスなどは書かれているので、そこに向けてプログラムすれば良いですが、MicroPythonにもI2Cバスのスキャン機能が含まれています。折角なので使ってみました。(使用したコードは末尾の I2C device scan のところに掲げました)実行すると以下の結果が返ります。

[25, 30]

解釈すると以下のようです。

  • 25=0x19 LSM303AGR accelerometer(加速度センサ)
  • 30=0x1E LSM303AGR magnetometer(電子コンパス)

アイキャッチ画像にmicro:bit上のLSM303AGR部分の拡大写真を掲げました。肉眼(老眼)ではマーキングすらよく見えないサイズの小さなデバイスです。I2Cバス上は機能別に2つのアドレスを占拠しています。なお、本来バスを使う前に初期化操作(init)が必要な筈ですが、「既に使える状態」になっているので不要と。

とりあえず無難なところでデバイスのレジスタに直接アクセスしてみます。LSM303AGRの内部のレジスタ番号は、加速度と磁気と併せて通番になっているみたいで、0x00から0x3F番地が加速度、0x40から0x6F番地が磁気に割り当てられていました(前述のようにI2Cアドレスは別になっている。)その中に、加速度と磁気と別々に WHO AM I というリードオンリのレジスタがあるのでこれを読んでみます。レジスタ幅は8ビット。それぞれのレジスタ番号は以下のとおりです。

  • accelerometer WHO_AM_I_A レジスタ番号 0x0F
  • magnetometer WHO_AM_I_M レジスタ番号 0x4F

デバイスのリビジョンが変わったりするとここに書かれている数字が変更されるのだと思います。手元にあるLSM303AGRについては、データシートからすると以下のような数値が読み取れる筈。

  • accelerometer WHO_AM_I_A … 0x33
  • magnetometer WHO_AM_I_M … 0x40

目出度くこの値が読み取れれば、正しくLSM303AGRのレジスタにアクセスできているということになります。

ラズパイ3 model B+のUSBポートに micro:bit V1.5 を接続し、Muエディタ使ってMicroPythonプログラムを書きこんで動かしてみたところがこちら。(使用したコードは末尾の LSM303AGR, Who am I? のところに掲げました。)

LSM303AGR Who Am I

なお、実行手順は以下のようです、念のため。

  1. 転送ボタンを押す(REPLが動いていないこと)
  2. micro:bit上のLEDがチカチカしてMicroPythonプログラム転送され、転送完了
  3. そのままだとprintした結果が見えないので REPL起動
  4. REPL起動すると転送済のプログラム実行が中断されてプロンプトが返る
  5. CTRL-Dを入力するとsoft rebootがかかり、REPLに接続したままプログラムが再実行される

想定通りのWHO AM Iコードが返ってきました。しかし、電子コンパス(磁気センサ)結構難物。建物の外へ出るとまあまあ思った方向を指すのだけれど、建物の中(特に私のいる部屋)に戻るとアッチ向いてホイ状態。トホホ。お陰でキャリブレーションだけは上手になったけれど。

MicroPython的午睡(4) micro:bitとWio Terminalの比較 へ戻る

MicroPython的午睡(6) micro:bit、ファイルシステムとメモリダンプ へ進む

i2c device scan
from microbit import *

devLis = i2c.scan()
print(devLis)
LSM303AGR, Who am I?
from microbit import *
from micropython import const

_LSM303AGR_A = const(0x19)
_LSM303AGR_M = const(0x1E)
WHOAMI_A_ADR = bytearray([0x0F])
WHOAMI_M_ADR = bytearray([0x4F])
rdata = 0

while True:
    i2c.write(_LSM303AGR_A, WHOAMI_A_ADR)
    rdata = i2c.read(_LSM303AGR_A, 1)
    print("ACC WHO AM I : 0x{0:02x}".format(rdata[0]))
    i2c.write(_LSM303AGR_M, WHOAMI_M_ADR)
    rdata = i2c.read(_LSM303AGR_M, 1)
    print("MAG WHO AM I : 0x{0:02x}".format(rdata[0]))
    sleep(2000)