超音波距離センサを使用した物体変位の通知

(1)構成概要
Wio LTE(超音波距離センサ)→SORACOM Funk→AWS Lambda(Python3.8)→ Line Notify


(2)使用するハードウェア
Wio LTE JP Version
Grove - 超音波距離センサー
Grove - ブザー
SORACOM IoT SIM plan-D
Anker PowerCore 10000


(3)使用するサービス
SORACOM Func
AWS Lambda
Line Notify

(4)参考文献
公式ワークブック SORACOM実装ガイド 株式会社ソラコム著
https://qiita.com/ryo_naka/items/c433a9c362679cee3d18
https://qiita.com/tan5o/items/6c5f2bd6f3f29b1ae465

 

(5)作業概要
STEP1. 開発環境のセットアップ
・開発PCにArduino IDEインストール
・開発PCにVirtual COM Portドライバーインストール
・開発PCにWinUSBドライバーインストール
Arduino IDEにWio LTEボード定義のインストール
Arduino IDEにWio LTEライブラリのインストール
Arduino IDEにGroveDriverPackライブラリのインストール

STEP2. Wio LTEのセットアップ
・アンテナを取り付ける
・SIMを取り付ける
・超音波センサーを「D38」に接続する
・ブザーを「D20」に接続する

STEP3. スケッチの書き込み

--------------

#include <WioLTEforArduino.h>
#include <Ultrasonic.h> // https://github.com/Seeed-Studio/Grove_Ultrasonic_Ranger
#include <GroveDriverPack.h>

#define ULTRASONIC_PIN (WIOLTE_D38)
#define BUZZER_PIN (WIOLTE_D20)
#define BUZZER_ON_TIME (100)
#define BUZZER_OFF_TIME (3000)

#define RECEIVE_TIMEOUT (10000)
#define INTERVAL (1000)

Ultrasonic UltrasonicRanger(ULTRASONIC_PIN);
WioLTE Wio;

long distance = 0;
int alarm_count = 0;
int distance_count = 0;
int seconds = 0;

GroveBoard Board;

void setup()
{
delay(200);
SerialUSB.begin(115200);

Wio.Init();
Wio.PowerSupplyLTE(true);
Wio.PowerSupplyGrove(true);
delay(500);

pinMode(BUZZER_PIN, OUTPUT);
delay(500);

if (!Wio.TurnOnOrReset()) {
return;
}
if (!Wio.Activate("soracom.io", "sora", "sora")) {
return;
}
}

void sendEnvData() {
char data[1024];
snprintf(data, sizeof(data),
"{\"distance\":%d}", distance);

int connectId;
connectId = Wio.SocketOpen("uni.soracom.io", 23080, WIOLTE_UDP);
if (connectId < 0) {
delay(INTERVAL);
}
if (!Wio.SocketSend(connectId, data)) {
goto err_close;
}

int length;
length = Wio.SocketReceive(connectId, data, sizeof (data), RECEIVE_TIMEOUT);
if (length < 0) {
goto err_close;
}

if (length == 0) {
goto err_close;
}

err_close:
if (!Wio.SocketClose(connectId)) {
delay(INTERVAL);
}
}


void measure_distance()
{
distance = UltrasonicRanger.MeasureInCentimeters();
SerialUSB.println("");
SerialUSB.print(distance);
SerialUSB.println("[cm]");
}

void Buzzer_ON()
{
for(int i=0; i < 20; i=i+1) {
digitalWrite(BUZZER_PIN, HIGH);
delay(BUZZER_ON_TIME);
digitalWrite(BUZZER_PIN, LOW);
delay(BUZZER_OFF_TIME);
}
}

void loop()
{

measure_distance();
if (distance >= 12) {
distance_count += 1;
}
//変位が5回以上12cm以上になったらFuncにデータを送信し、ブザーを3秒間隔で20回鳴らす
//アラームの実行回数上限3回
if (distance_count >= 5 and alarm_count < 3) {
alarm_count += 1;
sendEnvData();
Buzzer_ON();
distance_count = 0;
}
delay(INTERVAL);

//変位の履歴は1時間に1回クリア
seconds += 1;
if (seconds >= 3600) {
seconds = 0;
}
}

--------------


STEP4. Line Notifyでアクセストークンを発行する


STEP5. AWS Lambda関数の作成
・関数の作成
ランタイム: Python 3.8
--------------
import json
import sys
import urllib.parse
import urllib.request
import datetime
import os

def lambda_handler(event, context):
print(event)

LINE_TOKEN= os.environ.get("LINE_NOTIFY_API_KEY")
LINE_NOTIFY_URL="https://notify-api.line.me/api/notify"

msg = 'distance:{}'.format(event['distance'])
print (msg)

method = "POST"
headers = {"Authorization": "Bearer %s" % LINE_TOKEN}
payload = {"message": msg}
try:
payload = urllib.parse.urlencode(payload).encode("utf-8")
req = urllib.request.Request(
url=LINE_NOTIFY_URL, data=payload, method=method, headers=headers)
urllib.request.urlopen(req)
except Exception as e:
print ("Exception Error: ", e)
sys.exit(1)

--------------

環境変数の設定
環境変数(LINE_NOTIFY_API_KEY)にLine Notifyのアクセストークンを指定する

STEP6. AWS IAMユーザの作成
アクセスの種類: プログラムによるアクセス
既存のポリシーを直接アタッチ
ポリシーの作成
--------------
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": "lambda:InvokeFunction",
"Resource": "arn:aws:lambda:ap-northeast-1:xxxxxxxxxxxx:function:soracom_test"
}
]
}
--------------

ポリシーのアタッチ
アクセスキーの取得

STEP7. SORACOM SIMグループの作成とSIMの所属設定

STEP8. SORACOM認証情報の登録
認証情報ストアにAWS IAMユーザのアクセスキーを登録する

STEP9. SORACOM Funcの設定
SIMグループでFuncを有効化し、AWS Lambda関数のARNを指定する