BBC micro:bit

BBC micro:bit に関する記事です...とはいえここは Arduino コーナー。普通に micro:bit を使う方法は他サイトに任せ、ここでは Arduino 化に特化した話をしたいと思います。



BBC micro:bit

BBC micro:bit は 英国 BBC が自国の 11歳と12歳の小学生 (日本で言う中学生) 全員に無料配布する低消費電力、低コストのシングルボードコンピュータです。

MCU は Nordic nRF51822 です。ざっくり言えば ATMega2560 くらいの性能ですが、BLE (Bluetooth Low Energy) が使えます。micro:bit はもちろん技適を通っています。

See Also:


購入

スイッチサイエンス他で買えます。色はランダムです。

I/O をすべて引き出すには別途エッジコネクタ変換基板が必要です。

なお、Kitronik のボードは 19 / 20 ピン (I2C) にもピンヘッダを立てたほうがいいように思います。

See Also:


各部詳細

micro:bit の各部詳細

0 / 1 / 2 / 3V / GND のピン (リング) はワニ口クリップで挟むか、バナナプラグ (4mm) を挿して使います。ワニ口クリップは斜めになって短絡しそうでちょっと怖いですね。それと実際にワニ口クリップで挟んでみましたが、端子に傷が付くのでエッジコネクタ変換基板を使った方がいいですね。

ピン 0 / 1 / 2 はタッチセンサー (静電容量センサー) として使えます。公式サイトによると...

片方の手でGND端子を持ったときに、他の手で0、1、2のいずれかの端子に触れたかどうかを検知する、
まるで3つのボタンが追加されたかのようにBBC micro:bitをプログラムすることができます。
これはあなたのカラダで電子回路を完結しているのです。

簡易的には analogRead() で値の変化を調べればよさそうですが、どう考えても隣のピンまで触ってしまうので積極的に使いたくはないです。

See Also:

エッジコネクタ変換基板 (Kitronik) の各部詳細

これを取り付けるとコンパクトさは失われます。SparkFun の変換基板の方がいいかも。

