【RaspberryPi】Node-Redでカメラを使用する(mjpg_streaming)

前回のエントリではNode-REDを使用したカメラの使用を行っていましたが、その中で気になっていたものが残っていたのですが、 ちょっと試してみるとハマったのでそれに関してメモっておこうと思います。

気になった拡張ノードは以下のものです。

flows.nodered.org

これを使用するとカメラ画像をストリーミング的に使用できそう?

A node that consumes a mjpeg stream and outputs the latest saved frame as buffer

ドキュメントを見ると、mpeg_streamを使用してカメラ撮影した最新のバッファを取得するという機能を持つもののようです。 ページをパッと見た感じではインストールせよとははっきりとはわからないのですが、mjpg_streamというアプリケーションが必要のようです。 もう少しはっきりと書いてほしいかも。

事前準備

ドキュメントにもgithubのURLがあるのでこちらを見ながらインストールをします。aptコマンドではインストールはできないのでちょっと手間がかかります。

github.com

githubのドキュメントに従って行けば概ねインストールには引っかからない感じです。

$ cd ~
$ sudo apt update 
$ sudo apt install -y cmake libv4l-dev libjpeg-dev imagemagick
$ git clone https://github.com/jacksonliam/mjpg-streamer.git
$ cd mjpg-streamer/mjpg-streamer-experimental
$ make
$ sudo make install

ネットで検索すると上記の手順の最後にあるsudo make installを行わず、ローカルディレクトリで実行しているところが多かったのですが、私はインストールまで行っています。

インストールが終わったら試しに実行してみます。 mjpg_streamerは入力方法と出力方法のそれぞれをオプションの指定することによって実行する仕組なのでそれぞれ指定します。

$ mjpg_streamer -o "output_http.so -w /usr/local/share/mjpg-stream/www" -i "input_raspicam.so"

以下の実行例では

  • 入力:RaspberryPiのカメラモジュール(パラメータの類はデフォルト設定)
  • 出力:httpプロトコル

(注記)/usr/local/share/mjpg-stream/wwwはテスト用の静的コンテンツの入ったパスになります。インストールするとローカルからこのパスにコピーされます。

となっています。実行するとエラーが発生しなければ以下のような設定一覧が表示された画面が出力され、起動します。

f:id:ueponx:20191009085231p:plain

ここまできたら、キャプチャがうまく行っているか確認してみます。ブラウザでhttp://raspberrypi.local:8080/にアクセスするとWebでの実行画面が表示されます。 (注)mDNSでのアクセスが出来ていない場合にはhttp://【RaspberryPiのIPアドレス】:8080/でアクセスをしてください。

f:id:ueponx:20191009085948p:plain

これでmjpg_streamのインストールは完了です。 インストールの確認が終わったら、コンソール上で起動したmjpg_streamはCtrl+Cで終了させておきます。

拡張ノード(node-red-contrib-mjpgcamera)をインストール

先程作業で、事前準備が終わったので拡張ノードをインストールします。 これまでの拡張ノード同様に【三】をクリックし、メニューから【パレットの管理】を選択します。

f:id:ueponx:20191009091819p:plain

【ユーザー設定】で【ノード追加】タブをクリックし、検索ボックスにmjpgを入力すると該当の拡張ノードが表示されます。 名前を確認して【ノードを追加】ボタンをクリックします。確認ダイアログでも【追加】ボタンをクリックしてください。●

f:id:ueponx:20191009092659p:plain

インストールが完了するとelectronicplaygroundのカテゴリーに拡張ノードが格納されます。

f:id:ueponx:20191009092954p:plain

名称はmjpg consumerとなっています。

実際に使用してみる

今回は、ノードをワークスペースにドロップせず、以下のテキスト(JSON形式ですが)をクリップボードからペーストしてみます。テキストで保存できるので gitなんかとも親和性ありそうですね。今後調べてみたいです。

[{"id":"5b126518.b3359c","type":"tab","label":"mjpg_streming","disabled":false,"info":""},{"id":"2e754e61.560a52","type":"debug","z":"5b126518.b3359c","name":"","active":true,"console":"false","complete":"false","x":550,"y":60,"wires":[]},{"id":"343fc213.65c74e","type":"file","z":"5b126518.b3359c","name":"Camera Capture","filename":"capture.jpg","appendNewline":false,"createDir":false,"overwriteFile":"true","x":560,"y":140,"wires":[[]]},{"id":"81850657.0c4598","type":"mjpg-consumer","z":"5b126518.b3359c","name":"MjpgConsumer","stream":"http://raspberrypi.local:8080/?action=stream","interval":"5","x":360,"y":100,"wires":[["2e754e61.560a52","343fc213.65c74e"]]},{"id":"1307914e.5c5d0f","type":"inject","z":"5b126518.b3359c","name":"Stop Consumer","topic":"","payload":"stop","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":"","x":160,"y":140,"wires":[["81850657.0c4598"]]},{"id":"d30efe8.65f4f","type":"inject","z":"5b126518.b3359c","name":"Start Consumer","topic":"","payload":"start","payloadType":"str","repeat":"","crontab":"","once":true,"onceDelay":"","x":160,"y":60,"wires":[["81850657.0c4598"]]}]

ペーストの作業は、画面右上の【三】をクリックし、メニューから【読み込み】→【クリップボード】を選択してクリックを行います。●

f:id:ueponx:20191009094603p:plain

【フローをクリップボードから読み込み】というダイアログが開くので、先ほどのJSON形式のテキストをコピー&ペースト、【読み込み先】を新規のタブに変更、【読み込み】ボタンをクリックします。

f:id:ueponx:20191009094914p:plain

すると新しいフローが生成されて以下のようなフローが表示されます。

f:id:ueponx:20191009095009p:plain

拡大するとこんな感じです。(あんまり拡大になってませんが、文字は読みやすくなったと思います)

f:id:ueponx:20191009095034p:plain

各ノードはこんな感じの設定になっています。

Start Consumerのinjectノードは【ペイロード】にstartを設定しています。

