注釈

こんにちは、SunFounder Raspberry Pi & Arduino & ESP32 Enthusiast Community on Facebookへようこそ!他の愛好家と一緒に、Raspberry Pi、Arduino、ESP32の世界により深く入り込みましょう。

参加する理由

  • 専門家サポート: 購入後の問題や技術的な課題を、コミュニティと私たちのチームの助けを借りて解決します。

  • 学習と共有: ヒントやチュートリアルを交換して、スキルを向上させましょう。

  • 限定プレビュー: 新製品の発表や先行プレビューに早期アクセスできます。

  • 特別割引: 最新製品を特別割引でお楽しみいただけます。

  • 季節限定キャンペーンとプレゼント: プレゼント企画やホリデーキャンペーンに参加しましょう。

👉 一緒に発見し、創造する準備はできましたか? [こちら] をクリックして、今すぐ参加しましょう!

4.7 スマートファン

はじめに

このプロジェクトでは、手動モードと自動モードの両方で動作する「スマートファン」を作成します。モーター、ボタン、サーミスタを組み合わせることで、ファンの風量を調整できるだけでなく、温度変化にも応答できるようになります。モーター制御、温度検知、GPIO の使い方を学ぶのに最適な実験です。


必要なもの

このプロジェクトで必要なコンポーネントは以下のとおりです。

COMPONENT INTRODUCTION

PURCHASE LINK

ブレッドボード

購入

ジャンパーワイヤー

購入

抵抗器

購入

サーミスター

購入

ボタン

購入

DCモーター

購入

Fusion HAT+

-

Raspberry Pi

-


回路図

以下の回路図は、サーミスタ、ボタン、モータードライバー、およびモーターの接続方法を示しています。

../_images/4.1.7_sch.png

配線図

ブレッドボード上のレイアウトと配線接続は、以下の図を参照してください。

../_images/4.1.7_bb.png

サンプルの実行

このチュートリアルで使用するすべてのサンプルコードは ai-lab-kit ディレクトリに含まれています。 以下の手順に従ってサンプルを実行してください。

cd ~/ai-lab-kit/python/
sudo python3 4.7_SmartFan.py

コード

以下は、このプロジェクトで使用する Python スクリプトです。

#!/usr/bin/env python3

from fusion_hat.motor import Motor
from fusion_hat.pin import Pin, Mode, Pull
from fusion_hat.adc import ADC
from time import sleep, time
import math

BtnPin = Pin(22, mode=Mode.IN, pull=Pull.DOWN)
motor = Motor("M0")
thermistor = ADC("A3")

level = 0
currentTemp = None
markTemp = None

PRINT_INTERVAL = 1.0
_last_print = 0.0

button_event = False  # flag: button was pressed


def temperature(samples=5, delay=0.01):
   """Read thermistor multiple times and return averaged Celsius (float) or None."""
   vals = []
   for _ in range(samples):
      analogVal = thermistor.read()
      Vr = 3.3 * float(analogVal) / 4095.0
      if (3.3 - Vr) <= 0.1:
            return None
      Rt = 10000.0 * Vr / (3.3 - Vr)
      tempK = 1.0 / (((math.log(Rt / 10000.0)) / 3950.0) + (1.0 / (273.15 + 25.0)))
      vals.append(tempK - 273.15)
      sleep(delay)
   return sum(vals) / len(vals)


def motor_run(lv):
   lv = max(0, min(4, lv))
   motor.power(0 if lv == 0 else lv * 25)
   return lv


def changeLevel():
   """Button press: cycle level 0~4 and set a flag for main loop to print."""
   global level, button_event
   level = (level + 1) % 5
   button_event = True


BtnPin.when_activated = changeLevel


def main():
   global level, currentTemp, markTemp, _last_print, button_event

   markTemp = temperature()
   while True:
      currentTemp = temperature()
      if currentTemp is None:
            print("Sensor read failed. Please check the sensor.")
            sleep(0.5)
            continue

      # Handle button event in main loop (stable timing)
      if button_event:
            button_event = False
            markTemp = currentTemp
            print(f"[Button] Level -> {level} | Temp: {currentTemp:.2f} °C | Mark: {markTemp:.2f} °C")

      # Periodic temperature print
      now = time()
      if now - _last_print >= PRINT_INTERVAL:
            if markTemp is None:
               markTemp = currentTemp
            print(f"Temp: {currentTemp:.2f} °C | Mark: {markTemp:.2f} °C | Level: {level}")
            _last_print = now

      # Auto adjust level based on ±5°C
      if markTemp is None:
            markTemp = currentTemp

      if level != 0:
            diff = currentTemp - markTemp
            if diff <= -5:
               level = max(0, level - 1)
               markTemp = currentTemp
               print(f"[Auto] Temp down -> Level {level} (Temp: {currentTemp:.2f} °C)")
            elif diff >= 5:
               level = min(4, level + 1)
               markTemp = currentTemp
               print(f"[Auto] Temp up   -> Level {level} (Temp: {currentTemp:.2f} °C)")

      level = motor_run(level)
      sleep(0.5)


