【Node-RED】RaspberryPiを使用して木魚を鳴らしてみる

この記事は 「Node-RED Advent Calendar 2019 - Qiita」の 17日目 の記事です。

今年の秋頃からNode-REDのはじめました。なんとなくですが使い方もわかってきたので工作をやてみようかなと思いました。 LEDを点灯させるのはよくある話なので、今回は木魚をならしてみたいと思います。

f:id:ueponx:20191217191423p:plain

ハード編

木魚の鳴らし方としてはモーターを使用するを考えてましたが、SG90とかで駆動できるといいなあと思っていましたが、 木魚のバチを叩くほどのパワーはありませんでした。 歯車を使用してパワーを得ようとおもったのですが、今度はスピードが少しない感じです。

ということで、今回はソレノイドを使用して見ようと思います。 ソレノイドに関しては以下のサイトをみていただければと思いますが

www.takaha.co.jp

簡単に言うとコイルに電源を流して、中の芯(ブランジャー)を動かすものになります。 身の回りのものでは電子ロックなどにも使われているような技術になります。

ブランジャーの動きによって種類があって

  • プルソレノイド
  • プッシュソレノイド
  • 自己保持ソレノイド

があるようです。

小さいソレノイドは秋月電子さんや共立電子さんなどにも売っています。RaspberryPi程度の電源では小さなスイッチを操作する程度はありますが、 楽器のバチを叩く程度の大きなパワーを得られませんでした。 そこで今回はソレノイドで有名なタカハ機工さんのものを使用します。

www.takaha.co.jp

大きめのパワーが得られて低い電圧でも駆動できるものを考えてCBS1240/CBS12400080(8Ω)に決めました。

【参考】

http://takaha.co.jp/product/cb/img/item/CBS1240_SUB.jpg

http://takaha.co.jp/product/cb/img/item/cbs1240_image_02_l.gif

スペックとしては6Vで駆動できるようです。5Vだとちょっと動くかかなという不安はありますが…

タカハさんはAmazonPayで購入できるので通販もいいかなと思います。東京だったら秋葉原のラジオデパートの2階に明和電機さんのお店があるのでそちらで購入するのが手っ取り早いかもしれません。

www.maywadenki.com

回路としては以下の様になるかなと思います。RaspberryPiはGPIOは3.3Vなので、2SC1815を使用しています。

f:id:ueponx:20191217135306p:plain

ここまできたらあとは木魚の高さを調節するためにタミヤのユニバーサルプレートを準備します。

昔ならボビーショップやプラモデル(ミニ四駆)を売っているようなところに売っていそうですが、地方ではそういう店に行っても割とおいてはいないので 通販をおすすめします。

ソフトウエア(Node-RED)編

あとはこれを制御するソフトウエアを作成することになりますが、今回はRaspberryPiにインストールしたNode-REDを使用します。

基本的にはGPIOのON/OFFを定期的に行う処理を行うことになります。繰り返しを行うので以下のエントリーを参考にループ処理を行います。

【参考】 qiita.com

こちらの例ではWhileループですが今回は無限ループで条件が発生した場合にはbreakするような処理になります。Whileの処理に近いといえば近いです。

手動で動作させるフローを先に出すとすると以下のようになるかなと思います。

f:id:ueponx:20191217172010p:plain

今回のフローではGPIOの0/1切り替えをmsg.payloadで行い、全体の動作状態run/stopを司る変数をflow.modeとして制御しています。 一度フローを実行するとループに入り込んだ処理がストップ状態を書き換えてしまうので、新しく動作状態を作っています。

スタートとストップ

injectノードを使用してスタートとストップを操作できるようにしています。その後に続くchangeノードでflow.mode(string:{”run”|”stop”})と msg.payload(Integer:{0|1})を代入しています。

【スタート側の処理】 f:id:ueponx:20191217162358p:plain

【ストップ側の処理】 f:id:ueponx:20191217162408p:plain

f:id:ueponx:20191217173019p:plain

ループ処理

ループに関する部分は以下のようになります。

f:id:ueponx:20191217172219p:plain

switchノードでflow.modeでループ状態を判断し、

f:id:ueponx:20191217165630p:plain

ループを抜けるかどうかを判断しています。

f:id:ueponx:20191217165654p:plain

その後段のswitchノードでGPIOの0/1を判断しています。その後のchangeノードでmsg.payloadの0/1のトグル処理をしています。

f:id:ueponx:20191217165835p:plain

f:id:ueponx:20191217165907p:plain

もっと良い処理がありそうですが…

あとはmodeがrun状態であればGPIOに0.5秒毎に0/1が送られ、stop状態であればGPIOに0が常に送られます。

f:id:ueponx:20191217165220p:plain

Webからの起動

Webからも木魚を鳴らせるようにしようと思います。

これはかんたんにhttp inノードを使ってURLアクセスをしたらflow.modeとmsg.payloadに代入しています。 injectノードのあとの処理を代用しても良かったのですが、今回は新規に作っています。

Web経由でスタートする場合には/mokugyo/on f:id:ueponx:20191217170351p:plain

Web経由でストップする場合には/mokugyo/off f:id:ueponx:20191217170426p:plain

Webアクセスの部分を切り出すとこのような形になっています。

f:id:ueponx:20191217165406p:plain

changeノードで値を設定したらループのswitchノードと接続すればOKです。これはよくあるパターンです。

最終的にできたフロー再掲

終結果のフローはこのような形になります。

f:id:ueponx:20191217155652p:plain

動作確認

では、実際に動かしてみようと思います。


Node-REDで木魚を叩いてみる

無事に動作しました!

おわりに

【今回作成したフロー】

[
    {
        "id": "c7f37167.82ae8",
        "type": "tab",
        "label": "フロー 1",
        "disabled": false,
        "info": ""
    },
    {
        "id": "1aaeee48.d52b52",
        "type": "inject",
        "z": "c7f37167.82ae8",
        "name": "スタート",
        "topic": "",
        "payload": "1",
        "payloadType": "num",
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "x": 100,
        "y": 60,
        "wires": [
            [
                "9814504b.3fe4e"
            ]
        ]
    },
    {
        "id": "8507ccb5.08e81",
        "type": "rpi-gpio out",
        "z": "c7f37167.82ae8",
        "name": "",
        "pin": "7",
        "set": true,
        "level": "0",
        "freq": "",
        "out": "out",
        "x": 940,
        "y": 160,
        "wires": []
    },
    {
        "id": "95fb4ec1.979e7",
        "type": "delay",
        "z": "c7f37167.82ae8",
        "name": "",
        "pauseType": "delay",
        "timeout": "0.5",
        "timeoutUnits": "seconds",
        "rate": "1",
        "nbRateUnits": "1",
        "rateUnits": "second",
        "randomFirst": "1",
        "randomLast": "5",
        "randomUnits": "seconds",
        "drop": false,
        "x": 790,
        "y": 400,
        "wires": [
            [
                "d653f7e0.0643a8"
            ]
        ]
    },
    {
        "id": "c867ec32.1ecab",
        "type": "switch",
        "z": "c7f37167.82ae8",
        "name": "",
        "property": "payload",
        "propertyType": "msg",
        "rules": [
            {
                "t": "eq",
                "v": "0",
                "vt": "num"
            },
            {
                "t": "eq",
                "v": "1",
                "vt": "num"
            },
            {
                "t": "else"
            }
        ],
        "checkall": "true",
        "repair": false,
        "outputs": 3,
        "x": 590,
        "y": 280,
        "wires": [
            [
                "8507ccb5.08e81",
                "9d8ff730.f633d8"
            ],
            [
                "8507ccb5.08e81",
                "c4583abd.9d70b8"
            ],
            []
        ]
    },
    {
        "id": "9d8ff730.f633d8",
        "type": "change",
        "z": "c7f37167.82ae8",
        "name": "",
        "rules": [
            {
                "t": "set",
                "p": "payload",
                "pt": "msg",
                "to": "1",
                "tot": "num"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 840,
        "y": 260,
        "wires": [
            [
                "95fb4ec1.979e7"
            ]
        ]
    },
    {
        "id": "c4583abd.9d70b8",
        "type": "change",
        "z": "c7f37167.82ae8",
        "name": "",
        "rules": [
            {
                "t": "set",
                "p": "payload",
                "pt": "msg",
                "to": "0",
                "tot": "num"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 840,
        "y": 300,
        "wires": [
            [
                "95fb4ec1.979e7"
            ]
        ]
    },
    {
        "id": "d653f7e0.0643a8",
        "type": "switch",
        "z": "c7f37167.82ae8",
        "name": "",
        "property": "mode",
        "propertyType": "flow",
        "rules": [
            {
                "t": "eq",
                "v": "stop",
                "vt": "str"
            },
            {
                "t": "else"
            }
        ],
        "checkall": "true",
        "repair": false,
        "outputs": 2,
        "x": 330,
        "y": 300,
        "wires": [
            [
                "5b0120c0.1a77d"
            ],
            [
                "c867ec32.1ecab"
            ]
        ]
    },
    {
        "id": "5b0120c0.1a77d",
        "type": "change",
        "z": "c7f37167.82ae8",
        "name": "",
        "rules": [
            {
                "t": "set",
                "p": "payload",
                "pt": "msg",
                "to": "0",
                "tot": "num"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 620,
        "y": 160,
        "wires": [
            [
                "8507ccb5.08e81"
            ]
        ]
    },
    {
        "id": "9814504b.3fe4e",
        "type": "change",
        "z": "c7f37167.82ae8",
        "name": "",
        "rules": [
            {
                "t": "set",
                "p": "mode",
                "pt": "flow",
                "to": "run",
                "tot": "str"
            },
            {
                "t": "set",
                "p": "payload",
                "pt": "msg",
                "to": "1",
                "tot": "num"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 260,
        "y": 60,
        "wires": [
            [
                "d653f7e0.0643a8"
            ]
        ]
    },
    {
        "id": "b918518b.9cd01",
        "type": "inject",
        "z": "c7f37167.82ae8",
        "name": "ストップ",
        "topic": "",
        "payload": "1",
        "payloadType": "num",
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "x": 100,
        "y": 120,
        "wires": [
            [
                "c534e253.12e65"
            ]
        ]
    },
    {
        "id": "c534e253.12e65",
        "type": "change",
        "z": "c7f37167.82ae8",
        "name": "",
        "rules": [
            {
                "t": "set",
                "p": "mode",
                "pt": "flow",
                "to": "stop",
                "tot": "str"
            },
            {
                "t": "set",
                "p": "payload",
                "pt": "msg",
                "to": "0",
                "tot": "num"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 260,
        "y": 120,
        "wires": [
            [
                "d653f7e0.0643a8"
            ]
        ]
    },
    {
        "id": "f8156f4b.6600a",
        "type": "http in",
        "z": "c7f37167.82ae8",
        "name": "WEBアクセスでスタート",
        "url": "/mokugyo/on",
        "method": "get",
        "upload": false,
        "swaggerDoc": "",
        "x": 190,
        "y": 500,
        "wires": [
            [
                "5859b9e7.453f78"
            ]
        ]
    },
    {
        "id": "5859b9e7.453f78",
        "type": "change",
        "z": "c7f37167.82ae8",
        "name": "",
        "rules": [
            {
                "t": "set",
                "p": "mode",
                "pt": "flow",
                "to": "run",
                "tot": "str"
            },
            {
                "t": "set",
                "p": "payload",
                "pt": "msg",
                "to": "1",
                "tot": "num"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 430,
        "y": 500,
        "wires": [
            [
                "8593011b.c3a39",
                "d653f7e0.0643a8"
            ]
        ]
    },
    {
        "id": "8593011b.c3a39",
        "type": "debug",
        "z": "c7f37167.82ae8",
        "name": "",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "payload",
        "targetType": "msg",
        "x": 670,
        "y": 520,
        "wires": []
    },
    {
        "id": "81a03b2e.ebacf8",
        "type": "http in",
        "z": "c7f37167.82ae8",
        "name": "WEBアクセスでストップ",
        "url": "/mokugyo/off",
        "method": "get",
        "upload": false,
        "swaggerDoc": "",
        "x": 190,
        "y": 560,
        "wires": [
            [
                "552120e4.469a5"
            ]
        ]
    },
    {
        "id": "552120e4.469a5",
        "type": "change",
        "z": "c7f37167.82ae8",
        "name": "",
        "rules": [
            {
                "t": "set",
                "p": "mode",
                "pt": "flow",
                "to": "stop",
                "tot": "str"
            },
            {
                "t": "set",
                "p": "payload",
                "pt": "msg",
                "to": "0",
                "tot": "num"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 430,
        "y": 560,
        "wires": [
            [
                "8593011b.c3a39",
                "d653f7e0.0643a8"
            ]
        ]
    }
]
/* -----codeの行番号----- */