MakeCode for micro:bit で C/C++プログラミング

# 実は、

少し工夫をすると、 [Microsoft MakeCode for micro:bit](https://makecode.microbit.org/) でも、 **C/C++** によるプログラミングが可能です。

**helloworld.cpp**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252891/2ed8c545-6566-8be7-1c5b-90a24c7ddc0f.png)

# 必要なもの

[Microsoft MakeCode for micro:bit](https://makecode.microbit.org/) 上で、C/C++によるプログラミングをするために、次のものが必要です。

1. micro:bit(本体)
1. [GitHubアカウント](https://github.com/)

## micro:bit(本体)

C/C++で開発したプログラムを実行するには、 **micro:bit(本体)** への転送が必要です。MakeCodeのシミュレーターでは、実行することができません（シミュレーションできません）。
**micro:bit** のバージョン毎に、ランタイム等が異なりますので、できれば、**v1**と**v2**の２つを用意して、動作確認を行います。

|micro:bit|ランタイム|nRF5|
|---------|---------|----|
|V1|dal|Soft Device 110|
|V2|codal|Soft Device 113|

**The micro:bit runtime DAL/CODAL (英語)**

https://tech.microbit.org/software/runtime/

## GitHubアカウント
[Microsoft MakeCode for micro:bit](https://makecode.microbit.org/) では、作成したプロジェクトのソースコード一式を [GitHub](https://github.com/) で管理することができます。また、C/C++プログラミングに必要なファイルを追加するために、 [GitHub](https://github.com/) を使用します。
その為、[GitHub](https://github.com/) への **サインイン** が必要になりますので、事前に **GitHubアカウント** を用意してください（ [**サインアップ - https://github.com/signup**](https://github.com/signup) ）。

# C/C++で Hello World!

[Microsoft MakeCode for micro:bit](https://makecode.microbit.org/) の `文字列を表示` ブロックでは、その実行中（スクロール表示中）、順次実行がブロックされ、そのブロックの実行（スクロール表示）が完了するまで、次のブロックは実行されません（同期処理）。
C/C++プログラムの例として、この文字列表示をバックグラウンドで実行する `showAsyncString` ブロックをC/C++でプログラミングします。

## プロジェクトの新規作成

[Microsoft MakeCode for micro:bit](https://makecode.microbit.org/) で、 **新しいプロジェクト** を作成します。

ここでは、プロジェクト名を `microbit-cpp` にしました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252891/7a724260-0863-050d-e532-8cd6c1e4cc07.png)

## C/C++ファイルの追加

[Microsoft MakeCode for micro:bit](https://makecode.microbit.org/) 上では、ts形式以外のファイルを追加できません。そこで、MakeCodeのプロジェクトをGitHubリポジトリに登録し、GitHub上で、ts形式以外のファイルを追加します。

次の手順で、C/C++ファイル等を追加します。

**1.GitHubリポジトリを作成する**
`GitHubリポジトリを作成する` アイコンをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252891/529a32e8-733c-9bbb-1001-e2e438314917.png)

**2.GitHubでサインイン**
準備したGitHubアカウントでサインインします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252891/9baa633b-98bd-e288-f8af-9e62d739d510.png)

**3.GitHubリポジトリを作成**
`リポジトリ名` を確認し、 `つづける` ボタンでGitHubリポジトリを作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252891/833916b7-b98e-af1e-c199-312f1a56a6f2.png)

**4.リポジトリを準備中**
リポジトリが作成されるのを待ちます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252891/087dc8e2-3cba-26d2-9b4f-8b2f612e0947.png)

**5.リポジトリ作成完了**
リポジトリの作成が完了したら、 `ローカルの変更はGitHubと同期されます` アイコンをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252891/186951c6-2c6c-4896-2de7-5624115cd0b2.png)

**6.GitHubでリポジトリを開く**
`GitHubでリポジトリを開きます。` アイコンをクリックし、GitHubリポジトリを開きます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252891/52afc089-672b-5875-2996-ce2646d1f7d6.png)

**7.GitHubリポジトリにファイルを追加**
`＋` アイコンの `Create new file` をクリックし、ファイルを追加します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252891/d3dd12a5-1999-8a32-23c9-e2a33439c833.png)

**8.helloworld.cppファイルを追加**
ファイル名を `helloworld.cpp` とし、 `Commit changes..` で追加を確定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252891/f8e4c36b-b75d-eac6-1a92-6b3f62ab3a98.png)

**9.Commit changes**
`Commit changes` ボタンをクリックし、確定します。 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252891/b1bd6f83-dd97-b323-629a-1ac23fbdabb1.png)

**10.ptx.jsonファイルを編集**
GitHub上で、 `ptx.json` ファイルを編集し、 `helloworld.cpp` ファイルをプロジェクトに含めるようにします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252891/67f92343-4593-f897-4d19-f5c0355f7a89.png)

**11.Commit changes**
`ptx.json` ファイルの変更を確定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252891/e6537408-e905-f3a3-bc28-131c83565dbc.png)

**12.変更を取得（プル）**
MakeCode上で、 `変更を取得（プル）` ボタンをクリックし、GitHub上での変更をMakeCode上のプロジェクトに反映します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252891/773bbdfa-bab8-379b-ef6e-5e4fb4a8cf49.png)

**13.カスタムブロックの追加**
JavaScriptモードにして、エクスプローラーの `＋` アイコンをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252891/29cb0f0f-d470-90b2-5f1f-c307637bc805.png)

**14.新しいファイルの名前**
新しいファイル名を `helloworld.ts` とし、 `つづける` ボタンをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252891/1748eeaf-9f41-ef82-2cf7-e44dcefbe039.png)

**15.空のhelloworld.tsファイル**
`helloworld.ts` ファイルが作成されたことを確認します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252891/2907707c-144e-3e98-52d7-aa11d75793de.png)

**16.変更をコミットしてプッシュ**
`変更をコミットしてプッシュ` ボタンをクリックし、MakeCode上での変更をGitHubへ反映します。 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252891/f86a8967-cdab-ea8e-df68-17deedc2d058.png)

**17.GitHubリポジトリの確認**
GitHubリポジトリを開くと、 `helloworld.ts` ファイルが追加されていることを確認できます。また、 `ptx.json` ファイルにも、 `helloworld.ts` の記述が追加されていることも確認できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252891/e72c9080-aeec-9daf-d55e-e13074fac884.png)

## C/C++プログラミング

`helloworld.cpp` ファイルで、C/C++プログラミングを行いますが、それを呼び出すための拡張機能（ブロック）のプログラミングも必要です。

次のように各ファイルでプログラミングします。

```ts: helloworld.ts
/**
 * Hello World blocks
 * icon: a Unicode identifier for an icon from the Font Awesome icon set.
 *       http://fontawesome.io/icons
 */
//% weight=100 color=#696969 icon="\uf1b2"
namespace helloworld {

    /**
     * Show string, async
     * @param text 非同期でスクロール表示する文字列
     */
    //% block
    //% shim=helloworld::showAsyncString
    export function showAsyncString(text: string): void {
        // for the simulator
        basic.showString(text)
    }

    /**
     * Stop animation
     */
    //% block
    //% shim=helloworld::stopAnimation
    export function stopAnimation(): void {
        // for the simulator
        basic.clearScreen()
    }
}
```

```cpp: helloworld.cpp
#include "pxt.h"

namespace helloworld {
    
    //%
    void showAsyncString(String text) {
        uBit.display.scrollAsync(MSTR(text));
    }

    //%
    void stopAnimation() {
        uBit.display.stopAnimation();
    }
}
```

## コンパイル

コンパイルは、 `ダウンロード` ボタンでHEX形式ファイルをダウンロードする際に、MakeCode内部で行われます。
ここで、 `ダウンロード` ボタンをクリックすると、 `コンパイル（これには1分かかることがあります）...`　と表示され、コンパイルが行われます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252891/f4dc49bd-c1d3-cd34-670f-f701072c5abb.png)

## 動作確認

C/C++のプログラムは、MakeCodeのシミュレーターでは、実行されません。HEX形式ファイルをダウンロードし、micro:bit本体に転送し、動作確認します。

ブロック例では、次のように動作します。

1. Aボタンでは、文字列表示とメロディーが同時に実行されます。
1. Bボタンでは、文字列表示が実行されてからメロディーが実行されます。

**ブロック例**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252891/08468b18-17d8-5c78-1564-56ae5fccc76f.png)

```js: JavaScript
input.onButtonPressed(Button.A, function () {
    reset()
    helloworld.showAsyncString("Happy birthday!")
    music._playDefaultBackground(music.builtInPlayableMelody(Melodies.Birthday), music.PlaybackMode.InBackground)
})
input.onButtonPressed(Button.B, function () {
    reset()
    basic.showString("Hello!")
    music._playDefaultBackground(music.builtInPlayableMelody(Melodies.Dadadadum), music.PlaybackMode.InBackground)
})
function reset () {
    helloworld.stopAnimation()
    basic.clearScreen()
    music.stopAllSounds()
    basic.pause(100)
}
basic.showIcon(IconNames.Heart)

```

# おわりに

[Microsoft MakeCode for micro:bit](https://makecode.microbit.org/) でも、 **C/C++** によるプログラミングが可能であることを確認しました。