隨著物聯網技術的發展,居家安全系統也日益智慧化。本文介紹的智慧居家安全鎖系統,結合了 PIR 感測器、鍵盤輸入和 MQTT 通訊,實作門禁控制和即時警示通知。系統核心為 ESP32,負責感測運動、驗證密碼,並將結果透過 MQTT 傳輸至作為霧端節點的 Jetson Nano。Jetson Nano 接收到訊息後,透過 Twilio 雲端服務傳送 WhatsApp 通知給屋主,實作遠端監控和警示。此外,本文也介紹了根據 ESP32-CAM 和 MQ-4 感測器的火災警示系統,同樣利用 MQTT 和 Twilio,實作火災偵測和即時警示功能,提升居家安全保障。

5.6 FoG 與雲端運算例項

5.6.2.2 居家安全鎖設計

安全是任何家庭最重要的需求。隨著物聯網(IoT)的發展,人們可以為門鎖新增連網功能。在此,作者設計了一款智慧居家安全鎖,能夠與屋主進行溝通,並在有人進入房屋時通知屋主,無論是合法進入還是入侵者嘗試進入。

該系統使用ESP32 Wi-Fi模組組態IoT節點,並搭配電磁鎖。當PIR感測器偵測到運動時,IoT節點會提示使用者輸入密碼。只有當密碼正確時,鎖才會開啟,使用者才能進入房屋。合法或非法進入的狀態會透過MQTT協定向組態為FoG節點的Jetson Nano SBC報告。然後,FoG節點會利用Twilio雲端平台透過WhatsApp向屋主傳送警示訊息。

系統設計與連線

圖5.21展示了居家安全鎖的概念圖和針腳圖。表5.3詳細列出了居家安全鎖的針腳連線。

ESP32 Wi-Fi模組鍵盤電平轉換器輸入
VCC--
GND--
3V3-LV
GND-GND
D15-LV1
D13ROW 1-
D12ROW 2-
D14ROW 3-
D27ROW 4-
D26COL 1-
D23COL 2-
D33COL 3-
D32COL 4-
電平轉換器輸出繼電器模組
HO5 V(電源供應)
HO1IN
GNDGND
繼電器模組電磁鎖 12 V 電源供應
-RED PIN + PIN(紅色)
NO- PIN(黑色)
COMGND PIN -

MQTT組態與程式碼實作

要在ESP32 Wi-Fi模組上組態MQTT,請遵循5.6.2.1節中給出的步驟。這包括連線到由Jetson Nano SBC主機的熱點。

ESP32是客戶端,將感測器資料釋出到名為’password_verify’的主題。FoG節點,即Jetson Nano SBC,將是代理和客戶端。在FoG節點上執行的Python MQTT客戶端將訂閱’password_verify’主題並收集結果。

ESP32端程式碼
from machine import Pin
from time import sleep
from umqtt.simple import MQTTClient
import time
import machine
import network

# 組態Wi-Fi連線
station = network.WLAN(network.STA_IF)
station.active(True)
station.connect("jetson-desktop", "11111111")

# 定義鍵盤相關引數
KEY_UP = const(0)
KEY_DOWN = const(1)
keys = [['1', '2', '3', 'A'], ['4', '5', '6', 'B'], ['7', '8', '9', 'C'], ['*', '0', '#', 'D']]
rows = [13, 12, 14, 27]
cols = [26, 25, 33, 32]

# 初始化行和列的Pin
row_pins = [Pin(pin_name, mode=Pin.OUT) for pin_name in rows]
col_pins = [Pin(pin_name, mode=Pin.IN, pull=Pin.PULL_DOWN) for pin_name in cols]

def init():
    for row in range(0, 4):
        for col in range(0, 4):
            row_pins[row].value(0)

def scan(row, col):
    """掃描鍵盤"""
    row_pins[row].value(1)
    key = None
    if col_pins[col].value() == KEY_DOWN:
        key = KEY_DOWN
    if col_pins[col].value() == KEY_UP:
        key = KEY_UP
    row_pins[row].value(0)
    return key

