颯爽退勤日記

日々の考えごととか、ねことの日常とか

Raspberry Piと人感センサーでトイレに入ったらクラシック音楽が流れるようにした

はじめに

 

sassoutaikin.hatenablog.jp


Raspberry Pi と人感センサーを使って電気のON/OFFを自動で制御するようにしました。今回はこれの続きで、トイレに入ったら電気をつけるだけでなく音楽を流すことにしました。なんとなく音楽が流れたら小の方でも座るようになる気がする*1

やっぱりトイレはリラックスしたい、ということでクラシックが流れるようにしました*2

手順

準備するもの

(以前と一緒)

  • Raspberry Pi 3B+*3
  • 赤外線人感モジュール*4
  • ジャンプワイヤ(メス-メス)*5
  • Phillips Hue 電球 *6
  • Phillips Hue ブリッジ*7

(ここから今回使ったもの)

f:id:nyanco888:20191231224353j:plain
100円かと思ったら300円したスピーカー。USB給電なところが良い
f:id:nyanco888:20191231224402j:plain
開けるとこんな感じ

流す音楽を決める

最初はSpotifyにアクセスしてランダムで流せないかな、と思っていたのですが少し処理が面倒そうだったので、流す音楽は予めローカルにダウンロードして、その中からランダムで流すことにしました。

流すのは2-3分ですし、1日トイレ行くの数回だしランダムで流すと考えても、まあとりあえず10曲程度のクラシックをダウンロードします。

andotowa.quu.cc

今回、こちらのサイトにお世話になりました。

ダウンロードしたファイルは以下。基本的にリラックスできそうなやつにしました。

073-Tchaikovsky-SwanLake-Seane.mp3                    
Chopin-Etude-wakareno.mp3                               
Debussy-Girl-with-Flaxen-Hair.mp3                       
Debussy-clairdelune.mp3                                 
Elgar-Pomp-and-Circumstance-March-No1-2019-AR.mp3       
J.S.Bach-Air-On-G-2019-AR.mp3                           
J.S.Bach-Herz-und-Mund-und-Tat-und-Leben205B20175D.mp3  
Liszt-La-Campanella-2011.mp3
Mozart-EineKleine-1st.mp3
Satie-Gymnopedies-No1-piano.mp3
Schumann-Kinderszenen-Traumerei.mp3
Tchaikovsky-Nutcracker-waltz-flowers.mp3
Tchaikovsky-The-Nutcracker-Suite-6-Tea-Chinese-Dance.mp3
Tchikovsky-Reed-PipesDance.mp3
Tchikovsky-SugarPlumDance.mp3

ドビュッシーの月の光*9やバッハのG線上のアリア*10、サティのジムノペディ*11がお気に入りです。

クラシックって名前と曲が一致してなかったけど聞いたらあーーこの曲!!ってなるのめっちゃあります。 しっかり聞いてみようと思いました。

Raspberry Pi で音楽を流すには

ラズパイで音楽を流すには普通にスピーカーつなげばもちろん流れるのですが、今回のようにプログラムからpython用いて再生する際は、いくつか方法があるようです。

この辺りの記事が参考になりました。 qiita.com

どうやら、

  1. pygame
  2. PyAudio
  3. vlc
  4. aplay
  5. mpg321

の5種類があるようです。 今回はpygameを用いて実装しました。

公式のDocumentation*12を見ながら勉強します。日本語訳のもありました*13。助かります。

pygame.mixerで色々できるみたいです。

pygame.mixer.init - mixerモジュールを初期化します。

pygame.mixer.pre_init - mixerモジュールを初期化する引数を事前に設定します。

pygame.mixer.quit - mixerモジュールの初期化を解除します。

pygame.mixer.get_init - mixerモジュールが初期化されているか確認します。

pygame.mixer.stop - 全てのスピーカーでの音声再生を終了します。

pygame.mixer.pause - 全てのスピーカーでの音声再生を一時停止します。

pygame.mixer.unpause - 全てのスピーカーでの音声再生を再開させます。

pygame.mixer.fadeout - 再生中の音声を徐々に小さくしていった上で終了させます。

pygame.mixer.set_num_channels - 音声の再生に使用できるスピーカーの数を設定します。

pygame.mixer.get_num_channels - 音声の再生に使用できるスピーカーの数を取得します 。 pygame.mixer.set_reserved - 使用可能なスピーカーの中から、指定数のスピーカーを任意に確保します。

pygame.mixer.find_channel - 未使用のスピーカーを探します。