f:id:ueponx:20191009095526p:plain

Stop Consumerのinjectノードは【ペイロード】にstopを設定しています。

f:id:ueponx:20191009095547p:plain

MjpgConsumerのmjpg-consumerノードは【Stream】にhttp://raspberrypi.local:8080/?action=stream、【Streaming Interval】は5(秒)を設定してます。mjpg_streamは起動して、http://raspberrypi.local:8080/?action=streamにアクセスするとカメラで撮影した画像が表示され、startを送ると撮影開始し、stopを送ると撮影を停止する機能を持っています。

f:id:ueponx:20191009095451p:plain

debugノードは特に変更はありません。

f:id:ueponx:20191009095643p:plain

Camera Capturefileのfileードは【ファイル名】をcaputure.jpgに設定しています。

f:id:ueponx:20191009095612p:plain

とりあえず、そのまま【デプロイ】ボタンを押して実行してみます。(スタートを指定しなくても5秒間隔で動作します) そして、デバッグのタブを覗いてみると…

f:id:ueponx:20191009095234p:plain

undefined?うまく動作してないようです。なぜだ

うまくいかない?

ググってもなかなか情報が得られないのでいろいろ試したら、割とあっさり理由がわかりました。 Node-REDからこの拡張ノードを使用した場合でもmjpg_streamを起動してはくれないようです…原因は簡単でしたが、そこまで至るのに時間かかり過ぎた。

ということで、この拡張ノードを使用する際は起動時にサービスとしてmjpg_streamを起動しておくか、事前に起動する必要があります。 自分は面倒なので、起動スクリプトと終了スクリプトを書いて、事前に起動することにしました。(RaspberryPi2では結構負荷が高いので) スクリプトには実行権限をつけておきましょう。

起動時の実行に関してはrc.localに入れる方法やSupervisorを使用もあると思いますが、からあげさんのエントリーが参考になると思います。

qiita.com

【起動スクリプト

#!/bin/sh

# mjpg-streamer start script
export LD_LIBRARY_PATH=/usr/local/lib/mjpg_streamer
STREAMER="/usr/local/bin/mjpg_streamer"
 
# Pi camera configurations
XRES="640"
YRES="480"
FPS="10"

# Web configurations
WWWDOC="/usr/local/share/mjpg-streamer/www"
PORT="8080"

# Start streaming
$STREAMER \
-i "input_raspicam.so -x $XRES -y $YRES -fps $FPS" \
-o "output_http.so -w $WWWDOC -p $PORT"

【停止スクリプト

#!/bin/bash

if pgrep mjpg_streamer
then
    kill $(pgrep mjpg_streamer) > /dev/null 2>&1
    echo "mjpg_streamer stopped"
else
    echo "mjpg_streamer not running"
fi

起動するタイミングは事前でも、Node-RED作業後でもよいので、起動スクリプトを実行しておけば動作します。 Node-REDからフローを実行するとカレントパスにcapture.jpgが保存されます。dubugノードからの表示はデータ配列の形なので以下の画面のような表示になります。

f:id:ueponx:20191009230747p:plain

今回はpiユーザのhomeディレクトリで実行していたので以下のようになります。

f:id:ueponx:20191009230837p:plain

もし、ターミナルからの都度のmjpg_streamが面倒であれば、Node-REDのexecノードを使用しても良いかもしれません。

f:id:ueponx:20191009231308p:plain

injectノードとexecノードを使用してこんな風に起動させることで起動忘れを防ぐ事もできると思います。

f:id:ueponx:20191009234342p:plain

f:id:ueponx:20191009235047p:plain

おわりに

これでmjpg_streamを使用して、動画っぽいデータを取得できました。 だた、以前使用したcamerapiなどの拡張ノードでも同じことできるような気がしますが、違いはWebサービスとして公開が同時にできつつ、画像を処理することができる点かなと思います。使いどころは難しいかもしれませんが。

とりあえずうまく動いたということで。ググってもNode-REDとmjpg_streamノードの組み合わせの日本語の情報が少なかったので書いてみたというエントリーでした。

【今回のフロー】

[
    {
        "id": "1a4b6256.e141ce",
        "type": "tab",
        "label": "mjpg_streming",
        "disabled": false,
        "info": ""
    },
    {
        "id": "ff084c2e.c225a",
        "type": "debug",
        "z": "1a4b6256.e141ce",
        "name": "",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "payload",
        "targetType": "msg",
        "x": 550,
        "y": 60,
        "wires": []
    },
    {
        "id": "765a06f7.6ca7e8",
        "type": "file",
        "z": "1a4b6256.e141ce",
        "name": "Camera Capture",
        "filename": "capture.jpg",
        "appendNewline": false,
        "createDir": false,
        "overwriteFile": "true",
        "x": 560,
        "y": 140,
        "wires": [
            []
        ]
    },
    {
        "id": "46e883a0.2e335c",
        "type": "mjpg-consumer",
        "z": "1a4b6256.e141ce",
        "name": "MjpgConsumer",
        "stream": "http://raspberrypi.local:8080/?action=stream",
        "interval": "5",
        "x": 360,
        "y": 100,
        "wires": [
            [
                "ff084c2e.c225a",
                "765a06f7.6ca7e8"
            ]
        ]
    },
    {
        "id": "309b4801.230ef8",
        "type": "inject",
        "z": "1a4b6256.e141ce",
        "name": "Stop Consumer",
        "topic": "",
        "payload": "stop",
        "payloadType": "str",
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": "",
        "x": 160,
        "y": 140,
        "wires": [
            [
                "46e883a0.2e335c"
            ]
        ]
    },
    {
        "id": "9577ebc6.72bee8",
        "type": "inject",
        "z": "1a4b6256.e141ce",
        "name": "Start Consumer",
        "topic": "",
        "payload": "start",
        "payloadType": "str",
        "repeat": "",
        "crontab": "",
        "once": true,
        "onceDelay": "",
        "x": 160,
        "y": 60,
        "wires": [
            [
                "46e883a0.2e335c"
            ]
        ]
    },
    {
        "id": "aa22e1d5.e6c6",
        "type": "exec",
        "z": "1a4b6256.e141ce",
        "command": "./mjpg-streamer/start_mjpg_streamer.sh",
        "addpay": true,
        "append": "",
        "useSpawn": "false",
        "timer": "",
        "oldrc": false,
        "name": "",
        "x": 440,
        "y": 200,
        "wires": [
            [],
            [],
            []
        ]
    },
    {
        "id": "d141f688.7d0d28",
        "type": "inject",
        "z": "1a4b6256.e141ce",
        "name": "Start",
        "topic": "",
        "payload": "",
        "payloadType": "date",
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "x": 130,
        "y": 200,
        "wires": [
            [
                "aa22e1d5.e6c6"
            ]
        ]
    }
]

