資料介紹
描述
問題
我必須不斷調整我的加熱器以保持合適的溫度。此外,有時我離開家時忘記關掉暖氣。
解決方案
設置溫度和運動傳感器以捕獲環境數據。創建一個網絡應用程序,允許用戶設置他們想要的溫度,這將控制加熱器的關閉或打開方式。
這是一個圖表,顯示了一切將如何交互。
第 1 步 - 使用 Raspberry Pi 設置傳感器
獲得 DHT11 溫度和 PIR 運動傳感器后,是時候將其連接到 Raspberry Pi。
以下是如何連接 DHT11 溫度傳感器。我放棄了面包板并使用引腳 1(3V3)而不是引腳 2(5V)供電,從而偏離了圖表。
以下是如何連接 PIR 運動傳感器。LED 連接是可選的。我通過將 Gnd 連接到引腳 20(接地)而不是引腳 6(接地),輸出到引腳 36(GPIO 16)而不是引腳 8(GPIO 14)和 LED 連接到引腳 40(GPIO 21)而不是引腳 10(GPIO 15)。
兩者連接時的最終結果:
這里我的 PIR 傳感器連接到 GPIO 16,DHT11 連接到 GPIO4。溫度傳感器應放置在您想要獲得正確溫度的位置,而運動傳感器應朝向您通常所在的位置。
第 2 步 - 編寫代碼來測試傳感器
下面是測試運動傳感器的 Python 代碼(不要忘記在此處安裝 RPi.GPIO https://pypi.org/project/RPi.GPIO/ ):
import RPi.GPIO as GPIO
from time import sleep
GPIO.setmode(GPIO.BCM)
motion_pin = 16
led_pin = 21
GPIO.setup(motion_pin, GPIO.IN)
GPIO.setup(led_pin, GPIO.OUT)
print("Sensor initializing . . .")
sleep(2)
try:
no_motion_count = 0
while True:
if GPIO.input(motion_pin) == True:
print("Motion Detected!")
GPIO.output(led_pin, True)
sleep(4)
GPIO.output(led_pin, False)
no_motion_count = 0
else:
no_motion_count += 1
print(f"No Motion Count: {no_motion_count}")
sleep(1)
except KeyboardInterrupt:
pass
finally:
GPIO.output(led_pin, False)
GPIO.cleanup()
下面是測試溫度傳感器的 Python 代碼(不要忘記在此處安裝 Adafruit_DHT https://pypi.org/project/Adafruit_Python_DHT/ ):
import Adafruit_DHT
from time import sleep
temperature_humidity_sensor = Adafruit_DHT.DHT11
gpio_pin = 4
try:
while True:
humidity, temperature = Adafruit_DHT.read_retry(
temperature_humidity_sensor, gpio_pin)
if humidity is not None and temperature is not None:
print(
'Temp={0:0.1f}*C Humidity={1:0.1f}%'.format(temperature, humidity))
else:
print('Failed to get reading. Try again!')
sleep(0.5)
except KeyboardInterrupt:
pass
這是兩者結合的代碼:
import RPi.GPIO as GPIO
import Adafruit_DHT
from time import sleep
GPIO.setmode(GPIO.BCM)
# Motion
motion_pin = 16
led_pin = 21
no_motion_count = 0
GPIO.setup(motion_pin, GPIO.IN)
GPIO.setup(led_pin, GPIO.OUT)
def handle_motion(no_motion_count):
if GPIO.input(motion_pin) == True:
print("Motion Detected!")
GPIO.output(led_pin, True)
sleep(4)
GPIO.output(led_pin, False)
no_motion_count = 0
return 0
else:
return no_motion_count + 1
# Temperature + Humidity
temperature_humidity_sensor = Adafruit_DHT.DHT11
gpio_pin = 4
def handle_temperature():
humidity, temperature = Adafruit_DHT.read_retry(
temperature_humidity_sensor, gpio_pin)
if humidity is not None and temperature is not None:
print(
'Temperature = {0:0.1f}*C Humidity = {1:0.1f}%'.format(temperature, humidity))
return temperature
else:
print('Failed to read Temperature/Humidity')
# Run Program
print("Sensor initializing . . .")
sleep(5)
try:
no_motion_count = 0
desired_temperature = 28
desired_temperature_margin = 2
while True:
temperature = handle_temperature()
no_motion_count = handle_motion(no_motion_count)
if no_motion_count >= 20:
print(f"No Human Detected.")
elif temperature > desired_temperature + desired_temperature_margin:
print(f"Temperature Too High")
elif temperature < desired_temperature - desired_temperature_margin:
print(f"Temperature Too Low")
else:
print(f"Temperature Just Right")
print(f"No Motion Count: {no_motion_count}")
sleep(0.25)
except KeyboardInterrupt:
pass
finally:
GPIO.output(led_pin, False)
GPIO.cleanup()
第 3 步 - 開發 Flask API 以公開傳感器數據
在我們可以讓傳感器工作之后,它的服務時間是通過一個 API,在本例中是一個 Flask API。下面是重要的代碼,但請參考我的 GitHub 存儲庫https://github.com/sometheasiekswx/smart-heater-api-flask以查看所有代碼(不要忘記在此處安裝 Flask https://flask .palletsprojects.com/en/2.0.x/quickstart/和 Flask-CORS 在這里https://flask-cors.readthedocs.io/en/latest/ ):
from operator import itemgetter
from signal import signal, SIGINT
from sys import exit
from time import sleep
import RPi.GPIO as GPIO
from Adafruit_DHT import DHT11, read_retry
from flask import Flask
from flask_cors import CORS
GPIO.setmode(GPIO.BCM)
# Motion
motion_pin = 16
led_pin = 21
no_motion_count = 0
GPIO.setup(motion_pin, GPIO.IN)
GPIO.setup(led_pin, GPIO.OUT)
# Temperature + Humidity
temperature_humidity_sensor = DHT11
gpio_pin = 4
# Run Program
print("Sensor initializing . . .")
sleep(5)
app = Flask(__name__)
cors = CORS(app, resources={r"/api/*": {"origins": "*"}})
no_motion_count = 0
desired_temperature = 28
desired_temperature_margin = 2
@app.route("/api/v1/temperature")
def get_temperature():
humidity, temperature = read_retry(
temperature_humidity_sensor, gpio_pin)
if humidity is not None and temperature is not None:
return str(temperature)
return 'Unknown'
@app.route("/api/v1/motion")
def get_motion():
if GPIO.input(motion_pin):
GPIO.output(led_pin, True)
return "true"
GPIO.output(led_pin, False)
return "false"
def has_no_empty_params(rule):
defaults = rule.defaults if rule.defaults is not None else ()
arguments = rule.arguments if rule.arguments is not None else ()
return len(defaults) >= len(arguments)
@app.cli.command()
def routes():
'Display registered routes'
rules = []
for rule in app.url_map.iter_rules():
methods = ','.join(sorted(rule.methods))
rules.append((rule.endpoint, methods, str(rule)))
sort_by_rule = itemgetter(2)
for endpoint, methods, rule in sorted(rules, key=sort_by_rule):
route = '{:50s} {:25s} {}'.format(endpoint, methods, rule)
print(route)
@app.route("/")
def main():
return """
Smart Heater API
Endpoint
Method
Rule
get_motion
GET
/api/v1/motion
get_temperature
GET
/api/v1/temperature
"""
def cleanup(signal, frame):
print('Closing API...')
GPIO.output(led_pin, False)
GPIO.cleanup()
exit(0)
signal(SIGINT, cleanup)
在 Raspberry Pi 上添加代碼后,以下是如何運行代碼以及訪問在 Raspberry Pi 上設置的端點時應該得到的結果(嘗試從同一網絡上的不同設備訪問端點以測試是否CORS 策略正常工作):
第 4 步 - 使用 IFTTT 設置智能插頭
此步驟將根據您碰巧選擇的支持 WI-FI 的智能插頭品牌而有所不同。對我來說,我選擇了Powertech Wi-Fi Smart Plug ,這需要我使用Smart Life應用程序進行設置。無論您使用哪種品牌,請按照說明連接插頭。然后,轉到IFTTT ,創建一個帳戶,然后搜索 IFTTT 與您的智能插頭應用程序的集成。
設置兩個小程序。第一個觸發器是是否觸發了關閉加熱器的 GET 請求(事件名稱 temperature_high)。第二個觸發器是是否觸發了打開加熱器的 GET 請求(事件名稱 temperature_low)。
第 4 步 - 開發 React 前端來控制一切
最后,我們將開發這個漂亮的前端:
我使用 ReactJs 和 TailWindCss 來創建 Web 應用程序,因此它可以幫助您擁有這些技術的先前經驗。是幫助您入門的完美資源。您還可以使用您喜歡的任何其他框架(Angular、Laravel)或語言(HTML + CSS + JSS)來構建網站。
共有三張卡: 1. 溫度傳感器,顯示當前溫度,可以設置目標溫度 2. 運動傳感器,我們可以看到是否檢測到任何運動,如果太長時間沒有檢測到運動,我們可以自動關閉加熱器 3. 加熱器狀態為關閉或開啟,也可手動控制智能加熱器系統關閉。
這是我們從前端進行 API 調用的示例:
import axios from 'axios';
const sensorsApi = axios.create({
baseURL: `http://${process.env.REACT_APP_API_HOST}:${process.env.REACT_APP_API_PORT}/api/v1/`,
});
const heaterApi = axios.create({
baseURL: `https://maker.ifttt.com/trigger/`,
});
export const turnOffHeater = async () => {
try {
await heaterApi.get(`temperature_high/with/key/${process.env.REACT_APP_IFTTT_WEBHOOK_KEY}`);
} catch (error) {
console.log(error.message);
}
}
export const turnOnHeater = async () => {
try {
await heaterApi.get(`temperature_low/with/key/${process.env.REACT_APP_IFTTT_WEBHOOK_KEY}`);
} catch (error) {
console.log(error.message);
}
}
export const getTemperature = async () => {
try {
const data = (await sensorsApi.get('temperature')).data;
return parseFloat(data);
} catch (error) {
console.log(sensorsApi)
console.log(error.message);
}
}
export const getMotion = async () => {
try {
const data = (await sensorsApi.get('motion')).data;
return data === 'true';
} catch (error) {
console.log(error.message);
}
}
這是我如何使用這些異步函數的示例。它還顯示加熱器將根據它是否低于或高于目標溫度來打開和關閉。
import {useEffect, useState} from "react";
import {getMotion, getTemperature, turnOffHeater, turnOnHeater} from "../utils/api";
import {CronJob} from "cron";
function Devices() {
const [currentTemperature, setCurrentTemperature] = useState(0);
const [targetTemperature, setTargetTemperature] = useState(25);
const [targetTemperatureMargin] = useState(2);
const [heaterOn, setHeaterOn] = useState(false);
const handleTemperature = async () => {
const temperature = await getTemperature();
setCurrentTemperature(temperature);
console.log(currentTemperature, targetTemperature);
if (currentTemperature >= targetTemperature + targetTemperatureMargin && heaterOn) {
await turnOffHeater();
setHeaterOn(false);
} else if (currentTemperature <= targetTemperature - targetTemperatureMargin && !heaterOn) {
await turnOnHeater();
setHeaterOn(true);
}
}
const [jobTemperature] = useState(new CronJob("* * * * * *", handleTemperature()));
以下是運動邏輯的設置方式:
const handleMotion = async () => {
const newMotion = await getMotion();
if (newMotion === false) {
setNoMotion(noMotion + 1)
} else {
setNoMotion(0)
setMotion(true);
}
if (noMotion > 50) {
setMotion(false);
}
}
最后的想法
我在這里只展示重要的代碼,你可以在附件中找到整個前端和后端代碼庫,以及完成這個項目所需的電子設備和傳感器。祝你好運!
- PTC加熱器 REV1
- 康普茶加熱器開源分享
- 帶PID溫度控制的加熱器開源分享
- 脈沖感應加熱器開源分享
- 煒固專業級單相加熱器斷線報警器US17資料 10次下載
- 加熱器短線報警器原理、分類和選型 5次下載
- 開源硬件-TIDA-01184-適用于座椅加熱器的智能電源開關 PCB layout 設計
- 透明加熱器的應用
- 浸沒式汽水混合加熱器
- 國產300MW高壓加熱器泄漏原因分析及預防措施
- 超臨界高壓加熱器研制
- 大客車液體加熱器安裝要點
- 風暖加熱器油煙味產生的原因及其改進方法
- 國內外汽車燃油加熱器技術比較及發展
- 實用高精度智能恒溫加熱器系統設計
- 功率放大器在微型加熱器中的應用 941次閱讀
- 【電磁兼容技術案例分享】某車載PTC加熱器輻射發射低頻整改案例 1322次閱讀
- 使用MOSFET作為恒溫加熱器 1154次閱讀
- 電烙鐵的加熱器的結構組成與溫度控制方法分析 9294次閱讀
- 低壓加熱器工作原理_低壓加熱器的作用 1.8w次閱讀
- 恒溫加熱器的工作原理_恒溫加熱器保養 1.8w次閱讀
- 汽車駐車加熱器的工作原理詳解 3.5w次閱讀
- 如何正確使用防爆電加熱器 4000次閱讀
- 電加熱器的分類及對比 9637次閱讀
- 一文了解電加熱器是什么 5969次閱讀
- 電加熱器功率計算方法 6w次閱讀
- 簡易加熱器制作 1.7w次閱讀
- PTC加熱器原理及功能 23.6w次閱讀
- 用于植物的土壤加熱器 3770次閱讀
- 加熱器控制電路圖 2.6w次閱讀
下載排行
本周
- 1使用單片機實現七人表決器的程序和仿真資料免費下載
- 2.96 MB | 44次下載 | 免費
- 2聯想E46L DAOLL6筆記本電腦圖紙
- 1.10 MB | 2次下載 | 5 積分
- 3MATLAB繪圖合集
- 27.12 MB | 2次下載 | 5 積分
- 4PR735,使用UCC28060的600W交錯式PFC轉換器
- 540.03KB | 1次下載 | 免費
- 5UCC38C42 30W同步降壓轉換器參考設計
- 428.07KB | 1次下載 | 免費
- 6DV2004S1/ES1/HS1快速充電開發系統
- 2.08MB | 1次下載 | 免費
- 7模態分解合集matlab代碼
- 3.03 MB | 1次下載 | 2 積分
- 8美的電磁爐維修手冊大全
- 1.56 MB | 1次下載 | 5 積分
本月
- 1使用單片機實現七人表決器的程序和仿真資料免費下載
- 2.96 MB | 44次下載 | 免費
- 2UC3842/3/4/5電源管理芯片中文手冊
- 1.75 MB | 15次下載 | 免費
- 3DMT0660數字萬用表產品說明書
- 0.70 MB | 13次下載 | 免費
- 4TPS54202H降壓轉換器評估模塊用戶指南
- 1.02MB | 8次下載 | 免費
- 5STM32F101x8/STM32F101xB手冊
- 1.69 MB | 8次下載 | 1 積分
- 6HY12P65/HY12P66數字萬用表芯片規格書
- 0.69 MB | 6次下載 | 免費
- 7華瑞昇CR216芯片數字萬用表規格書附原理圖及校正流程方法
- 0.74 MB | 6次下載 | 3 積分
- 8華瑞昇CR215芯片數字萬用表原理圖
- 0.21 MB | 5次下載 | 3 積分
總榜
- 1matlab軟件下載入口
- 未知 | 935119次下載 | 10 積分
- 2開源硬件-PMP21529.1-4 開關降壓/升壓雙向直流/直流轉換器 PCB layout 設計
- 1.48MB | 420061次下載 | 10 積分
- 3Altium DXP2002下載入口
- 未知 | 233084次下載 | 10 積分
- 4電路仿真軟件multisim 10.0免費下載
- 340992 | 191367次下載 | 10 積分
- 5十天學會AVR單片機與C語言視頻教程 下載
- 158M | 183335次下載 | 10 積分
- 6labview8.5下載
- 未知 | 81581次下載 | 10 積分
- 7Keil工具MDK-Arm免費下載
- 0.02 MB | 73807次下載 | 10 積分
- 8LabVIEW 8.6下載
- 未知 | 65987次下載 | 10 積分
評論
查看更多