kanaza_ki が 2021年02月28日23時46分19秒 に編集
初版
タイトルの変更
コロナ禍を乗り越えろ!サイコーな消毒奨励機を作る
タグの変更
秋葉原2021
アルコール消毒
RaspberryPi
COVID-19
沼津高専
社会実装
メイン画像の変更
記事種類の変更
製作品
本文の変更
# はじめに 2019年末から人類を襲った未曾有の災禍、新型コロナウイルス感染症「COVID-19」。緊急事態宣言が解除され、県内の警戒レベルも下がり始めたこの時期。自分を含めた世間において、感染症対策の基本のキである「手指の消毒」が疎かなっているのではないか? この意識の低下を防ごうと、我々は**人間の承認欲求**を逆手にとることにした。 #### 褒める消毒液スタンド “3150 sanitizer” 誕生の瞬間である。 # UXを決める 褒める消毒液スタンドとは言ったものの、具体的なUXを決めねば話にならない。試行錯誤の結果、以下の3つに焦点を絞ることにした。 - 思わず立ち止まらせる(ユーザーの目に嫌でも入る) - 消毒液をプッシュしたら褒めてくれる - 認知度が限りなく低い本校第二校歌が聞ける > とにかく呼びかけること、目を引くことが消毒への第一歩である。 # システム ## したいこと ![](https://camo.elchika.com/4688e3a869f02e9930816d6217073f151038b9bc/687474703a2f2f73746f726167652e676f6f676c65617069732e636f6d2f656c6368696b612f76312f757365722f35666234666664382d316132352d343062372d623237312d6662383239656537303032392f37613565376534392d616432372d343639622d383761352d643838396633653131646262/) ## 使った電子部品・モジュール - Raspberry Pi 3B(3.5mmジャックが欲しいの) - 感圧センサ(四角形):[ALPHA-MF02-N-221-A01](https://www.switch-science.com/catalog/2615/) - 10bit 2ch ADコンバータ:[MCP3002-I/P](https://akizukidenshi.com/catalog/g/gI-02584/) - Φ3.5mm入力のスピーカー ## いざ配線 感圧センサとADコンバータの接続は[こちら](https://qiita.com/f_nishio/items/93387feade923a0d20a0)を参考にした。 ![ブレッドボード実装図](https://tinyurl.com/yaftkyva) ![実装写真](https://camo.elchika.com/cdcad13c50cf36a0522beb5d9fccc649c0aa3130/687474703a2f2f73746f726167652e676f6f676c65617069732e636f6d2f656c6368696b612f76312f757365722f35666234666664382d316132352d343062372d623237312d6662383239656537303032392f34633461383532652d386461322d343264382d626239372d626563313138656337643437/) ## コーディング ### センサ値を読み取る SPI通信を使うため、RaspberryPiのSPI driverを有効にする。RaspbeeryPiの/boot/config.txtを編集(`#dtparam=spi=on`のコメントを外す)するか、raspi-configで設定する。 > 作業後の再起動も忘れずに! ここでSPIのPythonモジュールもインストールしておく。 ```shell: $ git clone git://github.com/doceme/py-spidev $ cd py-spidev $ sudo python setup.py install ``` 以上を満たしていれば、センサ値は次のコードで読み込める([参考](https://tinyurl.com/yd4q83hd))。 ```Python:センサ値を取ろう def main(): # SPI channel (0 or 1) SPI_CH = 0 # SPI speed (hz) SPI_SPEED = 1000000 # GPIO number LED_PIN = 25 # setup wp.wiringPiSPISetup(SPI_CH, SPI_SPEED) wp.wiringPiSetupGpio() wp.pinMode(LED_PIN, wp.GPIO.OUTPUT) THRESHOLD = 200 while True: buffer = 0x6800 buffer = buffer.to_bytes(2, byteorder='big') wp.wiringPiSPIDataRW(SPI_CH, buffer) # 値を取得 value = (buffer[0] * 256 + buffer[1]) & 0x3ff # print(value) """ ここで音を鳴らす条件と処理を書く """ ``` > WiringPi2 には MCP3002用の関数があるため、SPI通信を意識せずともアナログデータをそのまま参照可能らしい。 ### 音声を鳴らす Raspberry PiのPythonでは、Pygameという音声再生モジュールが存在する。pipからインストール可能。 ```shell: $ pip install pygame ``` 基本的な文法はこちら。 ```python:音声再生サンプル import pygame.mixer import time # mixerモジュールの初期化 pygame.mixer.init() # 音楽ファイルの読み込み pygame.mixer.music.load("ファイル名.mp3") # 音楽再生、および再生回数の設定(-1はループ再生) pygame.mixer.music.play(-1) time.sleep(60) # 再生の終了 pygame.mixer.music.stop() ``` ### まとめる 上記のコードたちと流したい音声素材たちを集めて統合する。`Main.py`や`py-spidev/`などの位置関係は次の通り。 ``` 3150_sanitizer/ ├ audio_file | ├ 第2校歌.mp3 │ ├ 褒めるボイス1.mp3 │ └ 褒めるボイス2.mp3 │ : │ : ├ py-spidev/ ├ Main.py └ play_sound.py ``` 消毒液ボトルを載せた圧力センサの値を差分でチェックし、押したと判断できる閾値を超えた場合に音声を流す。今回は3種類の音声を用意し、第2校歌はレア枠とした。 > [音声ガチャの比率] > **第2校歌:ほめるボイス1:ほめるボイス2 = 1:5:5** ```python:Main.py import wiringpi2 as wp import time from play_sound import play_sound def main(): SPI_CH = 0 SPI_SPEED = 1000000 LED_PIN = 25 wp.wiringPiSPISetup(SPI_CH, SPI_SPEED) wp.wiringPiSetupGpio() wp.pinMode(LED_PIN, wp.GPIO.OUTPUT) previous_value = 0 THRESHOLD = 200 while True: buffer = 0x6800 buffer = buffer.to_bytes(2, byteorder='big') wp.wiringPiSPIDataRW(SPI_CH, buffer) value = (buffer[0] * 256 + buffer[1]) & 0x3ff # print(value, previous_value) if value - previous_value > THRESHOLD: play_sound() time.sleep(5) previous_value = value time.sleep(0.5) if __name__ == '__main__': main() ``` ```python:play_sound.py import os import pygame.mixer import random def play_sound(): pygame.mixer.init() file_name = select_file() pygame.mixer.music.load(file_name) pygame.mixer.music.play(1) return True def select_file(): audio_dir = 'audio_file/' base_dir = os.path.join(os.path.dirname(__file__), audio_dir) file_name_list = os.listdir(audio_dir) file_key = random.randint(0, 10) if file_key == 0: # リスト内で最初に来るのは第2校歌なので。 # (ガバ設計注意) file_key = 0 elif file_key < 6: file_key = 1 else: file_key = 2 file_name = file_name_list[file_key] file_path = os.path.join(base_dir, file_name) print(file_path) return file_path # test用の処理 if __name__ == '__main__': a = play_sound() print(a) ``` ## 合体! ![実装イメージ](https://camo.elchika.com/cd899a6f4efd3a72d9c5163cc124f661f61e2470/687474703a2f2f73746f726167652e676f6f676c65617069732e636f6d2f656c6368696b612f76312f757365722f35666234666664382d316132352d343062372d623237312d6662383239656537303032392f62613831383134642d363464352d343265322d616630332d646131663661643464393232/) # 設置 学生課教務係長の協力を取り付け、正式に設置が可能となった。 消毒できる男は **"3150"**(最高)であるというコピー。第2校歌の歌詞カードも追加した(著作権の都合上、モザイクをかけています)。まさに完璧である。 ![キャプションを入力できます](https://camo.elchika.com/2515b0b9f8ae10a56bd72403ac284c8bdde0b31a/687474703a2f2f73746f726167652e676f6f676c65617069732e636f6d2f656c6368696b612f76312f757365722f35666234666664382d316132352d343062372d623237312d6662383239656537303032392f62363136633263342d373735662d343635312d626339302d323534393630366366333861/) この**3150 Sanitizer**が本校の感染症対策の一助となれば幸いである。 ==皆さんも、レッツ消毒啓蒙活動。==