犬撃退(^_^;)装置

犬がテーブルの上乗って食べ物を食べる悪い癖がある。いくら叱っても聞かないので装置を作ってみました。仕様は犬が２０cm以内に接近するとプロペラが回り、音声「コラ！◯◯！コラ！コラ！」が鳴り、犬が嫌いな高周波を発信するものです。

使用したもの
* ラズパイピコ
* 超音波センサーHC-SR04
* スピーカー
* サーボモーターFS90R
* TPA2006アンプ
* 自作プロペラ

# #include
asyncioで非同期にする
```python
from machine import Pin, PWM, time_pulse_us, Timer
import time,utime
import wavePlayer
import uos
import asyncio

# player = wavePlayer.wavePlayer()
TEMP = 20  # 周囲の温度
s_speed = 331.5 + 0.6 * TEMP  # 音速計算

# ピンの設定
trig = Pin(14, Pin.OUT)  
echo = Pin(15, Pin.IN)  
# led pin
led = Pin(25, Pin.OUT)

SERVO_PIN = 16
PWM_FREQ = 50
```
# main
```python
async def main():
    try:
        while True:
            led.toggle()  # led 点灯
            distance = measure()  # 距離を測定
            print(distance)
            if distance < 20:  # 物体が20cm以内にあるかチェック
                print("20cm以内")


                # # サーボ回転             
                rotate_task = asyncio.create_task(pulse_width())

                # # wav再生
                sound_task = asyncio.create_task(soundplay())

                await asyncio.gather(sound_task, rotate_task)  # awaitするのを忘れないこと
                print("done")

            time.sleep(0.3)  # 次の測定まで1秒待つ（センサーからの連続読み取りを避け、システムに余裕を持たせる）
            # await asyncio.sleep(10)

    except KeyboardInterrupt:
                Pin(3, Pin.OUT, Pin.PULL_DOWN) # ザーの雑音消しておく
    finally:
        # servo.deinit()  # サーボモータのPWMを停止
        Pin(3, Pin.OUT, Pin.PULL_DOWN) # ザーの雑音消しておく
```
# 距離を測る
```python

def measure():
    trig.low()
    time.sleep_us(2)  # トリガーピンを短時間Lowにして安定させる
    trig.high()
    time.sleep_us(20)  # トリガーピンをHighにして超音波信号を発信
    trig.low()

    while ( echo.value( ) == 0 ):
        sigoff = utime.ticks_us()
    while ( echo.value( ) == 1 ):
        sigon = utime.ticks_us()
    dist = ( sigon - sigoff ) * s_speed / 2 * ( 10 ** -4 )
    return dist

```
# wavファイル再生
```python
# WAVファイルを再生する関数
async def soundplay():
    player = wavePlayer.wavePlayer()
    player.play('/sounds/sora.wav')
    player.stop()

    speaker = PWM(Pin(3, Pin.OUT))
    speaker.freq(int(25000)) # 犬の嫌な25KHz以上指定 
    speaker.duty_u16(2000)     # 10進数の0-65535または16進数で0x8000などと指定
    time.sleep(10) # wait a second
    #　消す
    speaker.duty_u16(0)

    Pin(3, Pin.OUT, Pin.PULL_DOWN) # ザーの雑音消しておく
    await asyncio.sleep(1)  # Pause 1s

```
# サーボモーター
```python
async def pulse_width( freq = PWM_FREQ, resol = 65535 ):
    # pulse = freq * val * 1e-6 * resol

    servo = PWM( Pin( SERVO_PIN ) ) # サーボモータ用のPWM設定、50Hzは一般的なサーボ用周波数
    servo.freq( PWM_FREQ )

    # サーボ回転 右5秒
    val = 1000
    duty= freq * val * 1e-6 * resol
    servo.duty_u16( int(duty) )
    # time.sleep( 5 )
    await asyncio.sleep(5) 

    # サーボ回転 左1秒
    val = 2000
    duty= freq * val * 1e-6 * resol
    servo.duty_u16( int(duty) )
    # time.sleep( 1 )
    await asyncio.sleep(1) 

    servo.deinit()  # サーボモータのPWMを停止

```
# 結果

```plantuml
@startuml
<style>
root {
  Padding 10
  Margin 10
}
header {
  FontColor black
  FontSize 50
}
</style>
scale 300 width
center header 装置全体図
title <img:https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3806156/0a8e1e4f-52ff-0f99-344e-e4b1b1d7a7b5.jpeg>
@enduml
```

![20240512_192151.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3806156/bf11c6e3-9f8a-23f6-f1ca-2895d257274c.gif)

大声で音声「コラ！◯◯！コラ！コラ！」が鳴っているにも関わらず全然うちの犬は動じませんでした（笑）