pygame.mixer.get_busy - 音声のミキシング処理が行われているか調べます。

pygame.mixer.Sound - ファイルなどから、Soundオブジェクトを新規に作成します。

pygame.mixer.Channel - 音声再生を制御するChannelオブジェクトを新規に作成します。

(公式documantationより)

実装

pygameを用いてmp3音楽ファイルを再生できることがわかったので、プログラムを書いていきます。 音楽フォルダのパスを取ってきて、センサー感知したらランダムに流し、センサーがオフになったら音楽を止める感じです。

#coding=utf-8
#!/bin/bash
#!/usr/bin/env python3
from datetime import datetime
import time
import datetime
import RPi.GPIO as GPIO
import requests
import pygame
import os
import random

# 1秒ごとにセンサー確認
INTERVAL = 1
# 一度電気をつけたあと2分間はセンサー確認を止める
SLEEPTIME = 120
# 使用するGPIOは18番(繋いだピン位置による)
GPIO_PIN = 18

GPIO.setmode(GPIO.BCM)
GPIO.setup(GPIO_PIN, GPIO.IN)

# pygame初期化
pygame.init()
pygame.mixer.pre_init(44100, 16, 2, 1024 * 4)
pygame.mixer.init()
pygame.mixer.set_num_channels(8)
screen = pygame.display.set_mode((320, 240))
clock = pygame.time.Clock()

musicfiles = []

os.chdir("/home/pi/sensor/music")

def play_random_track():
    # 音楽再生する関数
    global musicfiles
    # 再生リストがない場合は、mp3を指定パス内で探す
    if not musicfiles:
        musicfiles = [f for f in os.listdir('/home/pi/sensor/music') if f.endswith('.mp3')]
        random.shuffle(musicfiles)
    # musicfilesから最初の曲を流す
    pygame.mixer.music.load(files.pop(0))
    pygame.mixer.music.set_volume(1.0)
    pygame.mixer.music.play()


if __name__ == '__main__':
    try:
        print ("処理キャンセル:CTRL+C")
        cnt = 1
        day = datetime.date.today().strftime('%Y/%m/%d')
        while True:
            if day == datetime.date.today().strftime('%Y/%m/%d'):
                # センサー感知
                if(GPIO.input(GPIO_PIN) == GPIO.HIGH):
                    # 音楽再生されてない場合は再生
                    if pygame.mixer.music.get_busy() != True:
                        play_random_track()
                        print('音楽再生')
                    print(datetime.datetime.now().strftime('%Y/%m/%d %H:%M:%S')+
                    ":本日" + str("{0:02d}".format(cnt)) + "回目のトイレでの人感知")
                    cnt = cnt + 1
                    time.sleep(SLEEPTIME)
                else:
                    # センサーが感知しなかった場合、音楽がなっていたら5秒でフェードアウト
                    if pygame.mixer.music.get_busy() == True:
                        pygame.mixer.music.fadeout(5000)
                        print('音楽停止')

                    print(datetime.datetime.now().strftime('%Y/%m/%d %H:%M:%S') +
                    ":" + 'トイレに人はいません')
                    time.sleep(INTERVAL)
            else:
                day = datetime.date.today().strftime('%Y/%m/%d') 
                cnt = 1
            pygame.display.flip()
    except KeyboardInterrupt:
        print("終了処理中......")
    finally:
        GPIO.cleanup()
        print("GPIO clean完了")
        pygame.quit()

以前の電気ON/OFFも加えて、

流れました!!

おわりに

前回の電気に続いて、トイレ入ったらクラシック音楽が流れるようにすることができました。 音楽を流した結果、

  • ラズパイ使って人感センサー入力で音楽を流すことができた
  • 入ったら電気がついてゆったりとしたクラシックが流れる、良いトイレになった
  • 小でも座るようになった(音楽流れると座らなきゃとなぜか思います)
  • トイレで動画みたり長居することがなくなった(音楽が2分で切れるのであ、2分経ったとわかる)
  • やっぱりラズパイ楽しい。

と言ったのが感想です。

ちなみに、最終的にケースもつけていい感じになりました。 f:id:nyanco888:20191231201041j:plain

f:id:nyanco888:20200101000933j:plain
音楽は背後から流れます

あと、これは全く関係ないですが無印良品のアロマストーンも買いました。トイレに置いてます。

クラシックと相性抜群です。

f:id:nyanco888:20191231224342j:plain
グレーのアロマストーン。アロマはイランイランを買いました

次は猫の見守りカメラ作りたいなあ。