SORACOM IoT DIYレシピで始める工作。"画面に近づきすぎると警告してくれるロボット"を作ってみた 

## はじめに
平日の朝晩、休日、趣味でIoTの勉強や電子工作してますyoyoと申します。
10月にオンラインで開催されたSORACOM UG 2021を見ていたときに、”初心者でも大丈夫。同じ初心者のためになるからSORACOM試してアウトプットしてみよう！”って言葉がすごく印象深くて私も何か作ってみたい、アウトプットしてみようと思い、今回、AdventCalendarに登録しました。Qiita初投稿です。至らないところもあるかもしれませんが、どうか温かい目で見ていただけるとありがたいです。宜しくお願いいたします。

##概要
朝活、デスクワーク、オンライン勉強会、カフェでのプログラミング学習…。
作業に集中してるといつのまにかパソコンの画面に近寄りすぎていて、気づいたら目が疲れていることが多いなと感じます。
![Clipboard04.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/217319/42e3d6cd-dc8a-790b-14fa-1090f599b644.jpeg)
この身近な課題を解決を出来ないかと情報を探していたところ、SORACOM IoT DIYレシピで“近づくと音声で自動応答する店番ロボット”の記事を見つけました、本レシピを参考に、画面に近づきすぎたときにアラートメッセージを流してくれるロボットを作りましたので情報を共有いたします。

構成は以下になります。
![Clipboard01.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/217319/c00f6010-712f-0c94-39f5-a7ba99415d9e.jpeg)

## IoTプロトタイピング
https://soracom.jp/recipes_index/7243/

IoT DIYレシピをなぞりながら作っていきました。レシピが非常にわかりやすく、
また動画でも説明されてたので、詰まることなく非常にスムーズに作ることが出来ました。

今回、モニタ近接アラートを作るにあたってレシピと変えた点は以下になります。
1.近接判定条件
2.発話させるメッセージ
3.センサ固定部品

##1.近接判定条件変更
curlコマンドで取得したstorebot.pyを開き以下のように編集しました。
![Clipboard011.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/217319/16ff6e11-ed6d-4539-5428-df70b542d87e.jpeg)
a) MIN_DISTANCE_CM を 20から40に変更
b) 判定条件をif MIN_DISTANCE_CM >= distanceに変更

コード全体はこちら

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

MIN_DISTANCE_CM = 40
MAX_DISTANCE_CM = 200
STAY_COUNT = 5

import time
# 距離を読む関数
def read_distance():
    # 必要なライブラリのインポート・設定
    import RPi.GPIO as GPIO

    # 使用するピンの設定
    GPIO.setmode(GPIO.BOARD)
    TRIG = 11 # ボード上の11番ピン(GPIO17)
    ECHO = 13 # ボード上の13番ピン(GPIO27)

    # ピンのモードをそれぞれ出力用と入力用に設定
    GPIO.setup(TRIG,GPIO.OUT)
    GPIO.setup(ECHO,GPIO.IN)
    GPIO.output(TRIG, GPIO.LOW)

    # TRIG に短いパルスを送る
    GPIO.output(TRIG, GPIO.HIGH)
    time.sleep(0.00001)
    GPIO.output(TRIG, GPIO.LOW)

    # ECHO ピンがHIGHになるのを待つ
    signaloff = time.time()
    while GPIO.input(ECHO) == GPIO.LOW:
        signaloff = time.time()

    # ECHO ピンがLOWになるのを待つ
    signalon = signaloff
    while time.time() < signaloff + 0.1:
        if GPIO.input(ECHO) == GPIO.LOW:
            signalon = time.time()
            break

    # GPIO を初期化しておく
    GPIO.cleanup()

    # 時刻の差から、物体までの往復の時間を求め、距離を計算する
    timepassed = signalon - signaloff
    distance = timepassed * 17000

    # 500cm 以上の場合はノイズと判断する
    if distance <= 500:
        return distance
    else:
        return None

import urllib2
import json
import base64
from subprocess import Popen, PIPE
def main():
    cnt = 0
    while True:
        distance = read_distance()
        if distance:
            print "距離: %.1f cm" % distance

        if MIN_DISTANCE_CM >= distance:
#        if MIN_DISTANCE_CM <= distance and distance <= MAX_DISTANCE_CM:　#コメントアウトし条件変更
            cnt += 1
        else:
            cnt = 0
    
        if cnt > STAY_COUNT - 1:
            cnt = 0
            headers = {'Content-Type': 'application/json'}
            payload = json.dumps({})
            response = urllib2.urlopen(urllib2.Request('http://uni.soracom.io', payload, headers))
            print(response.getcode())
            body = json.loads(response.read())
            mp3data = base64.b64decode(body['data'])
            cp = Popen(['mpg123', '-'], stdin=PIPE)
            cp.communicate(input=mp3data)

        print(cnt)
        time.sleep(1)

if __name__ == "__main__":
    main()

```

## 2.発話させるメッセージ変更

AWS Lambdaのstorebot (Lambda 関数)のtextを"画面に近づきすぎです。画面から40センチ以上は
目を離しましょう"に変更しました。ちなみに㎝って書くとそのままセンチメートルって読んでしまい
違和感があったので、あえてセンチと入力しました。

コード全体はこちら

```
from boto3 import Session
from boto3 import resource
from contextlib import closing
import base64

def lambda_handler(event, context):
    text = "画面に近づきすぎです。画面から40センチ以上は目を離しましょう"

    polly = Session().client("polly")
    response = polly.synthesize_speech(Text=text, OutputFormat="mp3", VoiceId="Mizuki")
    with closing(response["AudioStream"]) as stream:
        r = {'encode': 'base64', 'format': "mp3", 'data': base64.b64encode(stream.read()).decode('utf-8')}
        return r
```

##3.超音波センサ固定部品製作
###3-1.設計

Autodesk社のFusion360を使って設計しました。

設計のポイントとしては
① ノートパソコンの開き具合が変わってもいいようにジョイント構造にしたこと
② できるだけシンプルにPCに取付けたかったのでコの字型にしたこと
  (カポッて被せられるようにした）
③ 細かい話ですが、干渉防止用の穴や各種固定用の穴を準備したこと
 です。

![Clipboard06.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/217319/f4dd3af3-fad5-a0a5-caeb-eeaac4bf111e.jpeg)
![Clipboard07.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/217319/18e91e4d-dd84-7024-17b6-120f7a542615.jpeg)

###3-2.部品製作＆組立、取付
FLASHFORGE社のAdventurer3 3Dプリンタを使って印刷したのち、組み立て、取り付けを行いました。
![Clipboard022.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/217319/7a1f8613-de6f-da52-a28c-7eb9d31afb50.jpeg)

## 完成

<iframe width="1130" height="753" src="https://www.youtube.com/embed/kQ2RqaUmEnA" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

※動画だと１秒間隔でドッ、ドッって音が入っていますが、超音波なので実際には人の耳には聴こえないです。


## まとめ
実際に作ってみたら色々と新たな課題が見えてきました。
① お店など人目が気になる環境では音声で警告するのではなく振動センサなど使って
　マナーモードで動作させたい（マナーモード機能が欲しい）
③スクリーンまでの距離をI2CのLCDでセンサ値を表示するなどして視える化したい

作ってみて思ったのは
まずはアイデアを大切に手を動かしてみる。形になれば人に見てもらって意見をもらうことも
できるし、より具体的に次の方向性が見えてきたりすると感じました。トライ＆エラーを繰り返して
より良いものを作り上げていくことが重要なんだろうと...。Advent Calendar投稿とても良い経験に
なりました。最後まで見ていただき有難うございます。