クリスマスの定番(?) Raspberry Pi と超音波センサーでクリスマスツリーを光らせて SORACOM Harvest Data でデータ収集

こちらは、 “ゆるWeb勉強会@札幌 Advent Calendar 2020” の 25日目の記事です。

メリークリスマス!
アドベントカレンダーも最終日のクリスマス、そしてクリスマスと言えばラズパイですよね!

ということで、 ゆるWeb勉強会@札幌 Advent Calendar 2020 の最後は、超音波センサーを使ってクリスマスツリーを光らせつつ、距離の情報を SORACOM Harvest Data で送信する仕組みを Raspberry Pi で作ってみたいと思います。

動画

まずはどのような動きになるか、動画をご覧ください。

では、どうやって作ったのか見ていきましょう。

揃えるもの

Raspberry Pi

  • Raspberry Pi 3 Model B+

超音波センサー

  • HC-SR04

上記2つは、今回は SORACOM さんのストアで購入しました。

 soracom.jp

このキットの体験ハンズオンをやった記事はこちら。

SORACOM の IoT 体験キット 〜距離測定センサー〜 のハンズオンをやってみたらとても手軽に楽しめたこちらは、 “ゆるWeb勉強会@札幌 Advent Calendar 2020” の 20日目の記事です。 最終的には25日のネタに繋がるのですが、それに向けて購入した (個人的に大好きな) SORACOM さんの体験…
続きを読む
 blog.tacck.net
SORACOM の IoT 体験キット 〜距離測定センサー〜 のハンズオンをやってみたらとても手軽に楽しめた

ツリー関係

  • 100均などで適宜購入

各自、好きなように作りましょう。

手順

Raspberry Pi やセンサーの準備など

センサーの接続や動作確認は、先ほどあげたハンズオン体験記事を参照してください。

SORACOM の IoT 体験キット 〜距離測定センサー〜 のハンズオンをやってみたらとても手軽に楽しめたこちらは、 “ゆるWeb勉強会@札幌 Advent Calendar 2020” の 20日目の記事です。 最終的には25日のネタに繋がるのですが、それに向けて購入した (個人的に大好きな) SORACOM さんの体験…
続きを読む
 blog.tacck.net
SORACOM の IoT 体験キット 〜距離測定センサー〜 のハンズオンをやってみたらとても手軽に楽しめた

ツリーの作成手順、 Raspberry Pi のセットアップ、 Node-RED のセットアップについては、アナザースタイルの記事を参照してください。

クリスマスの定番(?) Raspberry Pi と SORACOM LTE-M Button で光るクリスマスツリーを作成メリークリスマス!アドベントカレンダーも最終日のクリスマス、そしてクリスマスと言えばラズパイですよね! ということで、 North Detail Advent Calendar 2020 の最後は S
クリスマスの定番(?) Raspberry Pi と SORACOM LTE-M Button で光るクリスマスツリーを作成 www.northdetail.co.jp
クリスマスの定番(?) Raspberry Pi と SORACOM LTE-M Button で光るクリスマスツリーを作成

Node-RED のフロー実装

今回は Node-RED で実装してみました。

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

Node-RED でフローを実装。

センサーからの値(cmで取得できる)が 50cm 以下の場合に点灯、そうでない場合に消灯、というように実装しています。

送信できたデータは、 SORACOM のコンソール上にこのような形で確認できます。
(距離なので、値が小さいところで手をかざしている。)

SORACOM のコンソールで確認。

超音波センサー用のノードの実装

超音波センサーは、原理として「発射した超音波が返ってくるまでの時間」を基に距離を計算することになります。

つまり、かなり短い時間 (ミリ秒よりも小さい単位) で扱えないと良い精度が出せません。

Node-RED は Node.js (JavaScript) で動作しているので、基本はミリ秒での制御となっているように見えます。

そのため、標準のノードの組み合わせではうまく作ることができませんでした。

ということで専用のノードが必要になるので探してみたところ、下記のようなノードが公開されていました。

node-red-node-pisrfA Node-RED node for a Raspberry Pi to use a SRF04 or SRF05 range finder
node-red-node-pisrf flows.nodered.org
node-red-node-pisrf
node-red-nodes/hardware/PiSrf at master · node-red/node-red-nodesExtra nodes for Node-RED. Contribute to node-red/node-red-nodes development by creating an account on GitHub.
node-red-nodes/hardware/PiSrf at master · node-red/node-red-nodes github.com
node-red-nodes/hardware/PiSrf at master · node-red/node-red-nodes

