micro:bitでクリスマス飾りを無線操作

# はじめに
某科学館さんから「プログラミングショーをしたい」と相談されました。
聞くと、サイエンスショーのようなスタイルで行いたいらしい。
100人の子供に講師役が1-2人。
確かに効率は良いです。
でもプログラミングは「体験」することがとても大事です。
また、理解する速度も人それぞれ。
画一的な「ショースタイル」には難しい面が多すぎます。

# 10分プログラミング体験
それならば、「(1)誰にでも講師役ができて、(2)子供たちも短時間で体験できるコンテンツ」をと考えまました。
アルバイトさんでも講師ができるほど簡単なことなら、スタッフの手配も楽ちん。
スタッフ手配が楽なら体験できるコーナーも増やせる。
体験できるコーナーが複数あれば、子供たちも複数で体験できる。
さらに、体験時間が短いなら気軽に何度でも試してもらえる。

# micro:bitからの文字列を無線通信経由でUnityアプリで受信する
一つ目のコンテンツとしてモニターを使って色名を送ってダイナミックに文字が表示されるものを作りました。
[「micro:bitからの文字列を無線通信経由でUnityアプリで受信する」](https://qiita.com/SIHO_o/items/5300f2c5c809f888c1b5)
今回は2つ目のコンテンツです。送信側のロジックはどちらも一緒。
受信側をモニターから、LED照明に変えました。

# 開発環境
Window 10
micro:bit 3台
[ZIP Halo - micro:bit用円型フルカラーLED](https://www.switch-science.com/catalog/3484/)
イルミネーションライト3つ(点滅なし。色違いがきれい。100円ショップや秋月に売ってます)

# 完成動画

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">クリスマス飾りをmicro:bit でコントロールするやつを作りました。<br>11/24に開催される子供むけプログラミング教室のイベントネタです。これの送信側のプログラミングを子供たちが体験します。15分プログラミングです！ <a href="https://t.co/Ao6I0uCTP4">pic.twitter.com/Ao6I0uCTP4</a></p>&mdash; SIHO@ままプロ (@SIHO_o) <a href="https://twitter.com/SIHO_o/status/1061557216942030848?ref_src=twsrc%5Etfw">2018年11月11日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

# 機器構成
★クリスマスツリー側
(1)micro:bit + イルミネーションライト3つ（0-2端子に接続）
(2)micro:bit + ZIP Halo
![IMG_4350.JPG](https://qiita-image-store.s3.amazonaws.com/0/310600/583b50fe-2bab-ff8f-a091-33ec6fcf6ef3.jpeg)

★送信側
(3)iPad + micro:bit
![IMG_4269_.JPG](https://qiita-image-store.s3.amazonaws.com/0/310600/60daa787-f596-2815-a34c-1a2d2e2a6c9a.jpeg)

#micro:bitとは
micro:bitはカードサイズのマイコンボードです。英国で開発され、BLEや各種センサーが搭載されています。
プログラミングは、USBポート経由でWindowsやMac、BLEによるペアリング経由でiPadやAndoridタブレットを利用できます。
プログラミングが書き込んであるmicro:bit端末同士でも文字列の送受信が可能です。
micro:bitについては、こちらをご覧ください→[https://microbit.org/ja/](https://microbit.org/ja/)

#micro:bitをiOSで操作するときの基本操作
動画で説明していますので、参考にしてください
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">少し手順が変わっているので、明後日のイベント用に新しく撮りなおした。<br>[micro:bit]iPadでのペアリング方法 <a href="https://t.co/yjpGB2YfFj">https://t.co/yjpGB2YfFj</a></p>&mdash; SIHO🏃‍♀️IT系技術者・漆工芸作家 (@SIHO_o) <a href="https://twitter.com/SIHO_o/status/1223152447226445824?ref_src=twsrc%5Etfw">January 31, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">[micro:bit]iPadでのプログラミング画面の使い方 <a href="https://t.co/pzKwkO1Nd4">https://t.co/pzKwkO1Nd4</a></p>&mdash; SIHO🏃‍♀️IT系技術者・漆工芸作家 (@SIHO_o) <a href="https://twitter.com/SIHO_o/status/1223153671237554176?ref_src=twsrc%5Etfw">January 31, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">iPadでmicro:bitをプログラミングするときの導入動画を新しくしました。書き込みモードにする手順が少し変更されたので、新しくしましたよ。<br>[micro:bit]iPadでのプログラムの書き込み方法 <a href="https://t.co/OUOYfGP0Mc">https://t.co/OUOYfGP0Mc</a></p>&mdash; SIHO🏃‍♀️IT系技術者・漆工芸作家 (@SIHO_o) <a href="https://twitter.com/SIHO_o/status/1223155493641707521?ref_src=twsrc%5Etfw">January 31, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

# Script:(1)micro:bit + イルミネーションライト3つ（0-2端子に接続）
![20181112.png](https://qiita-image-store.s3.amazonaws.com/0/310600/daab3c2e-79ed-9bc4-3489-58a957a011c0.png)

```js:blinkLight.js
let stopTime = 0
function blink() {
    pins.digitalWritePin(DigitalPin.P0, 1)
    pins.digitalWritePin(DigitalPin.P1, 0)
    pins.digitalWritePin(DigitalPin.P2, 0)
    basic.pause(500)
}
function stopFunc() {
    pins.digitalWritePin(DigitalPin.P0, 0)
    pins.digitalWritePin(DigitalPin.P1, 0)
    pins.digitalWritePin(DigitalPin.P2, 0)
    basic.pause(2100)
    stopTime = 0
}
function blink2() {
    pins.digitalWritePin(DigitalPin.P0, 0)
    pins.digitalWritePin(DigitalPin.P1, 1)
    pins.digitalWritePin(DigitalPin.P2, 0)
    basic.pause(500)
}
radio.onReceivedString(function (receivedString) {
    stopTime = 1
})
function blink3() {
    pins.digitalWritePin(DigitalPin.P0, 0)
    pins.digitalWritePin(DigitalPin.P1, 0)
    pins.digitalWritePin(DigitalPin.P2, 1)
    basic.pause(500)
}
radio.setGroup(1)
stopTime = 0
basic.forever(function () {
    if (stopTime == 0) {
        blink()
        if (stopTime == 0) {
            blink2()
            if (stopTime == 0) {
                blink3()
            } else {
                stopFunc()
            }
        } else {
            stopFunc()
        }
    } else {
        stopFunc()
    }
})
```
イルミネーションと端子の接続に悩んだら、こちらの記事をご覧ください。
[「MICRO:BITと百円ショップ商品で作る、クリスマスツリーイルミネーション」](http://fabkominka.pigmal.com/blog/2017/12/15/microbit1/)
わかりやすいです。ただし、イルミネーションの電池は単三が3本のものでも2本と同じように使えます。ただやはりmicro:bitからの出力は3V弱なのでしょう。輝度が多少弱まります。
昇圧モジュールを挟むともっと良い感じに光りそうです。

# Script:(2)micro:bit + ZIP Halo
こちらは設定前にmakecodeにてNeopixelの拡張パッケージを追加してください。
micro:bitにはLower関数がないため、とても長い条件文になっていますが、やっていることは単純です。
通常はフルカラーが回転しながら光っていて、無線で指定の色名が送られてきたらその色で点滅するだけです。
■設定してある色
red
black
blue
green
pink
yellow
orange
purple

![20181111.png](https://qiita-image-store.s3.amazonaws.com/0/310600/7ff4c17b-f3c0-8335-f210-24c296fecacd.png)

```js:neopixelBleControll.js
let PushColor = 0
let neopixel2: neopixel.Strip = null
function setRainbow() {
    neopixel2 = neopixel.create(DigitalPin.P0, 24, NeoPixelMode.RGB)
    neopixel2.showRainbow(1, 360)
}
radio.onReceivedString(function (receivedString) {
    if (receivedString == "RED" || (receivedString == "Red" || receivedString == "red")) {
        PushColor = neopixel.colors(NeoPixelColors.Red)
        playColor()
    } else if (receivedString == "BLACK" || (receivedString == "Black" || receivedString == "black")) {
        PushColor = neopixel.colors(NeoPixelColors.Black)
        playColor()
    } else if (receivedString == "BLUE" || (receivedString == "Blue" || receivedString == "blue")) {
        PushColor = neopixel.colors(NeoPixelColors.Blue)
        playColor()
    } else if (receivedString == "GREEN" || (receivedString == "Green" || receivedString == "green")) {
        PushColor = neopixel.colors(NeoPixelColors.Green)
        playColor()
    } else if (receivedString == "PINK" || (receivedString == "Pink" || receivedString == "pink")) {
        PushColor = neopixel.rgb(255, 105, 180)
        playColor()
    } else if (receivedString == "YELLOW" || (receivedString == "Yellow" || receivedString == "yellow")) {
        PushColor = neopixel.colors(NeoPixelColors.Yellow)
        playColor()
    } else if (receivedString == "ORANGE" || (receivedString == "Orange" || receivedString == "orange")) {
        PushColor = neopixel.colors(NeoPixelColors.Orange)
        playColor()
    } else if (receivedString == "PURPLE" || (receivedString == "Purple" || receivedString == "purple")) {
        PushColor = neopixel.colors(NeoPixelColors.Purple)
        playColor()
    } else if (receivedString == "WHITE" || (receivedString == "White" || receivedString == "white")) {
        PushColor = neopixel.colors(NeoPixelColors.White)
        playColor()
    }
})
function SetColor() {
    neopixel2.rotate(1)
    neopixel2.show()
}
function playColor() {
    neopixel2.showColor(neopixel.colors(NeoPixelColors.Black))
    basic.pause(50)
    for (let i = 0; i < 7; i++) {
        neopixel2.showColor(PushColor)
        basic.pause(150)
        neopixel2.showColor(neopixel.colors(NeoPixelColors.Black))
        basic.pause(150)
    }
    neopixel2.showColor(PushColor)
    basic.pause(500)
    setRainbow()
    SetColor()
}
radio.setGroup(1)
setRainbow()
basic.forever(function () {
    SetColor()
})
```

# Script:(3)iPad + micro:bit
子供が実際に体験するプログラミングなのでできるだけ単純にしてあります。
文字を入力するのと、ボタンの設定を覚えるだけですね。
イベントで利用するときは、前の人が作ったプログラミングがそのまま残っていますので、実際は色名を変えるだけで完了すると思います。
■変更可能な色名
red
black
blue
green
pink
yellow
orange
purple
※イベントで利用するときは、これらを紙に印刷しておくとよいと思います。

![20181111_3.png](https://qiita-image-store.s3.amazonaws.com/0/310600/3ce13b81-fc12-7900-5264-3fba7126b6bb.png)

```js:SendColor.js
input.onButtonPressed(Button.A, function () {
    radio.sendString("pink")
})
input.onButtonPressed(Button.B, function () {
    radio.sendString("blue")
})
input.onButtonPressed(Button.AB, function () {
    radio.sendString("orange")
})
radio.setGroup(1)
```

# まとめ

また10分プログラミングがネタが思いついたら書きます。
アイディア募集中です。