【高先さんの電子工作】第21回：モーションセンサーで動きを検知したらLINEに通知してメロディーを鳴らす

# 概要

実演していますが、モーションセンサーに反応があったらLINEに通知が飛んできて、電圧ブザーでカエルのうたを鳴らしています。

https://youtu.be/zvkvuV_3X9g

## 電子回路

PIRセンサーモジュールは以下を参考にして下さい。

https://docs.sunfounder.com/projects/kepler-kit/ja/latest/pyproject/py_pir.html#py-pir

パッシブブザーは以下を参考にして下さい。

https://docs.sunfounder.com/projects/kepler-kit/ja/latest/pyproject/py_pa_buz.html

## ソースコード

Wi-Fiの接続情報とLINE Notifyのアクセストークンを設定ファイルに書き込みます。

```json:config.json
{
    "ssid": "2.4GHzのSSID",
    "password": "Wi-Fiのパスワード",
    "access_token": "LINE Notifyのアクセストークン"
}
```

メインのプログラムを実行すると、モーションセンサーがONになって、動体検知するとカエルのうたが鳴ります。

```python:main.py
import machine
from utime import sleep, sleep_ms
import ujson
import network
import urequests

melody = False
led = machine.Pin('LED', machine.Pin.OUT)
buzzer = machine.PWM(machine.Pin(15))
pir_sensor = machine.Pin(14, machine.Pin.IN)

def tone(pin, frequency, duration):
    pin.freq(frequency)
    pin.duty_u16(30000)
    sleep_ms(duration)
    pin.duty_u16(0)

def C(duration):
    tone(buzzer, 262, duration)

def D(duration):
    tone(buzzer, 294, duration)

def E(duration):
    tone(buzzer, 330, duration)

def F(duration):
    tone(buzzer, 349, duration)

def G(duration):
    tone(buzzer, 392, duration)

def A(duration):
    tone(buzzer, 440, duration)   

def B(duration):
    tone(buzzer, 494, duration)

def HI_C(duration):
    tone(buzzer, 523, duration)

def kaerunouta(duration):
    C(duration)
    D(duration)
    E(duration)
    F(duration)
    E(duration)
    D(duration)
    C(duration)
    sleep_ms(duration)
    E(duration)
    F(duration)
    G(duration)
    A(duration)
    G(duration)
    F(duration)
    E(duration)
    sleep_ms(duration)
    C(duration)
    sleep_ms(duration)
    C(duration)
    sleep_ms(duration)
    C(duration)
    sleep_ms(duration)
    C(duration)
    sleep_ms(duration)
    C(int(duration/2))
    sleep_ms(5)
    C(int(duration/2))
    sleep_ms(5)
    D(int(duration/2))
    sleep_ms(5)
    D(int(duration/2))
    sleep_ms(5)
    E(int(duration/2))
    sleep_ms(5)
    E(int(duration/2))
    sleep_ms(5)
    F(int(duration/2))
    sleep_ms(5)
    F(int(duration/2))
    E(duration)
    D(duration)
    C(duration)

def motion_detected(pin):
    global melody
    print('動きを検知しました。')
    if not melody:
        line_notify('動きを検知しました。')
        led.on()
        melody = True
        kaerunouta(400)
        melody = False
        led.off()
    
def line_notify(message):
    endpoint = 'https://notify-api.line.me/api/notify'
    headers = {
        'Authorization': 'Bearer ' + access_token,
        'Content-Type' : 'application/x-www-form-urlencoded'
    }
    data = f'message={message}'.encode('utf-8')
    response = urequests.post(endpoint, headers=headers, data=data)
    response.close()
 

try:
    led.on()
    sleep(10)
    config = {} 
    with open('config.json', 'r') as f:
        config = ujson.load(f)
    
    ssid = config['ssid']
    password = config['password']
    access_token = config['access_token']

    wlan = network.WLAN(network.STA_IF)
    wlan.active(True)
    wlan.connect(ssid, password)

    while not wlan.isconnected():
        print('Waiting for connection...')
        sleep(1)
        
    ip = wlan.ifconfig()[0]
    print(f'Connected on {ip}')
    print('Starting PIR Sensor')
    pir_sensor.irq(trigger=machine.Pin.IRQ_RISING, handler=motion_detected)
    while True:
        sleep(1)
except Exception as e:
    pir_sensor = None
    buzzer.duty_u16(0)
    led.off()
    print(e)


```