---
# System prepended metadata

title: 2025 Microprocessor Final Project Group7

---

# 2025 Microprocessor Final Project
contributed by Group7 (柯智幃, 陳睿謙, 鄭誌恩, 莊凱程)

## 一、系統功能與原理說明

我們的期末專案旨在建構一套自動化的防災原型系統，整合了紅外線(火焰)感測器、機電(伺服馬達、沉水幫浦)控制、微處理器邏輯與監控介面。系統運作流程分為四個主要階段：偵測警報、定位追蹤、瞄準滅火以及資料回傳。

### 自動偵測與警報

系統利用紅外線感測器結合 PIC18F4520 ADC 模組持續監測環境。當 ADC 數值低於設定閾值時，程式立即判定為火災狀態並觸發蜂鳴器示警，確保能在第一時間察覺災害發生。

### 火源定位與追蹤

透過 Timer0 中斷精確控制第一個伺服馬達 (Servo 1)，使其在角度 -90° ~ +90° 間進行週期性掃描。此機制讓感測器能主動覆蓋前方半圓形區域，動態搜尋並鎖定潛在的熱源位置。

### 自動瞄準與滅火

一但偵測到火源，系統會立即暫停掃描 (Servo 1) 並鎖定當前方位，隨即啟動第二個伺服馬達轉向火源位置 (Servo 2) ，並啟動沉水幫浦 (Motor 3) 精準對準火源進行撲滅，直到感測數值回升至安全範圍才停止運作。

### 資料分析與輸出

微控制器將角度、火焰數值與狀態封裝為 JSON 格式，經 UART 介面傳送至電腦。PC 端執行 Python Streamlit 儀表板，即時解析數據並繪製溫度與角度圖表，實現遠端視覺化監控。