【参考】

uepon.hatenadiary.com

【RaspberryPi】Node-Redでカメラを使用する(Cameraモジュール・USBカメラ)

RaspberryPiを使ってGPIOを操作することができるようになったので、今度はカメラを接続して見たいと思います。 カメラもRaspberryPiに端子の用意されたものと、USB接続の2タイプがあるのでそれぞれについても試してみたいと思います。

Raspberry Pi Cameraモジュール編

検索すると良い情報が結構あると思います。このエントリーをみていくことで問題なく進めていけるかなと思います。

【参考】

qiita.com

RaspberryPiのカメラといえば、直接リボンケーブルで接続できるカメラモジュールが挙げられます。最近本当に安くなっているので、カメラモジュールだけではなくケース込みでもかなり安く入手できるのがメリットだと思います。以前はもっと高価だったんですけどね…。

自分が買ったときには、カメラモジュールとケーブルのみでしたが、今購入するのであればケース付きのものをおすすめします。

では、使ってみましょう。

カメラモジュールを認識させる

RaspberryPiでカメラモジュールを使用するには、設定が必要になります。といってもraspi-configでカメラを有効化させるだけです。

以下のコマンドを入力して操作していきます。

$ sudo raspi-config

メニュー画面になったら…

f:id:ueponx:20191001083709p:plain

5 Interfacing Optionsを選択して【Enter】キーを押下。

f:id:ueponx:20191001083712p:plain

P1 Cameraを選択して【Enter】キーを押下。

f:id:ueponx:20191001083715p:plain

カメラインターフェースの有効化を尋ねられるので

f:id:ueponx:20191001083717p:plain

<Yes>を選択して【Enter】キーを押下。

f:id:ueponx:20191001083720p:plain

これでカメラインターフェースが有効化されました。【Enter】キーを押下してメニューに戻ります。

f:id:ueponx:20191001083722p:plain

メニューに戻ったら<Finish>を選択して【Enter】キーを押下します。

f:id:ueponx:20191001083726p:plain

再起動するかを尋ねられるので<Yes>を選択して【Enter】キーを押下して再起動を行います。

f:id:ueponx:20191001083728p:plain

再起動が完了するとカメラモジュールが使用できるようになっています。 以下のコマンドで撮影ができているか確認しましょう。

$ raspistill -o image.jpg

エラーが発生せず、カレントディレクトリにimage.jpgファイルが生成されていれば大丈夫です。

f:id:ueponx:20191001083731p:plain

Node-REDからカメラモジュールを使用する

ここまでできたら、次はNode-REDから制御を行ってみましょう。Node-REDからこのカメラモジュールを操作するには、拡張ノードが必要になってきます。 今回は以下のノードをNode-REDから導入してみます。

flows.nodered.org

Node-REDをWebブラウザで開き、右上にある【三】のボタンをクリックしてメニューを開き

f:id:ueponx:20191002075553p:plain

メニューの中から【パレットの管理】をクリックします。

f:id:ueponx:20191002075556p:plain

すると、【ユーザ設定】の【パレット】が開き【現在のノード】の画面が表示されます。この画面の【ノードの追加】タブをクリックします。

f:id:ueponx:20191002075558p:plain

追加するノードの検索画面が開きます。

f:id:ueponx:20191002075601p:plain

検索のテキストボックスに今回の拡張ノード名を入力すると、該当するノードが検索され、リストに候補が表示されます。 今回はcamerapiという名前の含まれているノードなので、これを入力します。 検索されたノードからインストールするノードの名前を確認して、【ノードの追加】ボタンをクリックします。

f:id:ueponx:20191002075604p:plain

クリック後、インストール確認のダイアログが表示されるので【追加】ボタンをクリックします。

f:id:ueponx:20191002075607p:plain

すると、インストールの作業が行われ、

f:id:ueponx:20191002075609p:plain

拡張ノードがパレット(ノードのリスト)に追加されます。あー画面の左側のノードのリストはパレットっていうのか…今更だ…。あとで他のエントリーも修正しておこうと思います。

f:id:ueponx:20191002075612p:plain

では今回インストールされたノードを確認してみます。【RaspberryPi】グループに【camerapi takephoto】が追加されているのがわかります。

f:id:ueponx:20191002075618p:plain

では、今回導入したこのノードを試してみたいと思います。 ワークスペースに以下のノードを追加します。

  • injectノード
  • camerapi takephotoノード
  • debugノード

以下のように配置し、

f:id:ueponx:20191002075626p:plain

各端子を接続していきます。

f:id:ueponx:20191002075629p:plain