SERVER = '10.42.0.1'  # MQTT伺服器位址
CLIENT_ID = 'ESP32'
TOPIC = b'password_verify'
client = MQTTClient(CLIENT_ID, SERVER)
client.connect()  # 連線到MQTT代理

Motion_status = False  # 用於儲存運動感測器狀態的全域變數

def handle_interrupt(Pin):
    global Motion_status
    Motion_status = True

lock = Pin(15, Pin.OUT)  # 設定GPIO14 LED為輸出
PIR_Interrupt = Pin(34, Pin.IN)  # 設定GPIO13 PIR_Interrupt為輸入
PIR_Interrupt.irq(trigger=Pin.IRQ_RISING, handler=handle_interrupt)

password = ['1', '0', '0', '0']
input_pass = ['0', '0', '0', '0']

def password_verify():
    print('請輸入密碼')
    break_loop = 0
    i = 0
    while i < 4:
        while break_loop == 0:
            for row in range(4):
                for col in range(4):
                    key = scan(row, col)
                    if key == KEY_DOWN:
                        print("按鍵按下", keys[row][col])
                        time.sleep(0.5)
                        last_key_press = keys[row][col]
                        break_loop = 1
            break_loop = 0
        input_pass[i] = last_key_press
        i = i + 1
    init()
    if input_pass == password:
        print('正確')
        lock.value(0)

lock.value(1)  # 初始化鎖定狀態

while True:
    if Motion_status:
        print('偵測到運動!')
        password_verify()
        print(input_pass)

#### 程式碼解析:

  1. Wi-Fi 連線設定:程式碼首先設定ESP32的Wi-Fi連線,連線到由Jetson Nano SBC建立的熱點。

  2. 鍵盤掃描功能:定義了鍵盤的行和列,並實作了掃描鍵盤的功能,用於檢測按鍵操作。

  3. MQTT 連線:建立了與MQTT代理的連線,用於發布感測器資料到指定的主題。

  4. 中斷處理:設定了PIR感測器的中斷處理函式,當偵測到運動時觸發。

  5. 密碼驗證:實作了密碼驗證功能,使用者輸入密碼後與預設密碼進行比對,正確則解鎖。

圖表翻譯:

此圖示展示了居家安全鎖系統的流程,包括偵測運動、驗證密碼以及控制電磁鎖的過程。

Jetson Nano端的MQTT客戶端程式碼範例(參考用)

import paho.mqtt.client as mqtt

def on_connect(client, userdata, flags, rc):
    print("Connected with result code "+str(rc))
    client.subscribe('password_verify')

def on_message(client, userdata, msg):
    print(msg.payload.decode())

client = mqtt.Client()
client.on_connect = on_connect
client.on_message = on_message
client.connect('localhost', 1883, 60)
client.loop_forever()

#### 程式碼解析:

  1. MQTT 連線:Jetson Nano作為MQTT客戶端,連線到本地MQTT代理。
  2. 主題訂閱:訂閱了password_verify主題,用於接收ESP32發布的密碼驗證結果。
  3. 訊息處理:當接收到訊息時,列印預出訊息內容。

5.6 霧端運算與雲端運算例項

5.6.2.1 設定 Jetson Nano (霧端節點) 以支援 MQTT 和 Twilio 雲端服務

在智慧居家安全鎖系統中,ESP32 開發板被用作 IoT 節點,負責驗證使用者輸入的密碼。如果密碼正確,ESP32 會開啟電子鎖並傳送 MQTT 訊息給 Jetson Nano (霧端節點),告知其已驗證透過。

程式碼範例:ESP32 傳送 MQTT 訊息

t = 1.0  # 1.0 表示驗證完成,解鎖
if isinstance(t, float):  # 確認感測器結果為數值
    msg = (b'{0:3.1f}'.format(t))
    client.publish(TOPIC, msg)  # 發布資料到 MQTT 主題
    print(msg)