![Dashboard](https://hackmd.io/_uploads/r1nq3wGmWl.png)

## 二、系統使用環境及對象

系統設計於居家、實驗室或小型倉儲等室內平坦環境。運作時需避免太陽直射或強光干擾，以確保紅外線感測準確度。同時需透過 USB 連接電腦進行供電與 UART 資料傳輸，維持監控連線。透過電腦端的圖形化儀表板 (Dashboard)，即可直觀監控環境數值、掌握火源方位並接收即時警報。

## 三、系統完整架構圖、流程圖、電路圖、設計

### 系統完整架構圖

```graphviz
digraph system_architecture {
    rankdir=LR;
    label = "系統完整架構圖";
    fontname="Sans-Serif";
    
    node [shape=record, style="filled,rounded", fontname="Sans-Serif", fontsize=10, margin=0.2];
    edge [fontname="Sans-Serif", fontsize=9];

    subgraph cluster_inputs {
        label = "Input Layer";
        style = dashed;
        color = "#82b366";
        fontcolor = "#82b366";
        
        node [fillcolor="#d5e8d4", color="#82b366"];
        sensor [label="{ 火焰傳感器 }"];
        btn    [label="{ 按鈕 }"];
    }

    subgraph cluster_PC {
        label = "PC Dashboard";
        style = dashed;
        color = "#6c8ebf";
        fontcolor = "#6c8ebf";
        
        node [fillcolor="#dae8fc", color="#6c8ebf"];
        pc [label="{ <json> JSON \n Parser | <py> Python \n Streamlit }"];
    }
    
    subgraph cluster_MCU {
        label = "PIC18F4520 ";
        style = dashed;
        color = "#d79b00";
        fontcolor = "#d79b00";
        
        node[fillcolor="#ffe6cc", color="#d79b00"]
        mcu [label="{ { <ADC> ADC | <In> Input } | <uart> UART | { <PWM> PWM | <Out> Output } }"];
    }

    subgraph cluster_outputs {
        label = "Output Layer";
        style = dashed;
        color = "#b85450";
        fontcolor = "#b85450";
        
        node [fillcolor="#f8cecc", color="#b85450"];
        motor1 [label="{ 伺服馬達 (Servo 1) \n (掃描) }"];
        motor2 [label="{ 伺服馬達 (Servo 2) \n (對準目標) }"];
        motor3 [label="{ 沉水幫浦 (Motor 3) \n (抽水)}"];
        alert [label="{ 蜂鳴器 \n (警報) }"];
        leds  [label="{ LED \n (方位判讀) }"];
    }

    sensor:e -> mcu:ADC:w  [color="green"];
    btn:e -> mcu:In:w      [color="green"];
    mcu:PWM:n -> motor1:w  [color="orange"];
    mcu:PWM:e -> motor2:w  [color="orange"];
    mcu:Out:e -> motor3:w  [color="blue"];
    mcu:Out:s -> alert:w   [color="blue"];
    mcu:Out:s -> leds:w    [color="blue"];
    pc:py:e -> mcu:uart:s [color="purple", dir="back"];
}
```

### 流程圖

```graphviz
digraph software_flowchart {
    rankdir=TB;
    nodesep=0.7;
    label = "流程圖";
    fontname="Sans-Serif";

    node [fontname="Sans-Serif", fontsize=10];
    
    node [shape=ellipse, style="filled", fillcolor="#e1d5e7", color="#9673a6"];
    Start [label="系統啟動\n(Start)"];

    node [shape=box, style="filled", fillcolor="#dae8fc", color="#6c8ebf"];
    Init [label="系統初始化\n(System Initialize)\n UART, ADC, PWM, Timer0, IO"];
    MainLoop [label="進入主迴圈(While)"];
    ReadSensors [label="讀取感測器數據\n ADC (火焰), IO (按鈕)"];
    Calc [label="資料處理\n 換算角度，判斷火災狀態"];
    
    node [shape=diamond, style="filled", fillcolor="#ffe6cc", color="#d79b00"];
    IsFire [label="是否偵測到火源?\n(ADC < 400)"];
    IsSafe [label="是否安全?\n(ADC > 600)"];
    CheckMsg [label="傳送資料?\n(per 0.25 sec)"];
    
    node [shape=box, style="filled, rounded", fillcolor="#f8cecc", color="#b85450"];
    FireAction [label="執行滅火程序\n- 停止掃描 (Run=0)\n- 鎖定目標\n- 啟動沉水幫浦/蜂鳴器"];
    SafeAction [label="恢復監控模式\n- 啟動掃描 (Run=1)\n- 關閉沉水幫浦/蜂鳴器"];
    SendUART [label="UART 資料傳輸\n- JSON 格式封包\n- 更新 PC Dashboard"];

    subgraph cluster_isr {
        label = "Timer0 中斷 (ISR)";
        style = dashed;
        color = "#82b366";
        fontcolor = "#82b366";
        
        node [fillcolor="#d5e8d4", color="#82b366"];
        ISR_Start [shape=ellipse, label="TMR0 中斷發生"];
        ISR_Count [label="計數器累加\n(Timing Control)"];
        ISR_Scan [label="伺服馬達掃描\n(Update Servo Angle)"];
        ISR_End [shape=ellipse, label="返回主程式"];
    }

    Start:s -> Init:n;
    Init:s-> MainLoop:n;
    MainLoop:s -> ReadSensors:n;
    ReadSensors:w -> Calc:n       [label="trigger", fontcolor="red"];
    Calc:s -> IsFire:n;
    IsFire:s -> FireAction:n      [label="Yes (Fire!)", fontcolor="red"];
    IsFire:w -> IsSafe:n          [label="No"];
    IsSafe:s -> SafeAction:n      [label="Yes (Safe!)", fontcolor="green"];
    IsSafe:w -> CheckMsg:w        [label="No \n(Keep State!)"];
    FireAction:s -> CheckMsg:n;
    SafeAction:s -> CheckMsg:w;
    CheckMsg:s -> SendUART:n      [label="Yes"];
    CheckMsg:e -> ReadSensors:s   [label="No"];
    SendUART:e -> ReadSensors:e;
    ISR_Start:s -> ISR_Count:n;
    ISR_Count:s -> ISR_Scan:n;
    ISR_Scan:s -> ISR_End:n;

    { rank=same; MainLoop; ISR_Start }
}
```

### 電路圖

```graphviz
digraph hardware_wiring {
    rankdir=LR;
    nodesep=0.5;
    ranksep=1.5;
    bgcolor="white";
    label = "PIC18F4520 + 外接硬體 電路圖";
    fontname="Sans-Serif";

    node [fontname="Sans-Serif", fontsize=10, style="filled"];
    edge [fontname="Sans-Serif", fontsize=9];

    subgraph cluster_MCU {
        label = "PIC18F4520";
        style = dashed;
        color = "#d79b00";
        fontcolor = "#d79b00";
        
        node [shape=record, fillcolor="#fff2cc", color="#d6b656"];
        pic [label="{ {  <RA0> RA0 | <RB0> RB0 | <RC1> RC1 (CCP2) | <RC2> RC2 (CCP1) } | { <RD0> RD0 | <RD1> RD1  | <vcc> VDD (5V) | <gnd> VSS (GND)  | <RC6> RC6 (TX) | <RC7> RC7 (RX)  |  <RD4to7> RD4~RD7 } }"];
    }

    node [shape=record, style="filled,rounded", fillcolor="#e1d5e7", color="#9673a6"];
    sensor [label="{4pin\n火焰感測器 | { <AO> (Analog Out) | <DO> (Digital Out)} }", fillcolor="#d5e8d4"];
    btn    [label="2pin\n按鈕開關", fillcolor="#d5e8d4"];
    servo1 [label="3pin\nServo 1\n(掃描馬達)", fillcolor="#dae8fc"];
    servo2 [label="3pin\nServo 2\n(瞄準馬達)", fillcolor="#dae8fc"];
    buzzer [label="2pin\n蜂鳴器", fillcolor="#f8cecc"];
    TIP122 [label="{{ <B> B | <C> C | <E> E } | 3pin\nTIP122}", fillcolor="#f8cecc"];
    leds   [label="2pin\nLED (x4)", fillcolor="#dae8fc"];
    pc_usb [label="USB-TTL\n轉接器", fillcolor="#bac8d3"];

    sensor:AO:e -> pic:RA0:w  [color="green"];
    sensor:DO:e -> pic:RB0:w  [color="green"];
    btn:e -> pic:RB0:w     [color="green"];
    servo1:e -> pic:RC2:w  [color="orange", dir="back"];
    servo2:e -> pic:RC1:w  [color="orange", dir="back"];
    pic:RD0:e -> buzzer:w  [color="blue"];
    pic:RD1:e -> TIP122:B:w  [color="blue"];
    pic:vcc:e -> pc_usb:w [color="red", dir="back"];
    pic:gnd:e -> pc_usb:w [color="black", dir="back"];
    pic:RC6:e -> pc_usb:w  [color="green"];
    pc_usb:w -> pic:RC7:e  [color="gray"];
    pic:RD4to7:e -> leds:w    [color="blue"];
}
```

```graphviz
digraph hardware_wiring {
    rankdir=LR;
    label = "TIP122 + Motor 3 + 6V Power Supply 電路圖";
    fontname="Sans-Serif";

    node [fontname="Sans-Serif", fontsize=10, style="filled"];
    edge [fontname="Sans-Serif", fontsize=9];

    node [shape=record, fillcolor="#fff2cc", color="#d6b656"];
    pic [label="{ PIC18F4520 | {<RD1> RD1 | <gnd> VSS (GND)} }"];

    node [shape=record, style="filled,rounded", fillcolor="#e1d5e7", color="#9673a6"];
    pwr [label="6V Power\nSupply", shape=cylinder, fillcolor="#f8cecc"];
    TIP122 [label="{{ <B> B | <C> C | <E> E } | 3pin\nTIP122}", fillcolor="#f8cecc"];
    motor3 [label="2pin\nMotor 3\n(沉水幫浦)", fillcolor="#dae8fc"];
    
    pic:RD1:e -> TIP122:B:w   [color="blue"];
    motor3:s -> pwr:w         [color="red", dir="back"];
    motor3:e -> TIP122:C:w    [color="black", dir="back"];
    pwr:e -> TIP122:E:w       [color="black"]
    TIP122:E:w -> pic:gnd:e   [color="black"]
    
}
```

## 四、系統開發工具、材料及技術

### 系統開發工具

MPLAB X IDE、MPLAB® PICkit 4、Python Streamlit

### 材料

- PIC18F4520
- SG90伺服馬達 * 2
- 4Pin火焰傳感器模組
- 蜂鳴器
- TIP122達林頓電晶體
- 沉水幫浦+矽膠軟管
- 6V外接電池盒
- 打火機
- Button、LED、杜邦線、鱷魚夾、電阻...

### 技術

#### 單元項目舉例：

- [x] Interrupt 
- [x] Timer 
- [x] PWM 
- [x] UART 
- [x] ADC 
- [ ] SPI 

#### 進階單元項目舉例：

- [x] 使用更多外部周邊，電子硬體元件(火焰感測器、蜂鳴器、沉水幫浦、TIP122達林頓電晶體)
- [ ] 能減少耗電、增加效率之軟硬體應用及演算法
- [x] 整合性、專題完整性、創新性

## 五、實際組員之分工項目

| 組員 | 分工項目 |
|:------ |:----------- |
| 柯智幃 | 伺服馬達與時脈設置、材料採購 |
| 陳睿謙 | 前端介面設計、類比輸出設置 |
| 鄭誌恩 | UART設置、蜂鳴器驅動與LED顯示、系統測試 |
| 莊凱程 | 系統架構設計、電路硬體整合、材料採購、報告撰寫 |

## 六、遇到的困難及如何解決

### 電源供應不足問題

對於同一個電壓 (筆電接出) 供應至多個設備 (PIC18F4520、火焰感測器、伺服馬達、蜂鳴器) ，分散輸出導致引腳電流太小，容易有供電不穩的情形。因此將沉水幫浦外接6V電源，單獨供電，並使用TIP122電晶體來作為電子開關，以小電流控制大電流，保護微處理器安全。

### 驅動沉水幫浦的電流供應

一開始使用碳鋅電池時，發現沉水幫浦雖然有過電聲響但無法順利抽水，且系統運作不穩。因為沉水幫浦啟動時的瞬時電流需求極大，碳鋅電池的放電能力與續航力不足以支撐。我們將電源更換為高能量密度且低內阻的鹼性電池後，成功解決了瞬間壓降導致的啟動失敗問題。

### 沉水幫浦的運作問題

即使沉水幫浦馬達正常運轉，但若矽膠軟管或幫浦內存有空氣，葉片會因為在空氣中空轉而無法產生足夠的負壓，導致無法出水。我們將這種非自吸式的設計，在啟動前手動將矽膠管充滿水以排出空氣(預先灌水)，讓幫浦葉片能順利推動水流。

## 七、程式碼與影片

[程式碼](https://github.com/KyntonKCC/NCKU_114-1_Microprocessor_Final_Project)
[影片](https://www.youtube.com/shorts/g-ZNsFBYXuA)