やっぱり我慢できずにピンソケットに付け替えたよね (w

そしたらピンヘッダ未実装版が販売開始になったよね (w

See Also:


セットアップ

Arduino IDE 用の Nordic nRF5 ボードライブラリが存在し、nRF51822 を搭載している micro:bit も Arduino IDE で動作します。以下にボードの追加方法を示します。

  1. [ファイル | 環境設定] で "追加のボードマネージャの URL" に以下の URL を追加。
    https://sandeepmistry.github.io/arduino-nRF5/package_nRF5_boards_index.json
  2. [ツール | ボード | ボードマネーシャ]
  3. Nordic Semiconductor nRF5 based boards を探してインストール
  4. [ツール | ボード:] で "BBC micro:bit" を選ぶ。
  5. [ツール | シリアルポート:] で "COMxx (BBC micro:bit)" になっているものを選ぶ。

See Also:


ボタン

A / B ボタン用の定数は以下のように定義されています。

ボタン 定数 ピン
A PIN_BUTTON_A 5
B PIN_BUTTON_B 11

以下のようなスケッチでテストできます。

void setup() {
  Serial.begin(115200);
  while (!Serial);
  pinMode(PIN_BUTTON_A, INPUT_PULLUP);
  pinMode(PIN_BUTTON_B, INPUT_PULLUP);
}

void loop() {
  if (digitalRead(PIN_BUTTON_A) == LOW) {
    Serial.println("A Button!");
    delay(200);
  }
  if (digitalRead(PIN_BUTTON_B) == LOW) {
    Serial.println("B Button!");
    delay(200);
  }
}

シリアルモニタを開いた状態でボタンを押してみてください。



LED スクリーン

micro:bit の LED スクリーンの実体は 9x3 の LED マトリクスです。nRF5 ボードライブラリは汎用ライブラリなため、micro:bit の LED スクリーンを簡単に扱うためのクラスは用意されていません。LED スクリーンに何かを表示するためには自前で LED マトリクスを制御する必要があります。

LED マトリクス用ピン

桁 (COL) に使われているピンは以下の通りです。

COL1 COL2 COL3 COL4 COL5 COL6 COL7 COL8 COL9
ピン 3 4 10 23 24 25 9 7 6

行 (ROW) に使われているピンは以下の通りです。

ピン
ROW1 26
ROW2 27
ROW3 28

こういうマトリクスです (座標は 5x5 マトリクスでの位置)。

COL1 COL2 COL3 COL4 COL5 COL6 COL7 COL8 COL9
ROW1 (0,0) (2,0) (4,0) (4,3) (3,3) (2,3) (1,3) (0,3) (1,2)
ROW2 (4,2) (0,2) (2,2) (1,0) (3,0) (3,4) (1,4)
ROW3 (2,4) (4,4) (0,4) (0,1) (1,1) (2,1) (3,1) (4,1) (3,2)

微妙に規則性がないのでイラっとしますね。素直に 5x5 にしなかった理由が知りたいです。

サンプルスケッチ

見た目通りの 5x5 でないため、座標変換も必要です。以下のスケッチを実行すると、左から右、上から下へとドットが移動します。

const uint8_t max_cols = 9;
const uint8_t max_rows = 3;
const uint8_t cols[max_cols] = {3410232425976};
const uint8_t rows[max_rows] = {262728};

typedef struct TPoint {
  uint8_t x;
  uint8_t y;
} POINT;

const POINT ledpos[5][5] =
{
  {{00}, {31}, {10}, {41}, {20}},
  {{32}, {42}, {52}, {62}, {72}},
  {{11}, {80}, {21}, {82}, {01}},
  {{70}, {60}, {50}, {40}, {30}},
  {{22}, {61}, {02}, {51}, {12}}
};

void led_init() {
  for (int i = 0; i < max_cols; i++) {
    pinMode(cols[i], OUTPUT);
    digitalWrite(cols[i], HIGH);
  }
  for (int i = 0; i < max_rows; i++) {
    pinMode(rows[i], OUTPUT);
    digitalWrite(rows[i], LOW);
  }
}

void led_pset(const uint8_t x, const uint8_t y, const uint8_t mode) {
  POINT position = ledpos[y][x];
  digitalWrite(cols[position.x], !mode);
  digitalWrite(rows[position.y], mode);
}

void setup() {
  led_init();
}

void loop() {
  for (int y = 0; y < 5; y++) {
    for (int x = 0; x < 5; x++) {
      led_pset(x, y, HIGH);
      delay(200);
      led_pset(x, y, LOW);
    }
  }
}

ライブラリ

誰かが作っているような気がしないでもないのですが、micro:bit 用の LED スクリーンライブラリを作りました。

こんな感じで簡単に Hello, world. できます。

#include "microbit_Screen.h"

void setup() {
  SCREEN.begin();
}

void loop() {
  SCREEN.showString("HELLO,WORLD.");  
  SCREEN.showString("micro:bit!");  
}

フォントは JavaScript Blocks Editor と同じになっている...ハズです。

実装されているメソッドは以下の通りです。詳しい使い方はサンプルを参照してください。

メソッド 説明 ブロックエディタで同等のメソッド
void begin(); 初期化。setup() に一度だけ記述する。
uint8_t brightness(); LED スクリーンの現在の明るさを 0~255 で返す。 https://makecode.microbit.org/reference/led/brightness
void clearScreen(); LED スクリーンを消去する。 https://makecode.microbit.org/reference/basic/clear-screen
void enable(bool on); LED スクリーンの有効/無効。 https://makecode.microbit.org/reference/led/enable
uint8_t lightLevel(); 明るさセンサー。LED スクリーンを照らす光の強さを 0~255 で返す。https://makecode.microbit.org/reference/input/light-level
void plot(const uint8_t x, const uint8_t y); ドットを点灯させる (x, y)。 https://makecode.microbit.org/reference/led/plot
void plotBarGraph(const uint32_t value, const uint32_t high); 棒グラフを表示する。 https://makecode.microbit.org/reference/led/plot-bar-graph
void plotBrightness(const uint8_t x, const uint8_t y, const uint8_t brightness);明るさを (0~255) 指定してドットを点灯させる (x, y)。 https://makecode.microbit.org/reference/led/plot-brightness
bool point(const uint8_t x, const uint8_t y); ドットの点灯/消灯状態を調べる (x, y)。 https://makecode.microbit.org/reference/led/point
void setBrightness(const uint8_t value); LED スクリーンの明るさを 0~255 で設定する。 https://makecode.microbit.org/reference/led/set-brightness
void showAnimation(const String str, const uint32_t interval); 任意の図形をアニメーションさせる。interval はアニメーション間隔 (省略可能)。 https://makecode.microbit.org/reference/basic/show-animation
void showArrow(const ArrowNames direction, const uint32_t interval); 8 方向の矢印を表示する。interval は表示時間 (省略可能)。 https://makecode.microbit.org/reference/basic/show-arrow
void showIcon(const IconNames icon, const uint32_t interval); アイコンを表示する。interval は表示時間 (省略可能)。 https://makecode.microbit.org/reference/basic/show-icon
void showLeds(const String str, const uint32_t interval); 任意の図形を表示する。interval は表示時間 (省略可能)。 https://makecode.microbit.org/reference/basic/show-leds
void showNumber(const int32_t value, const uint32_t interval); 数値を表示する。2 文字以上はスクロールして表示する。interval はスクロール時間 (省略可能)。 https://makecode.microbit.org/reference/basic/show-number
void showString(const String text, const uint32_t interval); 文字列を表示する。2 文字以上はスクロールして表示する。interval はスクロール時間 (省略可能)。 https://makecode.microbit.org/reference/basic/show-string
void stopAnimation(); showString() や ShowAnimation() のアニメーションを停止する。 https://makecode.microbit.org/reference/led/stop-animation
void toggle(const uint8_t x, const uint8_t y); ドットの点灯/消灯を反転する (x, y)。 https://makecode.microbit.org/reference/led/toggle
void unplot(const uint8_t x, const uint8_t y); ドットを消灯する (x, y)。 https://makecode.microbit.org/reference/led/unplot

See Also:



ADC

analogRead() に使えるピンは以下の通りです。デフォルトで 10 bit (0~1023) の ADC です。

定数1 定数2 ピン
A0 PIN_A0 0
A1 PIN_A1 1
A2 PIN_A2 2
A3 PIN_A3 3
A4 PIN_A4 4
A5 PIN_A5 10

DAC に使えるピンはありません。



SPI

SPI に使えるピンはデフォルトで以下の通りです。

定数1 定数2 ピン
SCK PIN_SPI_SCK 13
MISOPIN_SPI_MISO14
MOSIPIN_SPI_MOSI15
SS 16

See Also:



I2C

I2C に使えるピンはデフォルトで以下の通りです。

定数1 定数2 ピン
SDAPIN_WIRE_SDA20
SCLPIN_WIRE_SCL19

磁気センサー (MAG3110)加速度センサー (MMA8653) が I2C バスにぶらさがっているため、I2C Scanner を走らせると、以下のスレーブアドレスが検出されます。

Address センサー 割り込み1 割り込み2
0x0E磁気センサー (MAG3110) MAG INT1 (31)
0x1D加速度センサー (MMA8653)ACCEL INT 1 (29)ACCEL INT 2 (30)

See Also:



BLE (Bluetooth Low Energy)

micro:bit (nRF51822) で BLE を使うには SoftDevices と呼ばれるプロトコルスタックのプレコンパイルバイナリを導入する必要があります。これは追加のファームウェアのようなもので、幾つかの種類があります。

当然ですが、導入するとフラッシュメモリを消費します。

SoftDevice の導入手順

以下の手順で SoftDevice を導入します。

  1. スケッチブックの保存場所へ移動する ([ファイル | 環境設定] で調べられる)。
  2. ここに tools\nRF5FlashSoftDevice\tool\ というフォルダを作る (三階層作る)
  3. nRF5FlashSoftDevice.jar をダウンロードし、<スケッチブックの保存場所>\tools\nRF5FlashSoftDevice\tool\ にコピーする。
  4. Arduino IDE を再起動する。
  5. [ツール | SoftDevice] で SoftDevice を選択する (とりあえずなら S130 にしておくといい)。
  6. [ツール | 書き込み装置] で CMSIS-DAP を選択する。
  7. [ツール | nRF5 Flash SoftDevice] を選択する。
  8. ライセンス契約をよく読んで [Accept] ボタンを押す。
  9. 選択した SoftDevice が USB 経由で書き込まれる。

Done flashing SoftDevice のメッセージが出れば SoftDevice 導入成功です。

BLE ライブラリの導入

BLE を使うには別途 BLE ライブラリの導入が必要となります。

ライブラリを導入できたら [ファイル | スケッチ例 | BLEPeripheral] に豊富なサンプルがあるので試してみてください。BLE HID キーボードBLE HID マウスが簡単に作れますよ!

なお、転送時に "スケッチの書き込み中にエラーが発生しました" とエラーが出ますが、バイナリはちゃんと転送されているようです。

心配なら、micro:bit のリセットボタンを押してリセットしてください。

See Also:


磁気センサー (MAG3110)

micro:bit には磁気センサーが搭載されています。

ライブラリ

ライブラリはライブラリマネージャで "MAG3110" を検索すると出てきます。

サンプルスケッチ

最小限のサンプルスケッチは以下のようになります。

#include <SparkFun_MAG3110.h>

MAG3110 mag = MAG3110();

void setup() {
  Serial.begin(115200);
  mag.initialize();
  mag.start();
}

void loop() {
  int x, y, z;
  if(mag.dataReady()) {
    mag.readMag(&x, &y, &z);
    Serial.print(x); Serial.print(", ");
    Serial.print(y); Serial.print(", ");
    Serial.println(z);
  }
}

スケッチを実行して micro:bit を色々な方向に向けると X / Y / Z を示す値がシリアルモニタに表示されます...が、このライブラリは正しく動作していない気がします。

See Also:


加速度センサー (MMA8653)

micro:bit には加速度センサーが搭載されています。

ライブラリ

ライブラリは以下から DL できます。

サンプルスケッチ

最小限のサンプルスケッチは以下のようになります。

#include "Wire.h"
#include "MMA8653.h"

MMA8653 accel;

void setup() {
  Serial.begin(115200);
  Serial.println("microbit accel test");
  accel.begin(false2); // 8-bit mode, 2g range
}

void loop() {
  accel.update();
  Serial.print((float)accel.getX() * 0.0156); Serial.print(", ");
  Serial.print((float)accel.getY() * 0.0156); Serial.print(", ");
  Serial.println((float)accel.getZ() * 0.0156);
  delay(100);
}

スケッチを実行して micro:bit を振ると加速度がシリアルモニタに表示されます。

サンプルスケッチ2

電子サイコロのスケッチです。micro:bit を振ると 1~6 の数字が表示されます。

#include "microbit_Screen.h"
#include "Wire.h"
#include "MMA8653.h"
#include <math.h>

MMA8653 accel;
int num = 0;

const float sens = 100.0// 感度: 低すぎると傾けただけで反応してしまう

void setup() {
  accel.begin(false2); // 8-bit mode, 2g range
  SCREEN.begin();
  randomSeed(analogRead(A0));
}

void loop() {
  accel.update();
  float Rho = sqrt(pow(accel.getX(), 2.0) + pow(accel.getY(), 2.0) + pow(accel.getZ(), 2.0));
  if (Rho > sens)
    num = random(16);
  if (num == 0) 
    SCREEN.showIcon(IconNames::Happy);
  else  
    SCREEN.showNumber(num);
}

同じ数字が連続したのかちゃんと振られていないのかを判断しにくいので、初期状態ではニコニコマークが表示されています。一回振る毎にリセットボタンを押すといいでしょう。

See Also:


Tips

最初に入ってたデモをもう一度見たい!

以下から デモ hex を DL し、MICROBIT ドライブへドラッグ&ドロップしてください。

※ 判りにくいですが、一番下に DL アイコンがあります。

See Also:

正しい COM ポートを選んでいるのに "ポートが存在しない" と言われてスケッチコンパイル後にアップロードできない!

任意の hex を MICROBIT ドライブへドラッグ&ドロップしてください。上記の初期デモでも構いませんし、何もしない hex を作って転送してもいいです。

See Also:

簡易温度計

SoftDevices と BLE ライブラリ を導入すると、nrF51 のダイ温度を調べる事ができます。

#include "microbit_Screen.h"
#include "nrf_soc.h"
#include <SPI.h>
#include <BLEPeripheral.h>

BLEPeripheral blePeripheral = BLEPeripheral();

void setup() {
  SCREEN.begin();
  blePeripheral.begin();
}

void loop() {
  int32_t temp = getTtemperature();
  SCREEN.showNumber(temp);
  delay(100);
}

int32_t getTtemperature(void)
{
  int32_t temp;
  if (sd_temp_get(&temp))
    return -999;
  return (temp / 4);
}

sd_temp_get() の戻り値はセルシウス度 (℃) の 4 倍です。ダイ温度なので高めの温度が出ます。

See Also:


ここにある情報が役に立って、「調べる手間が省けたからオマイに飯でもおごってやるよ」 というハートウォーミングな方がいらっしゃいましたら、下のボタンからどうぞ。

メニュー: