micro:bit v2 (makecode v3) で拡張機能をつくってみる

micro:bit が 2020年11月末にバージョンアップしました。

むかしにつくった、とある拡張がうごかないだろうなので、えいやとバージョンアップしてみました。
https://github.com/pizayanz/pxt-linebeacon
（まだ作業中です）

Qiita にも、当時拡張の作り方の記事を書いたはずと探すも、なんと中途半端な下書きで終わっていたことを発見。オレってだめだなぁ。
その反省をいかして、この記事は、中途半端でも公開しちゃって、すこしずつ作業をすすめながら、書き足しながら、にしたいと思っています。

記載内容がころころかわっても、お許しください。
ずっと未来永劫、中途半端でも、お許しください。

はまったところだけでも、いまアップしておけば、同じ状況の人たちのお役に立てるかな。。。という思いなので、お許し下さい。

TypeScript だけでなく、C++(cpp) もつかっているため、技術的なレイヤーはすこし深めかと思いますが、
TypeScript だけで拡張をつくりたいひとにも、引っ掛かりポイントが同じ部分もあるので、一部は参考にしていただけるかと思います。

## かるい引っ掛かりポイント

2020年11月現在。

micro:bit (基板自体) は v2 (Version 2)

makecode (ブラウザとかで動くコードエディタね） は v3 (Version 3)

まぁ、念のために把握しておきましょう。

ちなみに、makecode のことは、PXT という表記でも頻繁に出てきます。

PXT とは、Microsoft Programming Experience Toolkit の略。
いろいろな種類があるのですが、micro:bit 用は、pxt-microbit だったりします。

## めちゃ引っ掛かりポイント

typescript で extension.ts などで、ブロックを定義するとき、
c++ を使いたい場合は、extension.cpp などのコードも用意します。

この違いなのですが、ざっくりと、ts は、makecode 内のシミュレーター用です。
cpp は、micro:bit 内でうごくものとなります。

### まず確認


### 空っぽの function について

このへんをみながら、ブロックを作っていくことになるのですが、
https://makecode.com/defining-blocks


これがだめ。よくわからないけど、うまくいかなかった。

```typescript
/**
* this is hoge
*/
//% blockId=hoge
//% block="Hoge"
//% block.loc.ja="ほげ"
//% weight=10 blockGap=8 shim=hogehoge::hoge
export function hoge(): void {
}
```


これらオッケーぽかった。


```typescript
/**
* this is hoge
*/
//% blockId=hoge
//% block="Hoge"
//% block.loc.ja="ほげ"
//% weight=10 blockGap=8 shim=hogehoge::hoge
export function hoge(): void {
    return;
} 


※ねぶかい件

.cpp しかコードが必要がないときは、cpp 側にブロック定義をしかるべく定義すれば、
.ts 側は省略してもよいという仕様。

.ts 側は、ビルド時に、自動的に .cpp をなめて、shim.d.ts なる中間ファイルを自動生成してくれる。

そのときの自動生成が、export ついてないから、おかしかったりするのかなと思いつつ。調査しきっていない。

```typescript
/**
* this is hoge
*/
//% blockId=hoge
//% block="Hoge"
//% block.loc.ja="ほげ"
//% weight=10 blockGap=8 shim=hogehoge::hoge
function hoge(): void;
```

そして、これだと、makecode で、property がみつからないだのどうのこうの、エラーが起きるという、どはまり。

Cannot read property 'hoge' of undefined


シミュレーターで、とくになにを動作させる必要がないときは、cpp 側にだけ function をつくって、そっちに block 修飾子のようなコメントをつくるだけでもいいのですが、作業中って、ちょっとしたデバッグコードかいたり、消したりするんですよね。

そのときに、からっぽの Function をおきっぱにすると、なぜか動かないケースがあって、とてもはまりました。

error TS2384: Overload signatures must all be ambient or non-ambient.

とか、makecode の console.log ではきだされているときは、このへんの二重定義がおかしいとかどうこうなかんじだった。（.ts で宣言した function と、.cpp から自動生成される .ts とが衝突している感じ）


### もうひとつ、はまりポイント。

typescript 側に、block 修飾子をかいておいて、cpp 側に同名の Function を用意して、block 修飾子を //% だけで済ませるケースがあります。

このときに、cpp 側に、丁寧にコメントを書くとなぜか動かないのです。コンパイルはとおるけど、makecode で動かないという。。。

```cpp
/**
* this is hoge
*/
//%
void hoge() {        
    ...
}  

```

これだと動きます。

```cpp
//%
void hoge() {        
    ...
}  

```

バージョンアップしたての、いまだけ、なんらかの PXT ジェネレーターがもつバグかもしれませんが、かなりわたしははまってしまったので、ご注意ください。

## メモ

Nordic の　SDK は version 16 相当が組み込まれている感じ。

nrf52833

Softdevice は S113（おそらく micro:bit v1用）と S140（こっちが v2）
https://files.seeedstudio.com/products/102991374/BBC-microbit-v2-datasheet-v1.2.pdf

ぽいのですが、codal-microbit-nrf5sdk などをもぐっていくと、S140 はとりこまれているものの、利用されていない気配がある。S113 でうごいているのか、要確認。

https://github.com/microbit-foundation/codal-microbit-nrf5sdk
https://github.com/microbit-foundation/codal-microbit-nrf5sdk/commit/b2fe152660abf0e99ed4ec3281042003237283f9

## よくわからんでばっぐ

conda create -n pxt python=2.7
conda activate pxt

conda install -c conda-forge nodejs

pxt は node 8.9.4 以上とのこと メジャーバージョンをあわせておいたほうがよいかもだけど、最新いっちゃえ。15.3.0 がはいった。
conda search -c conda-forge nodejs

もどそう
conda uninstall -c conda-forge nodejs

conda install nodejs
10.13.0 になった

その後、どうも v10 系があやしいのかもとおもう挙動があったので、推奨の v8.9.4 以降に。

conda uninstall nodejs 

して

conda install nodejs=8

だと、8.9.3 までだったので

conda install -c conda-forge nodejs=8

で、8.10.0

がはいった。しかし、なんだか npm install で msvs 依存がどうこうと、あやしい。
いろんなバージョンをためすかな。Microsoft Build Tools バージョンも 2015 をいれたりいろいろ。


http://docs.yottabuild.org/#installing-on-windows

webusb 関連ファイルをインストール

cd pxt-microbit
pxt npminstallnative

> pxt hiddmesg
Using target microbit with build engine yotta
  target: v3.0.61 C:\Users\hisayan\Downloads\pxt-microbit
  pxt-core: v6.0.35 C:\Users\hisayan\Downloads\pxt-microbit\node_modules\pxt-core
package "webusb" failed to load, run "pxt npminstallnative" to install native depencencies
INTERNAL ERROR: TypeError: Cannot read property 'USBAdapter' of undefined

 PXT_USE_HID=9796990b pxt hiddmesg

pxt-microbit/libs/core/dal.d.ts
MICROBIT_DMESG_LEVEL = MICROBIT_DMESG_LEVEL_DEBUG

## 最後にすこし宣伝

micro:bit はもちろん、scratch をフル改造したり、Node-RED のブロックつくったり、結構得意です。
そういう案件がある際は、こまやかなお仕事や相談にものりますので、お気軽にご相談ください。