注釈
こんにちは、SunFounder Raspberry Pi & Arduino & ESP32 愛好者コミュニティ (Facebook) へようこそ! Raspberry Pi、Arduino、ESP32 を仲間とともにさらに深く学びましょう。
参加する理由
専門サポート: 購入後の問題や技術的な課題をコミュニティとチームで解決
学びと共有: ヒントやチュートリアルを交換し、技術を向上
限定プレビュー: 新製品発表や先行情報に早期アクセス
特別割引: 新製品を特別価格で購入可能
イベントとプレゼント企画: プレゼントや季節ごとのキャンペーンに参加
👉 一緒に探求し、創造しましょう。今すぐ [ここ] をクリックして参加!
4.1.13 過熱監視装置 (MCP3008)
概要
工場などで回路が過熱したときにアラームを鳴らし、機械を自動的に停止させるなど、さまざまな状況で利用できる過熱監視装置を作成します。 このプロジェクトでは、温度を検出するためにサーミスタ、しきい値を調整するためにジョイスティック、警告用のブザー、表示用のLEDとLCDを使用して、しきい値を調整可能な温度監視装置を作ります。
必要な部品
本プロジェクトで必要な部品は以下の通りです。
キット一式で購入するのが便利です。リンクはこちら:
名称 |
キット内の数量 |
リンク |
|---|---|---|
Raphael Kit |
337 |
個別に購入する場合は以下のリンクをご参照ください。
部品名 |
購入リンク |
|---|---|
- |
|
- |
|
- |
回路図
T‑Board Name |
physical |
wiringPi |
BCM |
SPICE0 |
Pin 24 |
10 |
8 |
SPIMOSI |
Pin 19 |
12 |
10 |
SPIMISO |
Pin 21 |
13 |
9 |
SPISCLK |
Pin 23 |
14 |
11 |
GPIO22 |
Pin 15 |
3 |
22 |
GPIO23 |
Pin 16 |
4 |
23 |
GPIO24 |
Pin 18 |
5 |
24 |
SDA1 |
Pin 3 |
||
SCL1 |
Pin 5 |
実験手順
ステップ 1: 回路を組み立てます。
ステップ 2: SPI インターフェースを設定し、 spidev ライブラリをインストールします(詳細は SPI 設定 参照)。すでに完了している場合は省略可。
ステップ 3: コードを配置したフォルダに移動します。
cd ~/raphael-kit/python
ステップ 4: 実行します。
sudo python3 4.1.13-2_OverheatMonitor.py
プログラムが動作すると、I2C LCD1602 に現在の温度と高温しきい値 40 が表示されます。 現在の温度がしきい値を超えるとブザーとLEDが動作し警告します。
ジョイスティック は高温しきい値を調整するために使用します。 ジョイスティックをX軸またはY軸方向に倒すとしきい値を上下に変更できます。 ジョイスティックを押すとしきい値が初期値にリセットされます。
注釈
FileNotFoundError: [Errno 2] No such file or directory: '/dev/i2c-1'エラーが出た場合、I²C 設定 を参照してI2Cを有効にしてください。ModuleNotFoundError: No module named 'smbus2'エラーが出た場合、sudo apt install python3-smbus2を実行してください。OSError: [Errno 121] Remote I/O errorエラーが出た場合、配線の誤りまたはモジュールの故障の可能性があります。配線とコードが正しくてもLCDが表示しない場合は、背面の可変抵抗を回してコントラストを調整してください。
警告
RuntimeError: Cannot determine SOC peripheral base address エラーが出た場合は、「gpiozero」が動作しない場合。 を参照してください。
コード
注釈
コードの 修正/リセット/コピー/実行/停止 が可能です。事前に raphael-kit/python に移動してください。変更後すぐに動作確認できます。
(コード部分省略、元のまま保持)
コード解説
ライブラリ読み込み
GPIO、SPI、LCD表示、時間処理、数値計算を行うためのライブラリを読み込みます。
#!/usr/bin/env python3 import RPi.GPIO as GPIO import spidev import time import math import LCD1602
GPIOとデバイス設定
ジョイスティックボタン、ブザー、LEDのGPIOピン番号を定義し、モードを設定します。
JOY_BTN_PIN = 22 # Button pin BUZZER_PIN = 23 # Buzzer pin LED_PIN = 24 # LED pin GPIO.setmode(GPIO.BCM) GPIO.setup(JOY_BTN_PIN, GPIO.IN, pull_up_down=GPIO.PUD_UP) GPIO.setup(BUZZER_PIN, GPIO.OUT) GPIO.setup(LED_PIN, GPIO.OUT)
SPIとLCD初期化
MCP3008とのSPI通信を開始し、I2Cアドレス0x27のLCD1602を初期化します。
upperTem = 40 spi = spidev.SpiDev() spi.open(0, 0) spi.max_speed_hz = 1000000 LCD1602.init(0x27, 1)
ADC値読み取り
MCP3008から指定チャンネル(0〜7)のアナログデータを読み取ります。
def read_adc(channel): if channel < 0 or channel > 7: return -1 adc = spi.xfer2([1, (8 + channel) << 4, 0]) value = ((adc[1] & 0x03) << 8) | adc[2] return value
ジョイスティック検出
X/Y軸値を確認し、しきい値変更量を返します。
def get_joystick_value(): x_val = read_adc(1) y_val = read_adc(2) if x_val > 800: return 1 elif x_val < 200: return -1 elif y_val > 800: return -10 elif y_val < 200: return 10 else: return 0
上限温度設定
LCDに「Upper Adjust」を表示し、ジョイスティック入力でしきい値を調整します。
def upper_tem_setting(): global upperTem LCD1602.write(0, 0, 'Upper Adjust: ') change = int(get_joystick_value()) upperTem += change strUpperTem = str(upperTem) LCD1602.write(0, 1, strUpperTem) LCD1602.write(len(strUpperTem), 1, ' ') time.sleep(0.1)
温度計算
センサーのアナログ値を電圧・抵抗値に変換し、Steinhart–Hart近似で摂氏温度を計算します。
def temperature(): analogVal = read_adc(0) Vr = 3.3 * analogVal / 1023.0 if Vr == 0: return 0 Rt = 10000.0 * (3.3 - Vr) / Vr tempK = 1.0 / (((math.log(Rt / 10000.0)) / 3950.0) + (1.0 / (273.15 + 25.0))) Cel = tempK - 273.15 return round(Cel, 2)
温度監視
現在温度としきい値を表示し、超過時にブザーとLEDを動作させます。
def monitoring_temp(): global upperTem Cel = temperature() LCD1602.write(0, 0, 'Temp: ') LCD1602.write(0, 1, 'Upper: ') LCD1602.write(6, 0, str(Cel)) LCD1602.write(7, 1, str(upperTem)) time.sleep(0.1) if Cel >= upperTem: GPIO.output(BUZZER_PIN, GPIO.HIGH) GPIO.output(LED_PIN, GPIO.HIGH) else: GPIO.output(BUZZER_PIN, GPIO.LOW) GPIO.output(LED_PIN, GPIO.LOW)
メイン処理
ジョイスティックボタン押下でモードを切り替え、しきい値調整モードと監視モードを行き来します。
try: lastState = GPIO.input(JOY_BTN_PIN) stage = 0 while True: currentState = GPIO.input(JOY_BTN_PIN) if currentState == GPIO.HIGH and lastState == GPIO.LOW: stage = (stage + 1) % 2 time.sleep(0.1) LCD1602.clear() lastState = currentState if stage == 1: upper_tem_setting() else: monitoring_temp()
終了処理
Ctrl+C終了時にGPIOとSPIを解放し、LCDをクリアします。
except KeyboardInterrupt: pass finally: LCD1602.clear() GPIO.cleanup() spi.close()