else:
    print('無效的感測器讀數。')
sleep(10)
lock.value(1)
Motion_status = False

內容解密:

  1. 變數 t 的設定t = 1.0 表示驗證已完成並解鎖。
  2. 檢查資料型態:使用 isinstance(t, float) 來確認 t 是否為浮點數,以確保資料的有效性。
  3. MQTT 發布訊息client.publish(TOPIC, msg) 將格式化後的訊息發布到指定的 MQTT 主題。
  4. 輸出與控制:根據驗證結果進行輸出與控制,例如列印訊息、控制鎖的狀態。

5.6.2.2 Jetson Nano (霧端節點) 處理 MQTT 訊息並傳送 WhatsApp 通知

當 Jetson Nano (霧端節點) 接收到 ESP32 傳送的 MQTT 訊息後,會根據訊息內容判斷是否為授權使用者,並透過 Twilio 雲端服務傳送 WhatsApp 通知給屋主。

程式碼範例:Jetson Nano 處理 MQTT 訊息

import paho.mqtt.client as mqtt
from twilio.rest import Client

# 設定 Twilio 使用者資訊
twilio_client = Client('AC230101cb426d251b82479e33a992c149', '1d55483a6ab87ed20eac8531d70650c4')
from_whatsapp_number = 'whatsapp:+14155238886'
to_whatsapp_number = 'whatsapp:+91705750xxxx'

def on_message(client, userdata, msg):
    z = [float(x) for x in msg.payload.decode("utf-8").split(',')]
    if z[0] == 1.0:
        message = twilio_client.messages.create(body='授權人員進入', from_=from_whatsapp_number, to=to_whatsapp_number)
        print(message.sid)

client = mqtt.Client()
client.on_message = on_message
client.connect('localhost', 1883, 60)
client.loop_forever()

內容解密:

  1. MQTT 訊息處理on_message 回呼函式處理接收到的 MQTT 訊息,並解析其內容。
  2. Twilio WhatsApp 通知:根據解析結果,使用 Twilio API 傳送 WhatsApp 通知給屋主。
  3. 使用者端設定:設定 Twilio 使用者帳號和 WhatsApp 號碼,用於傳送通知。

5.6.2.3 火災警示系統

火災警示系統利用 ESP32-CAM 和 MQ-4 感測器模組來偵測煙霧濃度。當偵測到火災時,ESP32-CAM 會透過 MQTT 通訊協定向 Jetson Nano (霧端節點) 傳送警示訊息,後者再透過 Twilio 傳送 WhatsApp 警示通知給屋主。

程式碼範例:ESP32-CAM 傳送煙霧警示

import network
from machine import Pin
from umqtt.simple import MQTTClient

station = network.WLAN(network.STA_IF)
station.active(True)
station.connect("jetson-desktop", "11111111")

MQ4 = Pin(13, Pin.IN)  # 設定 GPIO13 為輸入

while True:
    if MQ4.value() == 0:
        smoke_status = True
    if smoke_status:
        t = 1.0  # 表示偵測到煙霧
        msg = (b'{0:3.1f}'.format(t))
        client.publish(TOPIC, msg)  # 發布煙霧警示到 MQTT 主題
        print(msg)
        sleep(5)
        smoke_status = False

圖表翻譯:

此圖示說明瞭火災警示系統的架構,包括 ESP32-CAM、MQ-4 感測器模組和 Jetson Nano 之間的連線與通訊流程。

內容解密:

  1. 煙霧偵測:MQ-4 感測器模組用於偵測空氣中的煙霧濃度。
  2. MQTT 通訊:ESP32-CAM 將煙霧狀態透過 MQTT 通訊協定發布到指定的主題。
  3. 狀態更新:根據煙霧偵測結果更新狀態變數 smoke_status,並在偵測到煙霧時傳送警示訊息。