PlatformIOでmicro:bitを動かす

以前、
[MIDIから出力したノート＋時間のデータを使って、micro:bitで音を鳴らす](https://www.youtube.com/watch?v=sfZ4_eE2Gzk&feature=youtu.be)
という実験をやったのですが、少し長めのデータを使うとmicro:bitがメモリ不足におちいってしまうため、これまではシリアル経由でPCからデータを送っていました。

ですが、やはりmicro:bit単体で鳴らしたくなり、PlatformIOを使ってみることにしました。

PlatformIOはVisualStudioCodeのプラグインの形で提供されているIDEです。
![スクリーンショット 2020-01-17 21.30.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59911/c6a7e728-9e99-ffec-eb66-5bc738e1f841.png)

適当なプロジェクト名を付け、```Board: ```のところに```micro:bit```と入力すると出てきます。
![スクリーンショット 2020-01-17 21.32.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59911/abfecb63-633a-f4e5-5663-90c570f92d3f.png)

Finishボタンを押すとプロジェクトが作成されます。
FrameWorkはArduinoで開発したかったのですが、BoardがArduino以外だと音を出すTone()関数が使えないようでしたので、mbedで開発することにしました。
左ペインで```platformio.ini```を選択し、```framework = mbed```に書き換えて保存します。
![スクリーンショット 2020-01-17 22.01.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59911/f010897e-1cd3-9aa5-8bf0-fd4b887c660e.png)

次に左ペインのsrc>main.cppを選択し、プログラムを書き換えます

```main.cpp
#include <mbed.h>
  // LED(2,2)
  DigitalOut row(P0_14);
  DigitalOut col(P0_6, 0);

const int mididata[]={0, 768, 86, 235, 0, 5, 86, 475, 0, 5, 88, 235, 0, 5, 88, 235, 0, 5, 88, 235, 0, 5, 89, 475, 0, 5, 94, 715, 0, 245, 89, 235, 0, 5, 89, 235, 0, 5, 91, 475, 0, 5, 91, 715, 0, 5, 89, 1195, 0, 2165, 84, 235, 0, 5, 84, 235, 0, 5, 84, 235, 0, 5, 84, 235, 0, 5, 84, 235, 0, 5, 86, 235, 0, 5, 84, 475, 0, 5, 84, 235, 0, 5, 84, 235, 0, 5, 84, 235, 0, 5, 84, 235, 0, 5, 84, 235, 0, 5, 86, 475, 0, 5, 84, 715, 0, 5, 82, 115, 0, 5, 81, 115, 0, 5, 82, 2395, 0, 725, 79, 475, 0, 5, 79, 475, 0, 5, 79, 235, 0, 5, 79, 235, 0, 5, 79, 235, 0, 5, 79, 235, 0, 725, 82, 235, 0, 245, 82, 235, 0, 5, 84, 235, 0, 4085, 84, 235, 0, 5, 84, 235, 0, 5, 84, 235, 0, 5, 84, 235, 0, 5, 84, 235, 0, 5, 84, 235, 0, 5, 84, 235, 0, 965, 84, 475, 0, 5, 86, 475, 0, 5, 91, 715, 0, 5, 86, 1195, 0, 2165, 88, 235, 0, 5, 88, 235, 0, 5, 88, 235, 0, 5, 88, 235, 0, 5, 88, 235, 0, 5, 88, 235, 0, 5, 88, 235, 0, 965, 89, 475, 0, 5, 91, 475, 0, 5, 91, 475, 0, 245, 89, 1195, 0, 1925, 86, 475, 0, 5, 86, 235, 0, 245, 86, 235, 0, 485, 81, 235, 0, 965, 86, 475, 0, 5, 89, 475, 0, 5, 91, 715, 0, 5, 89, 115, 0, 5, 88, 115, 0, 5, 89, 2395, 0, 485, 84, 955, 0, 5, 86, 955, 0, 5, 88, 955, 0, 5, 84, 955, 0, 5, 81, 1915, 0, 1925, 86, 475, 0, 5, 86, 235, 0, 5, 86, 235, 0, 5, 86, 235, 0, 5, 86, 475, 0, 5, 81, 475, 0, 725, 86, 475, 0, 5, 89, 475, 0, 5, 91, 715, 0, 5, 86, 2155, 0, 965, 88, 955, 0, 5, 88, 955, 0, 5, 88, 475, 0, 485, 84, 235, 0, 5, 84, 235, 0, 5, 86, 235, 0, 245, 88, 115, 0, 5, 91, 115, 0, 5, 96, 115, 0, 5, 100, 115, 0, 5, 103, 115, 0, 5, 100, 115, 0, 5, 96, 115, 0, 5, 91, 115, 0, 5, 88, 115, 0, 5, 91, 115, 0, 5, 96, 115, 0, 5, 100, 115, 0, 5, 103, 115, 0, 5, 100, 115, 0, 5, 96, 115, 0, 5, 91, 115, 0, 245, 0, 20, 0, 20, 96, 75, 100, 20, 103, 20, 0, 85, 0, 20, 0, 20, 96, 75, 100, 20, 103, 20, 0, 85, 0, 20, 0, 20, 96, 75, 100, 20, 103, 20, 0, 85, 0, 20, 0, 20, 96, 75, 100, 20, 103, 20, 0, 85, 0, 20, 0, 20, 96, 75, 100, 20, 103, 20, 0, 85, 0, 20, 0, 20, 96, 75, 100, 20, 103, 20, 0, 85, 0, 20, 0, 20, 96, 75, 100, 20, 103, 20, 0, 85, 93, 235, 0, 5, 93, 475, 0, 5, 89, 475, 0, 5, 89, 235, 0, 5, 89, 475, 0, 5, 91, 235, 0, 5, 91, 235, 0, 5, 89, 475, 0, 5, 88, 235, 0, 5, 88, 235, 0, 5, 89, 235, 0, 5, 89, 235, 0, 5, 91, 235, 0, 5, 91, 235, 0, 5, 91, 475, 0, 5, 93, 475, 0, 5, 91, 1435, 0, 965, 93, 235, 0, 5, 93, 475, 0, 5, 89, 475, 0, 5, 89, 235, 0, 5, 89, 475, 0, 5, 91, 475, 0, 5, 89, 475, 0, 5, 88, 235, 0, 245, 89, 475, 0, 5, 91, 235, 0, 5, 91, 235, 0, 5, 91, 475, 0, 5, 91, 955, 0, 1925, 93, 235, 0, 5, 93, 475, 0, 5, 89, 475, 0, 5, 89, 235, 0, 5, 89, 475, 0, 5, 91, 235, 0, 5, 91, 235, 0, 5, 89, 475, 0, 5, 88, 475, 0, 5, 89, 235, 0, 5, 89, 235, 0, 5, 91, 235, 0, 5, 91, 235, 0, 5, 91, 475, 0, 5, 93, 475, 0, 5, 91, 1435, 0, 965, 86, 235, 0, 5, 86, 475, 0, 5, 88, 475, 0, 5, 88, 235, 0, 5, 89, 475, 0, 5, 94, 235, 0, 5, 94, 235, 0, 5, 93, 235, 0, 5, 93, 235, 0, 5, 89, 235, 0, 5, 89, 235, 0, 5, 91, 475, 0, 5, 91, 715, 0, 5, 89, 235, 0, 5, 89, 955, 0, 1925, 86, 475, 0, 5, 86, 475, 0, 5, 88, 475, 0, 5, 89, 475, 0, 5, 94, 715, 0, 245, 89, 475, 0, 5, 91, 475, 0, 5, 91, 715, 0, 5, 89, 1195, 0, 10 };
const float tempoRate=0.00075;
int midiPeriod[128];
int main() {
  PwmOut* pPo = new PwmOut(P0);
  for(int i=0;i<128;++i){
    double freq = 440.0 * pow(2.0 , (double)(i - 69) / 12.0);
    midiPeriod[i] = (freq>10) ? (int)(1000000.0/freq) : 0;
  }
  int szh=sizeof(mididata)>>1;
  for(int i=0;i<szh;++i){
    int period = midiPeriod[mididata[(i<<1)+0]];
    pPo->period_us(period);
    pPo->pulsewidth_us(period>>1);
    row = (period>0) ? 1 : 0; // led
    wait((float)(mididata[(i<<1)+1])*tempoRate);
  }
  pPo->period_us(1);
  pPo->pulsewidth_us(0);
}

```
保存したらmicro:bitをUSBでPCと接続し、下段にある→を押してビルド＆転送します。
![スクリーンショット 2020-01-17 22.08.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59911/1eaca103-877f-d683-9478-71663452f3ac.png)

micro:bitのエディタから転送したときはメモリ不足でハングアップしていましたが、今回は余裕でした。
![スクリーンショット 2020-01-17 22.12.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59911/f512e6e5-86e8-0a4f-6b0f-5dcef632537c.png)

また、micro:bitのエディタでは精度が出なかったためテーブル化していた [midiノートから周波数を求める式](https://qiita.com/ELIXIR/items/e25238ef6855a8468e09) も、
PlatformIO では計算で正しい値を求めることができました(ここでは周波数ではなく時間[μs])。

```
  for(int i=0;i<128;++i){
    double freq = 440.0 * pow(2.0 , (double)(i - 69) / 12.0);
    midiPeriod[i] = (freq>10) ? (int)(1000000.0/freq) : 0;
  }
```