try:
   main()
except KeyboardInterrupt:
   print("\nExiting...")
finally:
   motor.stop()
   sleep(0.1)

この Python スクリプトは、モーター、ボタン、および温度センサーを組み合わせて、温度に応じて動作し、速度を調整できるファンシステムを作成します。実行すると、次のように動作します。

  1. 温度の測定: サーミスタを使用して現在の摂氏温度を読み取ります。

  2. 手動での風量調整:

    • GPIO22 に接続されたボタンにより、ユーザーは 5 段階の風量レベル(0~4)を順番に切り替えることができます。

    • ボタンを押すたびに風量レベルが 1 段階上がり、モーターは対応する速度で動作します。レベル 0 ではモーターが停止します。

  3. 自動風量制御: システムは温度変化に応じてモーター速度を自動調整します。

    • 温度が 5°C 以上上昇すると、風量レベルが 1 段階上がります(最大レベル 4)。

    • 温度が 5°C 以上低下すると、風量レベルが 1 段階下がります(最小レベル 0)。

  4. 継続的な監視: システムは温度を継続的に監視し、それに応じてファン速度を調整します。

  5. 安全な終了: Ctrl+C を押すと、モーターを停止し、スクリプトは安全に終了します。


コードの解説

  1. 温度の計算:

    def temperature(samples=5, delay=0.01):
       """Read thermistor multiple times and return averaged Celsius (float) or None."""
       vals = []
       for _ in range(samples):
          analogVal = thermistor.read()
          Vr = 3.3 * float(analogVal) / 4095.0
          if (3.3 - Vr) <= 0.1:
                return None
          Rt = 10000.0 * Vr / (3.3 - Vr)
          tempK = 1.0 / (((math.log(Rt / 10000.0)) / 3950.0) + (1.0 / (273.15 + 25.0)))
          vals.append(tempK - 273.15)
          sleep(delay)
       return sum(vals) / len(vals)
    

    temperature() 関数は、サーミスタのアナログ値を複数回読み取り、抵抗値へ変換し、数式を用いて対応する温度を計算します。

  2. モーター速度制御:

    def motor_run(lv):
       lv = max(0, min(4, lv))
       motor.power(0 if lv == 0 else lv * 25)
       return lv
    

    motor_run() 関数は、 level 変数に応じてモーター速度を調整します。速度は 0~4 の範囲に制限され、それに応じた出力が設定されます。

  3. 手動での風量調整:

    def changeLevel():
       """Button press: cycle level 0~4 and set a flag for main loop to print."""
       global level, button_event
       level = (level + 1) % 5
       button_event = True
    
    
    BtnPin.when_activated = changeLevel
    

    changeLevel() 関数は、ボタンが押されるたびに風量レベルを 0~4 の範囲で順番に切り替えます。

  4. 自動での風量調整:

    def main():
       global level, currentTemp, markTemp, _last_print, button_event
    
       markTemp = temperature()
       while True:
          currentTemp = temperature()
          if currentTemp is None:
                print("Sensor read failed. Please check the sensor.")
                sleep(0.5)
                continue
       ...
    

    main() 関数は温度を継続的に監視し、基準温度から 5°C 以上ずれた場合にファン速度を自動調整します。


トラブルシューティング

  1. モーターが動作しない :

    • 原因 : 配線ミス、または電源不足。

    • 対処方法 :

      • モーターが M0 に接続されていることを確認してください。

      • モーターの電源が必要電圧を満たしていることを確認してください。

  2. 温度読み取りが正しくない:

    • 原因 : サーミスタの不具合。

    • 対処方法:

      • サーミスタの配線を確認し、仕様範囲内で使用されていることを確認してください。

  3. ボタン入力が検出されない :

    • 原因 : ボタン配線または GPIO 設定の誤り。

    • 対処方法 :

      • ボタンが GPIO22 と GND に接続されていることを確認してください。

      • ボタン単体で、押したときに回路が閉じるかどうかをテストしてください。

  4. 風量レベルが自動で変わらない:

    • 原因 : 温度差の計算が正しくありません。

    • 対処方法 : main() 関数内で currentTempmarkTemp が正しく更新されていることを確認してください。


拡張アイデア

  1. 過熱アラート: 温度が危険なしきい値を超えたときに、ブザーや LED で警告を出します。

    if currentTemp > 50:
        buzzer.on()
    
  2. スマートボタン機能: ボタンの長押しで風量レベルを 0 にリセットしたり、自動/手動モードを切り替えたりできるようにします。


まとめ

スマートファンのプロジェクトでは、手動制御と自動制御を 1 つのシステムに統合する方法を学べます。これは、センサー、モーター、ユーザー操作を組み合わせた、実用的で効率的な設計例です。さらに機能を追加して、自分だけの温度制御システムへ発展させてみてください。