あとは、camerapi takephotoノードを設定していきます。ノードをダブルクリックしてプロパティ画面を開きます。 ここで設定できることは以下となります。

  • ファイル名の設定(File Mode)
  • 画像の解像度(Image Resolution)
  • 画像の角度の変更(Rotation)
  • 画像の上下左右の反転(Image Flip)
  • 画質のプロパティ設定(Image Properties)
  • エフェクト(Image Effect)
  • ISO感度(ISO)
  • 露出・ホワイトバランス(Preset modes)
  • AGCの調整(Wait for AGC
  • LEDの点灯・消灯(LED)

f:id:ueponx:20191002075631p:plain

細かい設定に関してはそれぞれ試してもらえればと思いますが、画像の解像度(サイズ)は大きくても仕方ないので、今回は 【ImageResolution】のプルダウンから【640x480】を選択し、完了ボタンをクリックします。

f:id:ueponx:20191002075635p:plain

あとは、【デプロイ】ボタンをクリックします。

f:id:ueponx:20191002075638p:plain

デプロイが成功しましたという表示がでればOKです。

f:id:ueponx:20191002075643p:plain

あとはinjectノードをクリックして実行します。

f:id:ueponx:20191002075645p:plain

カメラによるキャプチャが成功すると、デバッグのタブに

f:id:ueponx:20191002075652p:plain

実際にファイルがあるかコンソールから確認すると

f:id:ueponx:20191002075649p:plain

ちゃんとカメラの映像が入っています。

USBカメラ編

先ほどはRaspberryPiのカメラインターフェースに接続するモジュールでしたが、次はUSB接続のカメラをNode-REDから操作してみたいと思います。 Node-REDで使用できるUSBカメラの拡張ノードは調べてみるといくつかあります。

flows.nodered.org

flows.nodered.org ↑の拡張ノードは使用できないようです(20191008現在Node-RED 0.20.7でインストールに失敗します)

flows.nodered.org

まだまだあるかなとは思いますが、今回はこの中からnode-red-contrib-usbcameraを使用してみたいと思います。

node-red-contrib-usbcameraを使用してみる

今回使用したUSBカメラは以下のものです。カメラ自体は古いものなのですが、最新のUSBカメラものでもほとんど同じように使用することはできるかなと思います。

以前使用したときのエントリーはこちらになります。 uepon.hatenadiary.com

www.logicool.co.jp

まずはUSBカメラをRaspberryPiのUSBコネクタに接続します。すると以下のようになります。

【認識前】

$ lsusb 
Bus 001 Device 004: ID 056e:4008 Elecom Co., Ltd 
Bus 001 Device 003: ID 0424:ec00 Standard Microsystems Corp. SMSC9512/9514 Fast Ethernet Adapter
Bus 001 Device 002: ID 0424:9514 Standard Microsystems Corp. SMC9514 Hub
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

【認識後】

$ lsusb 
Bus 001 Device 004: ID 056e:4008 Elecom Co., Ltd 
Bus 001 Device 005: ID 046d:082c Logitech, Inc. 
Bus 001 Device 003: ID 0424:ec00 Standard Microsystems Corp. SMSC9512/9514 Fast Ethernet Adapter
Bus 001 Device 002: ID 0424:9514 Standard Microsystems Corp. SMC9514 Hub
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

Bus 001 Device 005: ID 046d:082c Logitech, Inc.がUSBカメラの認識部分になっています。

【画面】

f:id:ueponx:20191007080935p:plain

拡張ノードのインストール

カメラが認識できたら、拡張ノードをインストールするのですが、事前に準備が必要になります。そこからはじめて行きます。

拡張ノードのインストールの事前準備(追加インストールするパッケージ)

拡張ノードのページをみるとこのノードはfswebcamコマンドを呼び出して実行をするようです。拡張ノードはfswebcamパッケージがインストールされていない場合でもエラーは発生しません。ただし、拡張ノード実行時にはエラーします。

fswebcamパッケージがインストールされていない場合のエラー画面】

f:id:ueponx:20191007081017p:plain

拡張ノードの説明では、以下のように書かれているので

You have to install fswebcam by following command.

$sudo apt install fswebcam

このコマンドを実行してパケージのインストールを行います。

f:id:ueponx:20191007081014p:plain

すんなりとインストールできました。

拡張ノードのインストール

事前準備ができたので、拡張ノードのインストールを行っていきます。

画面の右上側にある【三】ボタンをクリックし、メニューの中から【パレットの管理】を選択しクリックをします。

f:id:ueponx:20191007080939p:plain

【ユーザ設定】が表示されたら

f:id:ueponx:20191007080942p:plain

【ノードを追加】のタブをクリックします。

f:id:ueponx:20191007080946p:plain

検索のテキストボックスにusbcameraを入力すると、拡張ノードが検出されます。 検出された拡張ノードの【ノードの追加】ボタンをクリックします。

f:id:ueponx:20191008075801p:plain

インストールの確認が表示されるので【追加】ボタンを押します。

f:id:ueponx:20191007080951p:plain

するとインストール処理がスタートし

f:id:ueponx:20191007080955p:plain

少しするとインストールが完了の表示がされます。【閉じる】ボタンを押して【ユーザ設定】を閉じます。

f:id:ueponx:20191007080959p:plain

インストールされた拡張ノードは【RaspberryPi】カテゴリーの中に【usbcamera】という形で組み込まれます。

f:id:ueponx:20191007081005p:plain

では、先程同様にテストをやってみましょう。以下のノードをワークスペースに配置していきます。

  • injectノード(配置すると名称がタイムスタンプになる)
  • usbcameraノード
  • debugノード

f:id:ueponx:20191007081008p:plain

ノードを配置したら、端子の接続を行っていきます。これで準備は完了です。あとはusbcameraノードのプロパティ設定を行っていくことになります。

f:id:ueponx:20191007081028p:plain

usbcameraノードをダブルクリックしてプロパティを開くと3つのモードを選択することができます。

f:id:ueponx:20191007081011p:plain

File Modeのプルダウンから選択することができるようになっています。BufferFile ModeGenerateというモードがありここから選んでいくことになります。

f:id:ueponx:20191007081023p:plain

モード設定

Bufferのプロパティ画面

Bufferはカメラが撮影した画像をデータの配列として取得することができるモードになります。後続の処理がファイル操作ではなく、データ配列のだった場合に使用できます。ファイル化するオーバーヘッドも大きい(SDメモリにファイルを書き込むので結構処理は遅くなります)ので可能であれば、こちらを使用するのはありだと思います。(デバッグは難しいかもしれませんが)

以下の設定値があります。

  • File Mode(Buffer)
  • Image Resolution(画像サイズ)

f:id:ueponx:20191007081020p:plain

File Modeのプロパティ画面

File Modeはカメラが撮影した画像をファイルとして取得することができます。ただし、ファイル名は固定になります。(この処理の前にファイル名を生成することができれば可変のファイル名で保存も可能です)あと、保存するパスや画像フォーマットなども変更できるのがポイントです。PNGなどの画像ファイルを使用したい場合にはこちらで行うしかないかなと思います。

以下の設定値があります。

  • File Mode(File Mode)
  • File Name(ファイル名)
  • File Default Path(保存するディレクトリ、パス)
  • File Format(保存する画像のフォーマット。PNGやJPGなど)
  • Image Resolution(画像サイズ)

f:id:ueponx:20191007081011p:plain

Generateのプロパティ画面

Generateは自動的にファイル名を生成して、カメラが撮影した画像を保存するモードです。画像サイズは変更できるのですが、JPG形式でしかできないのがちょっと物足りない感じです。ただ、学習電通データとして何枚も何枚も画像を生成する場合には便利だと思います。

以下の設定値があります。

  • File Mode(Generate)
  • File Default Path(保存するディレクトリ、パス)
  • Image Resolution(画像サイズ)

f:id:ueponx:20191007081025p:plain

実行させてみる!

あとは実行させてみます。injectノードの左側のボタンをクリックするとこんな感じになります。

Bufferモードでの実行】 f:id:ueponx:20191008075145p:plain

実行すると、デバッグ表示には配列データが出力されます。

Generateモードでの実行】

f:id:ueponx:20191007081030p:plain

実行すると、デバッグ表示には出力されたがファイルパスが出力されます。

おわりに

カメラも使えるようになったぜーって感じなんですが、 なんと2019年9月30日にNode-REDのバージョンが1.0になりました!パチパチパチ nodered.org

ちょっとどうなっちゃうのかっていうのが気になるところではありますが、次回もなにかできるといいなと思っています。

【Node-RED 参考エントリ-】

uepon.hatenadiary.com

uepon.hatenadiary.com

uepon.hatenadiary.com

uepon.hatenadiary.com

uepon.hatenadiary.com

uepon.hatenadiary.com

uepon.hatenadiary.com

【RaspberryPi】Node-REDでGPIOを使ってみる!

ようやくNode-REDを使ってRaspberryPiGPIOを操作したいと思います。 これまでやってきたことは、RaspberryPiでなくてもできますが、GPIOの使用に関しては少し特徴的な操作になるかなと思います。

これがやりたかった…

RaspberryPiにインストールしたNode-REDに含まれる特有のノード

f:id:ueponx:20190925074550p:plain

RaspberryPiNode-REDをインストールすると特有のノードも一緒にインストールされます。(バージョンによって入ってない場合もありますが、別途拡張ノードとしてインストールすることはできます)

rpiでノード検索のフィルタすると4つのノードが表示されます。

f:id:ueponx:20190925074552p:plain

表示されるのは以下の4つになります。

  • rpi-gpio(入力)
  • rpi-gpio(出力)
  • rpi-mouse(入力)
  • rpi-keyboard(入力)

mousekeyboardRaspberryPiのUSBに接続されたマウスやキーボードを入力として扱えるノードとなります。 今回はとりあえずLチカをしたいのでrpi-gpio(出力)を使います。

f:id:ueponx:20190925074555p:plain

ノードを選択して、ワークスペースにドロップします。すると名称がPINに変更されます。

f:id:ueponx:20190925074558p:plain

次にダブルクリックしてノードのプロパティを開きます。すると、以下の様なGPIOのピン一覧が表示されます。 最近老眼になってしまったので、こういうふうにコーディング時に表示されているととてもわかりやすい、便利です!

f:id:ueponx:20190925074600p:plain

今回はGPIO-04 7を使用することにします。ラジオボタンの該当の位置をクリックして選択しておきます。また出力もデジタル出力のままにしておきます。 端子の状態は今回は設定していませんが、端子の状態を初期化にチェックしておいたほうが無難だと思います。

設定が終わったら【完了】ボタンをクリックします。

f:id:ueponx:20190925074824p:plain

するとノードはGPIOのPIN設定が反映されて【PIN:7】と表示されます。

f:id:ueponx:20190925074710p:plain

ワークスペースは以下のようになっていると思います。あとは実行に必要になるノードを追加していくことになります。

f:id:ueponx:20190925074713p:plain

GPIOの入力のノードを使用してもいいのですが、もっと簡単に試すならinjectノードを使用するほうが楽に試すことができます。 ノードからinjectノードを選択し、ワークスペースに2つドロップします。

f:id:ueponx:20190925074715p:plain

ワークスペースに2つノードをドロップし、

f:id:ueponx:20190925074719p:plain

つづいて、実行結果をGPIO以外でも表示できるようにdebugノードを配置します。

f:id:ueponx:20190925074721p:plain

以下のようにGPIOのoutputノード```の下辺りに配置しておきます。

f:id:ueponx:20190925074724p:plain

これで必要なノードの配置が終わりました。あとは、これらのノードの端子を接続していきます。以下のように接続します。

f:id:ueponx:20190925074741p:plain

あとはそれぞれのノードのプロパティを設定していきます。入力となるinjectノードGPIOノード数値01入力するので、

f:id:ueponx:20190925074744p:plain

まずペイロードのプルダウンを数値と変更して、

f:id:ueponx:20190925074746p:plain

その値に0を入力します。設定が終わったら【完了】ボタンをクリックします。

f:id:ueponx:20190925074750p:plain

もう一方のinjectノードは同じように操作し、値は1として設定し、【完了】ボタンをクリックします。

f:id:ueponx:20190925074753p:plain

フローを見たときにノードの状態が以下のようになっていればOKです。

f:id:ueponx:20190925074756p:plain

これで実行時にinjectノードをクリックすれば設定した数値が入力されるようになります。ここまでできたら【デプロイ】ボタンをクリックします。 これで準備完了です。

実行してみる

デプロイが成功したら、早速動作させてみましょう!

f:id:ueponx:20190925074811p:plain

0を出力するinjectノードをクリックすると以下の様に表示されます。するとそれまでGPIOノードの下あたりにある表示がOKだったものが0と表示が変わります。

f:id:ueponx:20190925074814p:plain

では、続いて1を出力するinjectノードをクリックすると、以下のように表示され、GPIOの下にある表示が1に変化します。

f:id:ueponx:20190925074817p:plain

デバックの表示も同様に表示しています。

f:id:ueponx:20190925074828p:plain

ソフト的には動作することがわかったのであとはLEDをRaspberryPiGPIO7に接続してOKであることを確認します。

RaspberryPiにLEDを接続する

先程のプログラムを動作させるために、回路を以下の様に作ってみます。

必要になるものとしては

  • 330Ωの抵抗 1本
  • LED 1個
  • ブレッドボード
  • ブレッドボード用ジャンパーワイヤ2本

といったところです。これで以下のように組み立ててました。

f:id:ueponx:20190928074744p:plain

実際にinjectノードを【1】の方をクリックすると点灯

f:id:ueponx:20190928101829j:plain

【0】の方をクリックすると消灯

f:id:ueponx:20190928101856j:plain

無事に動作しているようです。 ようやく自分がNode-REDでやりたかったことが達成できました!

injectノードの代わりにrpi-mouseを使用してみる

このまま終わっても良いのですが、もう少し別の機能も試してみたいと思います。 RaspberryPiの関連ノードでrpi-mouseを使用して、これをinjectノードの入力の代わりにしてみましょう。 ノードの一覧からrpi-mouseを選択し、

f:id:ueponx:20190928110828p:plain

ワークスペースにドロップして配置します。

f:id:ueponx:20190928110935p:plain

自分はこんな風にドロップしてみました。ノードの名称はドロップがされた段階でPi Mouse Leftという名称に変更されて、マウスの左ボタンの押下(1が出力)解放(0が出力)に紐付けられます。

f:id:ueponx:20190928111214p:plain

ノードをダブルクリックするとその様子も確認できます。

f:id:ueponx:20190928111012p:plain

後は、このノードを先程まで使用していたrpi-gpio出力ノードdebugノードの端子に紐付けます。

f:id:ueponx:20190928111345p:plain

後は【デプロイ】ボタンをクリックします。あとは実行をさせてみます。

f:id:ueponx:20190928111518p:plain

マウスボタンを押し込むとLEDが点灯し、マウスのボタンから指を離すと消灯します。これでマウスをスイッチのように使用する事ができるようになりました。

おわりに

ようやくNode-REDを使用してLEDの点灯(Lチカ)を行うことができるようになりました。操作などから学んできましたがようやくという感じでしょうか。

ただ、Node-REDGPIOの割当がGUIベースでわかりやすいのは非常に良い機能だなと思いました。あとは、他の機能などと連携させるとロジックの根幹を 作るにはいいプロダクトかなと思います。今後は拡張ノードも多くでているのでそれらをもう少し調べながら使ってみようと考えています。 次はカメラでしょうか?

【Node-RED 関連エントリ-】

uepon.hatenadiary.com

uepon.hatenadiary.com

uepon.hatenadiary.com

uepon.hatenadiary.com

uepon.hatenadiary.com

uepon.hatenadiary.com

uepon.hatenadiary.com

【RaspberryPi】Node-REDでWebアクセス(クライアント)追記

前回のエントリーを公開後にコメントを頂いたので、それについて調べてみました。

指摘いただいたのは以下の2点

  • アクセス先がhttpsなので、「SSL/TLS認証の有効化」で、証明書の確認をしたほうが安全です。そのままでもアクセスはできますがサーバ証明書の確認をしてくれませんので、中間者攻撃に対応できません。
  • http-requestノードの後にJSONノードをつけてオブジェクトに変換されていますが、http-requestノード自体にその機能があります。アクセスエラー時には文字列になりますが、それはJSONノードでも同じなので、ノードの数が減らせます。

それぞれについてやってみます。

【参考】 uepon.hatenadiary.com

SSL/TLS認証の有効化する

まずは、SSL/TLS認証の有効化を行ってみます。

http requestノードをダブルクリックして、プロパティ編集画面に入ります。 まずは、【SSL/TLS認証の有効化】のプロパティにチェックボックスをチェックをいれてます。

f:id:ueponx:20190923081928p:plain

続いてその下にある【TLS設定】のプルダウンを【新規にtls-configに追加…】になっていることを確認し、右にある【鉛筆のアイコン】(編集)のボタンをクリックします。

f:id:ueponx:20190922074314p:plain

クリックすると、【tls-configノードを編集】画面が表示されるので、【サーバ証明書を確認】のチェックボックスにチェックを入れて、【更新】ボタンをクリックします。

f:id:ueponx:20190922074303p:plain

変更後は【TLS設定】のプルダウンがTLS設定に値が変更されています。あとは【完了】ボタンをクリックすれば、サーバ証明書の確認を行ってくれるようになります。サーバのURLに入っている、確認するサーバが異なる場合には【サーバー名】のプロパティSNIの記述をすれば設定も可能です。

f:id:ueponx:20190922074732p:plain

これで安全性が上げることができました。

http requestノードから直接JSONオブジェクトを出力する

以前作成したものはデータをhttp requestノードで取得してからJSONノードで変換してアクセス時のデータをJSONオブジェクトとして取得するというものでした。http requestノードの設定を変更すれば、このノードのみでJSONオブジェクトを取得できるようです。

http requestノードをダブルクリックして、プロパティ編集画面に入ります。 【出力形式】のプロパティのプルダウンをクリックをして、【UTF-8文字列(デフォルト値)】から【JSONオブジェクト】に変更します。

f:id:ueponx:20190922074307p:plain

これで設定は完了です。設定を変更したら【完了】ボタンを押します。

ちなみに注釈にもありますが、JSONデータとしてパースができない場合には文字列としてノードから出力されるとのことです。

f:id:ueponx:20190922074310p:plain

後続のJSONノードはこれで減らす事ができます。フローの変更後は忘れずに【デプロイ】ボタンをクリックしましょう。 これでフローはスッキリしますね。

終わりに

さらなる情報を頂きました…

flows.nodered.org

パタリ…すでにカスタムノードがあったとは…

【Node-RED 関連エントリ-】

uepon.hatenadiary.com

uepon.hatenadiary.com

uepon.hatenadiary.com

uepon.hatenadiary.com

uepon.hatenadiary.com

uepon.hatenadiary.com

uepon.hatenadiary.com

【RaspberryPi】Node-REDでWebアクセス(クライアント)後半

Webアクセスの処理も後半となります。前回はHTTP経由でのCSVファイルのダウンロードを行っていましたが、今回は一般的なWebAPIへアクセスして見ようと思います。

【関連】

【RaspberryPi】Node-REDでWebアクセス(クライアント)前半 - uepon日々の備忘録

WebAPIへのアクセスを行う

今回は比較的アクセスが簡単なwaht3wordsというサービスのAPIを使用してみたいと思います。

what3wrodsの登録をする

what3words.com

waht3wordWikipediaによれば…

what3words(ワットスリーワーズ)は、3メートルの解像度で場所を伝達するためのジオコーディングシステムである。what3wordsでは、地理的座標を3つの単語で符号化する。例えば、自由の女神像の持つ松明の位置は、"toned.melt.ship"の3語で表している。従来のほかの位置エンコードシステムとの違いは、長い文字(たとえば住所)や数字(たとえば経緯度)ではなく、3つの単語で簡単に表される点にある。

ja.wikipedia.org

ってことのようです。簡単に言えば住所などの表記が長くなりがちなので、3つの言葉の組み合わせで表現しましょうというものです。

what3wordsユーザー登録をする

まず、WebAPIを使用するにはAPI-Keyが必要になるので、そのためのユーザー登録を行います。 ユーザ登録するために、こちらのURLにアクセスします。 すると以下のような画面が表示されます。

f:id:ueponx:20190916074920p:plain

画面右上にあるハンバーガーボタンをクリックし、ユーザー登録の作業をすすめます。

登録はFacebookgoogleのアカウントと連携することで行うことができるので、今回はFacebookのユーザIDとのアカウント連携をすすめてみます。 【Facebookで続行】のボタンをクリックします。

f:id:ueponx:20190916092105p:plain

ボタンをクリックすると確認のダイアログが表示されるので【中央にある青いボタン】をクリックします。 アカウント作成の画面に遷移します。

f:id:ueponx:20190916094448p:plain

この中で、氏名などの情報を入力し、プライバシーポリシーの同意のチェックボックスにチェックを入れます。このチェックを入れないと【続行】ボタンがアクティブになりませんので、必ず行ってください。(アクティブになるとボタン化赤く変化します。)

f:id:ueponx:20190916095212p:plain

【続行】ボタンをクリックするとユーザー登録は完了して以下のような画面になります。

f:id:ueponx:20190916095302p:plain

これでユーザー登録は完了です。

API KEYの取得

つづいてAPIのアクセスに必要なAPI-KEYを取得します。ログインが終わったら上の方にあるメニューバーの【Developer】をクリックします。

f:id:ueponx:20190916095606p:plain

すると以下のような画面に遷移します。このページはAPIの説明とGet Startedというチュートリアルがあるのでそれを見ていくことになります。

f:id:ueponx:20190916094816p:plain

画面内のGet Startedの中にある【1.Get your free API key】のリンクをクリックします。

f:id:ueponx:20190916075010p:plain

すると、以下のようなデベロッパーページが表示されます。左側のペインにある【デベロッパAPIキー】をクリックします。

f:id:ueponx:20190916075014p:plain

すると画面右側に【APIキーの作成】が表示されるのでクリックします。

f:id:ueponx:20190916075025p:plain

APIキーの作成に関するライセンス確認のダイアログが表示されるので

f:id:ueponx:20190916075030p:plain

同意のチェックボックスにチェックを入れて、【続行】ボタンをクリックします。

f:id:ueponx:20190916075037p:plain

続いてはAPIキーを発行するアプリの作成を行います。アプリの【名前】と【ディスクリプション】(説明)を入力して【APIキーの作成】ボタンをクリックします。

この例では以下のように設定しています。

  • 名前:ueponAPP
  • ディスクリプション:API test

f:id:ueponx:20190916075044p:plain

すると、デベロッパAPIキーが表示されます。ここで表示されたAPIキーを後程使用するのでメモしておきます。

f:id:ueponx:20190916075050p:plain

これで開発の準備ができました。先ほどのDeveloperページのGet Startedに戻ります。

今回は緯度経度から3つのワードでできた住所を調べたいので【Coordinates => 3 word address】の欄にあるリンクをコピーします。

f:id:ueponx:20190916075058p:plain

コピーすると以下のようなリンクアドレスが取得できます。ここで[API-KEY]となっている部分を先ほど生成しておいたAPI-KEYに変更します。

https://api.what3words.com/v3/convert-to-3wa?coordinates=51.521251%2C-0.203586&key=[API-KEY]

このリンクアドレスにブラウザなどからアクセスすると以下のようなJSONデータ返されます。 この中でwordsの値がindex.home.raftとなっているのがわかるかと思います。これが取得された3 word Addressとなります。

f:id:ueponx:20190916075110p:plain

値が英語の単語になっていますが、これはデフォルトが英語になっているので、クエリで言語を設定すれば日本語にすることもできます。

リンクアドレスの末尾に&language=jaに追加すれば大丈夫です。

https://api.what3words.com/v3/convert-to-3wa?coordinates=51.521251%2C-0.203586&key=[API-KEY]&language=ja

改めてこのリンクアドレスにアクセスすると以下のようになります。

f:id:ueponx:20190916081434p:plain

日本語の場合にはていせい・ゆとり・しゅふという3つの単語が帰ってきます。

これでAPIの準備はOKです。

Node-REDからアクセスを行う

今度はNode-REDからこのAPIにアクセスをしてみたいと思います。 まずは新規のフローを作成します【+】のタブをクリックします。

f:id:ueponx:20190916075134p:plain

今回使用するのは以下4つのノードになります。

  • 入力グループの【inject】ノード
  • 機能グループの【http request】ノード
  • 機能グループの【json】ノード
  • 出力グループの【debug】ノード

f:id:ueponx:20190917080229p:plain

これらのノードをワークスペースにドロップし、

f:id:ueponx:20190917080251p:plain

以下のようにノードの端子を接続していきます。

f:id:ueponx:20190917080254p:plain

後は各ノードの設定を行います。

【inject】ノードを編集する

まずは起動トリガーとなるinjectノードをダブルクリックします。

f:id:ueponx:20190917080300p:plain

ノードをドロップすると、自動的にタイムスタンプという表示になるのでそれを名前のプロパティをスタートと変更して【完了】ボタンをクリックします。

f:id:ueponx:20190917080313p:plain

【http request】ノードを編集する

続いてhttp requestノードをダブルクリックします。このノードでWebアクセスをします。

f:id:ueponx:20190917080319p:plain

編集するのはURLのプロパティです。

https://api.what3words.com/v3/convert-to-3wa?coordinates=51.521251%2C-0.203586&key=[API-KEY]

先ほど使用したリンクアドレスに編集します。[API-KEY]の部分は置き換えます。 終わったら【完了】ボタンをクリックします。

f:id:ueponx:20190917080421p:plain

json】ノードを編集する

JSONデータを処理する、jsonノードをダブルクリックします。

f:id:ueponx:20190917080432p:plain

動作のプロパティのプルダウンから【常にJavaScriptオブジェクトに変換】を選びます。ここを修正していないとWebアクセスによって得られたJSONデータが単なるString(文字列)になるので以降データの取得などを行うことを考えるならばオブジェクトに変換させておく方が便利です。

f:id:ueponx:20190917084204p:plain

【debug】ノードを編集する

最後のdebugノードで結果を表示します。debugノードをダブルクリックして

f:id:ueponx:20190917080423p:plain

対象プロパティをmsg.payload.wordsと編集します。前段のJSONから送信されたデータからwordsのキーに入っているデータを取得し、表示を行うことになります。

f:id:ueponx:20190917080439p:plain

デプロイとフローの実行

設定が終了したので上部の【デプロイ】ボタンをクリックして、デプロイ作業を行います。

f:id:ueponx:20190917080426p:plain

以下のようにデプロイが成功しましたと表示されれば成功です。

f:id:ueponx:20190917080428p:plain

後はフローの実行になります。スタートと名付けたinjectノードの左側のボタンをクリックすると実行されます。

f:id:ueponx:20190917080441p:plain

デバックタブを表示させると以下のように表示されます。先ほどと同様にindex.home.raftが表示されています。これでWebAPIへのアクセスができました。

f:id:ueponx:20190917080444p:plain

もう少し触ってみる

先ほどはリンクアドレスの言語設定を行っていなかったので、英語の3単語になっていました。 URLを変えるものいいのですが、折角なので日本語も同時にアクセスできるようにしたいと思います。

先ほど作成したフローのhttp requestノード以降をマウスで選択し、コピー&ペーストを行います。あとはスタートのノードの端子と接続を行っておきます。

f:id:ueponx:20190917080446p:plain

つづいて新規に作成したhttp requestノードをダブルクリックしてURLプロパティの末尾に&language=jaを追加して【完了】ボタンをクリックします。

f:id:ueponx:20190918200627p:plain

あとは【デプロイ】ボタンをクリックして、

f:id:ueponx:20190917080457p:plain

フローの実行を行います。

f:id:ueponx:20190917080452p:plain

すると、英語と日本語の2つの結果がデバッグ画面上に表示されます。

f:id:ueponx:20190917080454p:plain


さらにもう少し触ってみる

今はhttp requestノードのURLプロパティにクエリパラメータを入力していますが、長くなると間違える可能性があります。そこでhttp requestノードにクエリパラメータをJSON形式でデータを渡しアクセスURLに反映をさせてみようと思います。

まずはスタートのinjectノードをダブルクリックします。

f:id:ueponx:20190917081734p:plain

ペイロードプロパティのブルダウンからJSONを選択します。

f:id:ueponx:20190917081738p:plain

そして入力ボックスの右側の【…】をクリックします。

f:id:ueponx:20190917081741p:plain

するとJSONエディタが立ち上がります。ここにJSON形式でKeyとValueのセットを記述します。(この時の入力にはURLエンコードをする必要はありません➡うれしい)編集が終わったら【完了】ボタンをクリックします。

f:id:ueponx:20190917081745p:plain

先ほど編集を行ったJSON形式のデータがペイロード部分に格納されます。確認できたら【完了】ボタンをクリックします。

f:id:ueponx:20190917081747p:plain

あとは、http requestノードをダブルクリックし、URLプロパティからクエリパラメータの文字列を削除し、【msg.payloadをクエリパラメータに追加】にチェックを入れて【完了】ボタンをクリックします。

これで先ほどと同様にWebAPIにアクセスができるようになります。

f:id:ueponx:20190918200654p:plain

おわりに

これでNode-REDを使用して一般的なWebAPIへのアクセスができるようになりました。 これで一般的な機器とのHTTPでの連携ができるようになりました。サーバー側もクライアント側もできるようになったので割と広がったかなと思います。

【Node-RED 関連エントリ-】

uepon.hatenadiary.com

uepon.hatenadiary.com

uepon.hatenadiary.com

uepon.hatenadiary.com

uepon.hatenadiary.com

uepon.hatenadiary.com

uepon.hatenadiary.com

/* -----codeの行番号----- */