このノードで距離を取得できたのですが、ある程度離れると情報が返ってこなくなるので「周期的に値を取得する」ということが実現できませんでした。

これができないと、「距離が離れたらライトを消灯する」ということが実現できません。

そこで、上記のノードのコードの作り方と Node-RED の公式情報を基に、 SORACOM のサンプルコード(Python) を使った自作ノードを作成して対応しました。

センサーの値を Python で取得し、 JavaScript からそのコードを呼び出してノードとして動作させる、という形です。

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import time

import RPi.GPIO as GPIO
import sys

GPIO.setmode(GPIO.BOARD)
TRIG = 11 # GPIO17
ECHO = 13 # GPIO27

GPIO.setup(TRIG,GPIO.OUT)
GPIO.setup(ECHO,GPIO.IN)
GPIO.output(TRIG, GPIO.LOW)

GPIO.output(TRIG, GPIO.HIGH)
time.sleep(0.00001)
GPIO.output(TRIG, GPIO.LOW)

signaloff = time.time()
while GPIO.input(ECHO) == GPIO.LOW:
    signaloff = time.time()

signalon = signaloff
while time.time() < signaloff + 0.1:
    if GPIO.input(ECHO) == GPIO.LOW:
        signalon = time.time()
        break

GPIO.cleanup()

timepassed = signalon - signaloff
distance = timepassed * 17000

print distance

これでセンサーから距離を取得し、標準出力へ出力するようにします。

module.exports = function (RED) {
  const execFile = require('child_process').execFile;
  const gpioCommand = __dirname + '/gpio.py';

  function Ultrasonic(config) {
    RED.nodes.createNode(this, config);
    const node = this;

    node.on('input', function (msg) {
      execFile(gpioCommand, [], (err, stdout, stderr) => {
        const strData = stdout.trim();
        if (strData.length > 0) {
          node.send({ topic: node.topic, payload: parseFloat(strData) });
        } else {
          node.send({ topic: node.topic, payload: 1000 });
        }
      })
    });
  }
  RED.nodes.registerType("node-red-ultrasonic", Ultrasonic);
}

Node.js の execFile() を使って Python のファイルを実行し、標準出力から得た結果を使ってノードの出力としています。

こういった感じで、簡単なノードであればすぐに実装できました。

ローカルでの詳しいノードの作成・追加方法は、こちらの公式ドキュメントを参考にしてください。

ノードの開発 : Node-RED日本ユーザ会 top) { if (positions[i].pos-top < windowHeight/2 ) { return positions[i].el; } else { return previous; } } previous = positions[i].el; } } function scrollWindow() { var targetItem = getCurrentItem(); if (targetItem !== currentItem) { if (currentItem) { currentItem.removeClass("active"); } currentItem = targetItem; if (currentItem) { currentItem.addClass("active"); } } } $(window).resize(resizeWindow); $(window).on("scroll",scrollWindow); setTimeout(function() { resizeWindow(); scrollWindow(); },500); }); ノードの開発 Node-REDを拡張する主な方法は、パレットに新しいノードを追加することです。
ノードの開発 : Node-RED日本ユーザ会 nodered.jp
ノードの開発 : Node-RED日本ユーザ会

Harvest への送信方法は、数値をそのままURLへ送るだけでできました。
(SORACOM の SIM を差したドングルが必要です。)

動作させる

ということで、改めて動画を確認してみてください。

うまくできましたね!

まとめ

Node-RED でのセンサーの扱いで少し苦労しましたが、このような形で対応できることがわかりました。

センサーも含め、自分で使う時に欲しいノードがあればかなり手軽に自作ノードとして対応できそうです。

色々な道具を組み合わせることで、かなり手軽に欲しい物が作れますね。

みなさんも、ぜひ色んなものを作ってみてください!

tacck
  • tacck
  • 北の大地の普通のソフトウェアエンジニア。
    インフラ・バックエンド・フロントエンドと、色々やります。

    初心者・若手向けのメンターも希望あればお受けします。

    勉強会運営中
    * ゆるWeb勉強会@札幌
    * スマートスピーカーで遊ぼう会@札幌

コメントする

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください