Yossyのアイコン画像
Yossy 2024年09月20日作成 (2024年10月31日更新) © MIT
製作品 製作品 閲覧数 83
Yossy 2024年09月20日作成 (2024年10月31日更新) © MIT 製作品 製作品 閲覧数 83

こまめに室温・湿度を確認しよう!「こまめちゃん」

こまめに室温・湿度を確認しよう!「こまめちゃん」

概要

近年、熱中症警戒アラートの発令によって気温上昇に注意を向ける場面が増加しています。そこで私は、指さし温度・湿度計を制作し、より自分自身の体調管理に気を付けて行動したいと考えました。また、今回温度・湿度計を作成するにあたって皆さんに熱中症の警戒を呼びかける啓発活動に少しでも貢献できるのではないかと感じました。

概要を示す図

イメージ図

アイデアの詳細

  • イラスト作成を行う。
  • サーボモータを使用して温度と湿度を示す。
  • 一定温度になると何かしらのアクションを出力する。
    (例、緊急性のある音を出す、指を素早くふるなど)
  • Pythonを使用して気温や湿度を取得するプログラムを作成。
  • 気温や湿度の目盛りの間隔とサーボモータの動作範囲を明確にする。
  • サーボモータの使い方を理解する。

必要となる物品

部品名称 型名 数量
Raspberry pi 4 1
サーボモータ SG90 2
温度湿度センサ BME280 1
イラスト作成の道具 (板や紙、段ボールなど)

「pigpio」ライブラリのインストール

Raspberry Piの制御方法として「pigpio」ライブラリがあり、サーボモータの制御が可能となっています。
aptコマンドでインストールすることができます。
pigpioライブラリ
また、pigpioライブラリを使ってGPIOにアクセスするには、pigpiodを起動する必要があります。
自動起動
これでサーボモータを使う準備ができました。

GPIOのピン配置について

ピン配置

温度用サーボモータ部分

制御信号用の配線は、Raspberry PiのGPIO13(端子番号33)に接続して制御した。
電源用配線は、Raspberry Piの端子番号2に接続して制御した。
GND用配線Raspberry Piの端子番号6に接続して制御した。

湿度用サーボモータ部分

制御信号用の配線は、Raspberry PiのGPIO12(端子番号32)に接続して制御した。
電源用配線は、Raspberry Piの端子番号4に接続して制御した。
GND用配線Raspberry Piの端子番号30に接続して制御した。

サーボモータには3本の配線が取り付けられています。
配線は、赤線が電源、茶線がGND、オレンジ線が制御信号用配線となっています。

3本の配線

サーボモータの動作範囲を調べる

次に目盛りの最大温度(40℃)、最小温度(0℃)、最大湿度(70%)、最小湿度(30%)を指すためのパルス幅を調べます。指定するパルス幅を変えながら「adjust.py」でサーボモータを動かし、最大温度・湿度または最小温度・湿度を指すように調整します。

adjust.py

import sys import pigpio SERVO_PIN = 12 //SERVO_PIN = 13 args = sys.argv f = 0 if ( len( args ) > 1 ): if ( args[1].isdecimal() ): p_width = int( args[1] ) if ( p_width >= 500 and p_width <= 2500 ): f = 1 if ( f == 1 ): print ("Servo set", p_width ) pi = pigpio.pi() pi.set_servo_pulsewidth(SERVO_PIN, p_width) else: print ("USAGE: python3 servo.py PULSE_WIDTH") print (" PULSE_WHDHT : Pulse range is 500-2500.")

今回は、

  • 40℃を指すパルス幅 →「2350」
  • 0℃を指すパルス幅  →「1550」
  • 70%を指すパルス幅 →「680」
  • 30%を指すパルス幅 →「1500」となりました。
    このパルス幅を実際に指振りプログラムに利用していきます。

プログラムの書き込み

このプログラムは温度や湿度を示すことが可能です。
また、温度が35℃以上、湿度が65%以上になった場合、指を素早く振るというプログラムです。

指振りプログラム

import pigpio import sys, time import smbus2 import bme280 MIN_TEMP = 0 MAX_TEMP = 40 MAX_PULSE = 2350 MIN_PULSE = 1550 MIN_HUMIDITY = 30 MAX_HUMIDITY = 70 MIN_PULSE_HUMIDITY = 1500 MAX_PULSE_HUMIDITY = 680 SWING_MIN_PULSE = 1000 # サーボモーターが振れる最小パルス幅 SWING_MAX_PULSE = 2000 # サーボモーターが振れる最大パルス幅 SWING_DELAY = 0.5 # モーターが振動する速度(秒単位) INT_TIME = 1 TEMP_SERVO_PIN = 13 HUMIDITY_SERVO_PIN = 12 BME280_ADDR = 0x76 pi = pigpio.pi() bus = smbus2.SMBus(1) calibration_params = bme280.load_calibration_params(bus, BME280_ADDR) delta_temp = (MAX_PULSE - MIN_PULSE) / (MAX_TEMP - MIN_TEMP) inter_temp = (MIN_PULSE * MAX_TEMP - MAX_PULSE * MIN_TEMP) / (MAX_TEMP - MIN_TEMP) delta_humidity = (MAX_PULSE_HUMIDITY - MIN_PULSE_HUMIDITY) / (MAX_HUMIDITY - MIN_HUMIDITY) inter_humidity = (MIN_PULSE_HUMIDITY * MAX_HUMIDITY - MAX_PULSE_HUMIDITY * MIN_HUMIDITY) / (MAX_HUMIDITY - MIN_HUMIDITY) def swing_motor(): # 温度サーボと湿度サーボを左右に振る動作 for _ in range(3): # 3回振る # 温度サーボモーターを振動させる pi.set_servo_pulsewidth(TEMP_SERVO_PIN, SWING_MIN_PULSE) pi.set_servo_pulsewidth(HUMIDITY_SERVO_PIN, SWING_MIN_PULSE) # 湿度サーボモーターも同時に動かす time.sleep(SWING_DELAY) # 温度サーボモーターを反対方向に振る pi.set_servo_pulsewidth(TEMP_SERVO_PIN, SWING_MAX_PULSE) pi.set_servo_pulsewidth(HUMIDITY_SERVO_PIN, SWING_MAX_PULSE) # 湿度サーボモーターも反対方向に振る time.sleep(SWING_DELAY) # モーターを停止 pi.set_servo_pulsewidth(TEMP_SERVO_PIN, 0) pi.set_servo_pulsewidth(HUMIDITY_SERVO_PIN, 0) def swing_motor_temp(): # モーターを左右に振る動作 for _ in range(3): # 3回振る pi.set_servo_pulsewidth(TEMP_SERVO_PIN, SWING_MIN_PULSE) time.sleep(SWING_DELAY) pi.set_servo_pulsewidth(TEMP_SERVO_PIN, SWING_MAX_PULSE) time.sleep(SWING_DELAY) pi.set_servo_pulsewidth(TEMP_SERVO_PIN, 0) # モーターを停止 def swing_motor_humidity(): # モーターを左右に振る動作 for _ in range(3): # 3回振る pi.set_servo_pulsewidth(HUMIDITY_SERVO_PIN, SWING_MIN_PULSE) time.sleep(SWING_DELAY) pi.set_servo_pulsewidth(HUMIDITY_SERVO_PIN, SWING_MAX_PULSE) time.sleep(SWING_DELAY) pi.set_servo_pulsewidth(HUMIDITY_SERVO_PIN, 0) # モーターを停止 while True: data = bme280.sample(bus, BME280_ADDR, calibration_params) temp = data.temperature humidity = data.humidity target_servo_temp = int(delta_temp * temp + inter_temp) target_servo_humidity = int(delta_humidity * humidity + inter_humidity) print(f"Temperature: {temp:.2f}C\t Humidity: {humidity:.2f}%\t Temp Servo pulse: {target_servo_temp}\t Humidity Servo pulse: {target_servo_humidity}") # 温度が35℃以上、かつ湿度が65%以上の場合にモーターを振動させる if temp >= 35 and humidity >= 65: print("Temperature is 35°C or higher and Humidity is 65% or higher. Swinging the motor.") swing_motor() elif temp >= 35: # 温度が35℃以上の場合にモーターを振動させる print("Temperature is 35°C or higher. Swinging the motor.") swing_motor_temp() elif humidity >= 65: # 湿度が65%以上の場合にモーターを振動させる print("Humidity is 65% or higher. Swinging the motor.") swing_motor_humidity() # サーボモーターのパルス幅の範囲チェック(温度用) if target_servo_temp < 500 or target_servo_temp > 2500 or temp > MAX_TEMP or temp < MIN_TEMP: print("温度用サーボパルス幅の範囲外") else: pi.set_servo_pulsewidth(TEMP_SERVO_PIN, target_servo_temp) # サーボモーターのパルス幅の範囲チェック(湿度用) if target_servo_humidity < 500 or target_servo_humidity > 2500 or humidity > MAX_HUMIDITY or humidity < MIN_HUMIDITY: print("湿度用サーボパルス幅の範囲外") else: pi.set_servo_pulsewidth(HUMIDITY_SERVO_PIN, target_servo_humidity) time.sleep(INT_TIME)

完成したイラスト(表)
ラズパイとサーボモータ(裏)

プログラムで工夫した点

温度と湿度がそれぞれ(35℃以上、65%以上)を超える場合、個別にサーボモータを振動させるか、同時に振動させるかを分岐させています。たとえば、温度が閾値以上ならば swing_motor_temp()関数で温度用のサーボを振動させ、湿度の場合はswing_motor_humidity()関数で湿度用サーボを振動させるようにしました。また、計算したサーボモータのパルス幅が適正範囲内にあるかをチェックすることで、温度や湿度が設定された範囲外になったときに警告メッセージを出力する処理を作成しました。これにより、不適切なパルス幅でサーボモータが動作しないようにしました。

結果

気温・湿度が変化すると指が正常に上がったり、下がったりと動作することを確認できた。また、一時的に温度・湿度センサを覆い気温を35℃以上にすると、サーボモータが素早く上下に動作したため思い通りのものにすることができた。改善点としては、電源供給をPCからではなく、乾電池を利用してどこにでも設置でき、温度・湿度を確認できるものにすることや、温度の変動が少ないため現在電源が入っているか分からなくなってしまうため、LEDなどを付けることで瞬時に電源が入っているのかを確認できる仕組みを追加できたらいいなと感じた。

まとめ

一般的には、温度湿度センサーのデータはディスプレイや画面に数値として表示されますが、今回はアナログ的な表示方法としてサーボモータを使い、指さしで温度と湿度を示すことができる作品を製作しました。サーボモータやセンサーの使い方についての理解も深まり、これらをきっかけにより発展した内容にも挑戦していきたいと感じました

参考文献

電子工作初心者がラズパイでサーボモータ1~4個を動かした方法
https://qiita.com/kurukurupapa@github/items/953fcc69c17bf082e76e
ラズパイ電子工作の基本① サーボモータを使って指さし温度計を作ってみよう
https://deviceplus.jp/raspberrypi/raspberrypi_f01/#servo motor 01
Raspberry Pi 4 の GPIO ピン配置(ピンマッピング)について
https://qiita.com/Erytheia/items/f362a3d68e57cd088713
秋月電子通商
https://akizukidenshi.com/catalog/g/g108761/

ログインしてコメントを投稿する