2026年2月25日 星期三

習題解答 (5/6)

 

第五章 習題解答

一、 錯誤偵測技術

1. 何謂循環冗餘檢查法 (CRC)? 是一種根據傳輸資料產生簡短固定位數校驗碼的演算法。發送端將資料除以一個特定的多項式,得到的「餘數」即為 CRC 碼並隨資料發送;接收端以同樣多項式除之,若餘數為 0 則代表資料傳輸正確。

2. 何謂縱向冗餘檢查法 (LRC)? 這是一種簡單的校驗方式。它將一組資料區塊按位元進行異或 (XOR) 運算,產生一個校驗位元組。雖然計算簡單,但偵測多位元同時出錯的能力較 CRC 弱。


二、 RFID 碰撞問題 (Collision)

3. 何謂讀取器對讀取器的干擾? 當多個讀取器的訊號涵蓋範圍重疊時,一個讀取器發出的高頻訊號會干擾到另一個讀取器接收標籤回傳的微弱訊號,導致讀取失敗。

4. 何謂電子標籤的碰撞? 當多個電子標籤同時位於同一個讀取器的感應範圍內,並同時嘗試發送資料時,訊號會在空中互相重疊干擾,導致讀取器無法辨識任何一個標籤。


三、 防止碰撞方法 (Anti-collision)

5. 試說明電子標籤防止碰撞的四種基本方法?

  • 空分多重存取 (SDMA): 利用定向天線或空間分割,限制讀取器一次只與特定區域的標籤通訊。

  • 頻分多重存取 (FDMA): 讓不同標籤使用不同的頻率通道進行傳輸。

  • 碼分多重存取 (CDMA): 利用不同的展頻編碼來區分不同的標籤訊號。

  • 時分多重存取 (TDMA): 將時間分成多個時段,讓標籤在不同的時間點傳送資料。

6. 在電子標籤的防止碰撞方法中,最常用的是哪一種? 時分多重存取 (TDMA)。因為它不需要複雜的天線設計或多個頻段,成本最低且效率穩定,是目前主流 RFID 標準(如 EPC Global)採用的方式。


四、 TDMA 與演算法細節

7. 在時間分割多重存取中,何謂讀取器驅動式 (Reader Driven)? 由讀取器主導通訊。讀取器發出指令詢問標籤,標籤被動回應。讀取器會控制通訊的節奏與優先順序,這在被動式 RFID 系統中最為常見。

8. 在時間分割多重存取中,何謂電子標籤驅動式 (Tag Driven)? 由標籤主動發起通訊。標籤進入讀取器範圍後,會主動嘗試發送資料(如 ALOHA 協議)。讀取器僅扮演接收與管理的角色,通常用於主動式標籤系統。

9. 何謂 Tree Algorithm (樹狀演算法)? 這是一種確定性的防止碰撞演算法。讀取器將標籤的 ID 視為樹狀結構,透過逐位元詢問(例如:ID 開頭為 0 的請回應,接著 00 的請回應...),像修剪樹枝一樣排除衝突,直到找出唯一的標籤。

10. 何謂 Splitting Method (分裂法)? 這是樹狀演算法的一種核心邏輯。當發生碰撞時,將參與碰撞的標籤群組「分裂」成兩個或多個較小的子群組(例如隨機分配到不同的時槽),反覆進行直到每個子群組只剩一個標籤。


1. 循環冗餘檢查 (CRC): 利用多項式除法產生餘數作為檢查碼,偵錯能力極強。

2.縱向冗餘檢查 (LRC): 對資料區塊進行逐位元 XOR 運算的簡易檢驗法。

3.讀取器對讀取器干擾: 重疊區域內的讀取器訊號互相蓋過,使標籤無法正確接收。

4.電子標籤碰撞: 多個標籤同時回傳資料,導致訊號在空中疊加成雜訊。

5.防止碰撞四種方法: SDMA (空間)、FDMA (頻率)、CDMA (編碼)、TDMA (時間)。

6.最常用方法: TDMA (時間分割多重存取)

7.讀取器驅動式 (Reader Driven): 讀取器主動點名或詢問,標籤被動回答。

8.電子標籤驅動式 (Tag Driven): 標籤一進入場域就主動發送資料(如 Aloha 系統)。

9.Tree Algorithm (樹狀演算法): 透過二元搜尋(Binary Search)逐位元篩選標籤 ID,直到找出唯一標籤。 

10. Splitting Method (分裂法): 碰撞發生時,將標籤隨機或依序分成小組,縮小範圍直到碰撞消失。


第六章 習題解答


1. 說明何謂「壹位元射頻系統」?

這是一種最簡單的 RFID 應用,通常稱為 EAS (Electronic Article Surveillance)

  • 原理: 讀取器只偵測感應範圍內是否有「標籤」存在,而不讀取標籤內部的具體 ID 碼。

  • 狀態: 只有「在場 (1)」或「不在場 (0)」兩種狀態。

  • 應用: 服飾店或超市門口的防盜門。

2. 說明何謂「壹位元電磁系統」?

這與射頻系統類似,但使用的是磁場飽和原理。

  • 特點: 標籤通常是一條具有高導磁率的軟磁金屬條。當經過讀取器的交變磁場時,會產生高次諧波,讀取器藉此判斷標籤存在。

  • 優點: 標籤極薄,常隱藏在書本中,且標籤可以反覆磁化(上鎖)與消磁(解鎖)。

3. 說明何謂「序列程序傳輸」?

  • 定義: 指讀取器與標籤之間的資料交換是非同步、分時進行的。

  • 流程: 讀取器先發送射頻能量(供標籤充電)與指令 $\rightarrow$ 停止發送 $\rightarrow$ 標籤利用儲存的能量回傳資料。這種方式可以避免讀取器強大的發射訊號干擾到標籤微弱的回傳訊號。

4. 試繪圖說明「電感耦合系統」之工作原理?

這是 低頻 (LF)高頻 (HF, 13.56MHz) 系統的核心。

  • 物理定律: 依據法拉第電磁感應定律

  • 原理: 讀取器天線線圈產生交變磁場,當標籤進入磁場時,標籤線圈會感應出電流(類似變壓器的原副線圈)。

  • 關鍵圖元: 需畫出兩個線圈、磁力線,以及標籤端的電容(形成諧振)。

5. 試繪圖說明「電磁反向散射耦合」之工作原理?

這是 超高頻 (UHF)微波 系統的核心。

  • 物理定律: 依據雷達原理 (Radar Section)

  • 原理: 讀取器發射電磁波,遇到標籤天線後反射。標籤透過改變自身的輸入阻抗(負載調變),改變反射波的幅度或相位,將資料「背載」回讀取器。

  • 關鍵圖元: 需畫出電磁波輻射、標籤天線反射波,以及標籤內部的阻抗切換開關。

6. 試說明「表面聲波 (SAW) 標籤」之工作原理?

這是一種無晶片 (Chipless) 的特殊技術。

  • 過程: 讀取器發出脈衝電磁波 $\rightarrow$ 標籤天線接收並轉換為機械聲波在壓電材料表面傳播 $\rightarrow$ 聲波遇到預先刻好的反射柵(反射鏡)反射回來 $\rightarrow$ 轉回電磁波傳回讀取器。

  • 特色: 因為聲波傳播速度遠慢於電磁波,這提供了一個天然的延遲,且能耐受極高溫或強輻射環境。


  • 感耦合: 標註「磁場 (Magnetic Field)」、「變壓器原理」。

  • 反向散射: 標註「反射波 (Reflected Wave)」、「負載調變 (Load Modulation)」。

習題解答 (3/4)

 

第三章 習題解答

1. 何謂 ISM?

  • 全名: Industrial, Scientific and Medical (Band)。

  • 定義: 這是由國際電信聯盟(ITU)預留,專門開放給工業、科學及醫療機構使用的無線電頻段。

  • 特性: 使用這些頻段通常不需要向當地政府申請許可證(免授權頻段),只要設備符合功率限制即可。常見的 Wi-Fi、藍牙與部分 RFID 系統都運行在 ISM 頻段中。


2. 何謂 EPCglobal?

  • 定義: EPCglobal 是一個非營利性的國際組織,由 GS1 與原 MIT Auto-ID Center 共同成立。

  • 目標: 致力於推動 EPC(Electronic Product Code,電子產品碼) 的全球標準化。它定義了標籤與讀取器之間的通訊協定(如著名的 EPC Gen2),目的是讓全球供應鏈中的物體都能擁有唯一的身份辨識。


3. RFID 業界中最常用的標準為何?

  • 目前業界應用最廣、最具代表性的標準是 EPCglobal Class 1 Generation 2 (簡稱 EPC Gen2),對應的國際標準為 ISO/IEC 18000-6C

  • 這個標準主要用於超高頻 (UHF) 供應鏈管理,提供高效能的防衝突讀取與全球通用的規格。


4. 動物晶片所使用的頻段為何?

  • 動物晶片通常採用 低頻 (Low Frequency, LF) 頻段。

  • 具體頻率: 全球通用的標準主要是 134.2 kHz125 kHz

  • 原因: 低頻波長較長,具有較強的穿透力,不易受生物體內組織(水分)的影響,且安全性高。


5. 目前 RFID 最常用的頻段為何?

RFID 根據應用情境有三個主流頻段,但以應用範疇來說,目前最常用的是:

  1. 高頻 (HF, 13.56 MHz): 用於支付、門禁(如悠遊卡、NFC)。

  2. 超高頻 (UHF, 860-960 MHz): 用於零售、物流與庫存管理。這是目前商業物流領域中最廣泛使用的頻段。


快速總結表

應用類型使用頻段典型頻率
動物識別低頻 (LF)134.2 kHz
門禁/卡片高頻 (HF)13.56 MHz
物流倉儲超高頻 (UHF)860 - 960 MHz

第四章 習題解答

1. 編碼的目的為何? (What is the purpose of encoding?)

編碼的主要目的是將原始資訊(如文字、聲音、影像)轉換成適合在特定通道(Channel)中傳輸或儲存的數位格式。其具體目標包括:

  • 提高傳輸效率: 透過資料壓縮減少頻寬需求。

  • 增強可靠性: 加入錯誤偵測與修正碼(如 CRC、ECC),確保資料在雜訊干擾下仍能正確還原。

  • 安全性: 透過加密編碼防止未經授權的讀取。

2. 調變的目的為何? (What is the purpose of modulation?)

調變是將低頻的基頻訊號(Baseband signal)載入到高頻的載波(Carrier wave)上的過程。其主要目的有:

  • 便於輻射與接收: 根據物理原理,天線長度需與波長成比例。高頻訊號波長短,可使用較小的天線。

  • 多工處理 (Multiplexing): 讓不同的訊號佔用不同的頻段,實現同時傳輸而不互相干擾(例如收音機頻道)。

  • 減少雜訊與干擾: 提高訊號的抗干擾能力。

3. 何謂曼徹斯特編碼? (What is Manchester Encoding?)

這是一種自我同步(Self-clocking)的數位編碼方式。其特點在於每個位元的中央都有一個位準轉換(Transition)

  • 邏輯 0: 通常定義為由高電位轉為低電位。

  • 邏輯 1: 通常定義為由低電位轉為高電位。

優點: 內含時脈資訊,接收端容易同步,且不會有直流偏移(DC Offset)問題。

4. 何謂米勒編碼及修飾式米勒編碼? (What is Miller and Modified Miller Encoding?)

  • 米勒編碼 (Miller Encoding): 又稱延遲調變。在位元「1」的中央進行位準轉換;若連續出現「0」,則在位元結束處轉換。這能有效減少所需的頻寬。

  • 修飾式米勒編碼 (Modified Miller Encoding): 常用於 RFID(如 ISO 14443A 標準)。它利用脈衝的有無來代表邏輯,進一步簡化硬體設計並提高傳輸的穩定性。

5. 試說明何謂 ASK、FSK、PSK 調變?

這三者是數位訊號調變載波的三種基本方式:

  • ASK (振幅鍵移): 透過改變載波的振幅來代表 0 與 1。有訊號代表 1,無訊號代表 0(又稱 OOK)。

  • FSK (頻率鍵移): 透過改變載波的頻率來代表 0 與 1。頻率 A 代表 1,頻率 B 代表 0。

  • PSK (相位鍵移): 透過改變載波的相位(角度)來代表資料。例如相位差 $180^\circ$ 分別代表 0 與 1。

6. 何謂副載波調變? (What is Subcarrier Modulation?)

副載波調變是在主載波(Main Carrier)之上,先將訊號調變到一個較低頻率的載波上,再將這個「已調變的副載波」去調變主載波。常見於 FM 廣播(傳輸立體聲資訊)或 RFID 系統中。

7. 副載波調變的目的何在?

  • 分離訊號: 在同一個主頻率通道中區隔不同的資料流(如聲音、影像或同步訊號)。

  • 降低干擾: 將基頻資料移到較高頻段,避開低頻的環境雜訊(1/f noise)。

  • 提高系統靈活性: 方便在現有的通訊架構中增加額外的資料服務。



習題解答 (1/2)

 

第一章 習題解答

1. 悠遊卡使用的頻段為何?

悠遊卡(EasyCard)採用的是 高頻(High Frequency, HF) 頻段。

  • 具體頻率: 13.56 MHz

  • 通訊標準: 符合 ISO/IEC 14443A 規範,這也是目前全球感應式智慧卡與 NFC 手機最常用的頻段。


2. RFID 的中文及英文的全名為何?

  • 英文全名: Radio Frequency Identification

  • 中文全名: 無線射頻辨識(或稱為「無線射頻識別系統」、「電子標籤」)


3. 試舉例生活中 RFID 應用的例子?

RFID 技術在日常生活中非常普及,以下是幾個常見的例子:

  • 交通與支付: 悠遊卡、一卡通、eTag(國道電子收費)。

  • 門禁管理: 公司識別證、社區感應磁扣、飯店房卡。

  • 物流與倉儲: 倉庫貨物盤點、快遞包裹追蹤、超商商品防盜標籤。

  • 自動化零售: 無人商店(如 Amazon Go 的感應結帳)、迪卡儂(Decathlon)的自助結帳系統。

  • 動物管理: 寵物植入的晶片、農場牲畜追蹤。

  • 醫療應用: 醫院的病患手環(用於身分核對)、藥品追蹤。

第二章 習題解答

1. 試說明 RFID 系統組成架構?

一個完整的 RFID 系統主要由以下三個部分組成:

  • 電子標籤 (Tag/Transponder): 附著在物體上,存儲識別資料。

  • 讀取器 (Reader/Interrogator): 發射無線電波以激活標籤,並讀取或寫入數據。

  • 應用軟體與電腦系統 (Host System/Middleware): 處理讀取器傳回的資料,並與資料庫對接。


2. 試說明那些頻段會受水份的影響?

  • 超高頻 (UHF, 860-960 MHz)微波 (Microwave, 2.45 GHz 以上): 水分子容易吸收這些高頻率的電磁波能量,導致訊號衰減嚴重,因此標籤若貼在含水容器上,讀取距離會大幅縮短。

3. 試說明那些頻段會受金屬物質的影響?

  • 所有頻段都會受影響,但表現不同:

    • 低頻 (LF) 與 高頻 (HF): 金屬會產生渦流感應,抵消磁場,導致無法感應。

    • 超高頻 (UHF) 以上: 金屬會反射電磁波,造成多路徑干擾或訊號遮蔽。


4. 何謂主動式電子標籤?

  • 定義: 標籤內部內建電池

  • 特性: 能主動發送訊號,識別距離長(可達百米),具備較大的記憶體,但體積較大、成本高且有電池壽命限制。

5. 何謂被動式電子標籤?

  • 定義: 標籤內部無電池

  • 特性: 電力來自讀取器發出的電磁波感應(電磁感應或反向散射)。壽命長、體積小且便宜,但讀取距離較短。


6. 電腦系統在 RFID 所擔任的角色為何?

  • 資料處理與儲存: 將讀取到的原始 ID 轉換為有意義的資訊(如品名、價格)。

  • 系統控管: 控制讀取器的運作時間與功率。

  • 後端集成: 與 ERP、倉儲管理系統 (WMS) 或資料庫連線,實現自動化管理。


7. 何謂 class 2 電子標籤?

根據 EPCglobal 的分類標準,Class 2 標籤屬於:

  • 功能: 除了具備 Class 1 的讀寫功能外,還具備額外的記憶體空間輔助感測功能(如溫度監控)。

  • 電力: 通常仍為被動式或半主動式(Battery-Assisted Passive),能提供比基本標籤更複雜的資料邏輯處理。

2026年2月21日 星期六

ESP32 Telegram 指令選單(Bot Commands)

ESP32 Telegram 指令選單(Bot Commands) 



/*******************************************************************
 *******************************************************************/
#include <WiFi.h>
#include <WiFiClientSecure.h>
#include <UniversalTelegramBot.h>

// Wifi network station credentials
#define WIFI_SSID "Wokwi-GUEST"
#define WIFI_PASSWORD ""
// Telegram BOT Token (Get from Botfather)
#define BOT_TOKEN "7738940254:AAHbrWu9ovb1BKPQyWsbNSjNxfCGCrEWU-o"
const unsigned long BOT_MTBS = 1000; // mean time between scan messages

unsigned long bot_lasttime; // last time messages' scan has been done
WiFiClientSecure secured_client;
UniversalTelegramBot bot(BOT_TOKEN, secured_client);

void handleNewMessages(int numNewMessages)
{
  Serial.print("handleNewMessages ");
  Serial.println(numNewMessages);
 
  String answer;
  for (int i = 0; i < numNewMessages; i++)
  {
    telegramMessage &msg = bot.messages[i];
    Serial.println("Received " + msg.text);
    if (msg.text == "/help")
      answer = "So you need _help_, uh? me too! use /start or /status";
    else if (msg.text == "/start")
      answer = "Welcome my new friend! You are the first *" + msg.from_name + "* I've ever met";
    else if (msg.text == "/status")
      answer = "All is good here, thanks for asking!";
    else
      answer = "Say what?";

    bot.sendMessage(msg.chat_id, answer, "Markdown");
  }
}

void bot_setup()
{
  const String commands = F("["
                            "{\"command\":\"help\",  \"description\":\"Get bot usage help\"},"
                            "{\"command\":\"start\", \"description\":\"Message sent when you open a chat with a bot\"},"
                            "{\"command\":\"status\",\"description\":\"Answer device current status\"}" // no comma on last command
                            "]");
  bot.setMyCommands(commands);
  //bot.sendMessage("25235518", "Hola amigo!", "Markdown");
}

void setup()
{
  Serial.begin(115200);
  Serial.println();

  // attempt to connect to Wifi network:
  Serial.print("Connecting to Wifi SSID ");
  Serial.print(WIFI_SSID);
  WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
  secured_client.setCACert(TELEGRAM_CERTIFICATE_ROOT); // Add root certificate for api.telegram.org
  while (WiFi.status() != WL_CONNECTED)
  {
    Serial.print(".");
    delay(500);
  }
  Serial.print("\nWiFi connected. IP address: ");
  Serial.println(WiFi.localIP());

  Serial.print("Retrieving time: ");
  configTime(0, 0, "pool.ntp.org"); // get UTC time via NTP
  time_t now = time(nullptr);
  while (now < 24 * 3600)
  {
    Serial.print(".");
    delay(100);
    now = time(nullptr);
  }
  Serial.println(now);

  bot_setup();
}

void loop()
{
  if (millis() - bot_lasttime > BOT_MTBS)
  {
    int numNewMessages = bot.getUpdates(bot.last_message_received + 1);

    while (numNewMessages)
    {
      Serial.println("got response");
      handleNewMessages(numNewMessages);
      numNewMessages = bot.getUpdates(bot.last_message_received + 1);
    }

    bot_lasttime = millis();
  }
}

這段程式碼展示了 Telegram 機器人一個非常實用的功能:「指令選單(Bot Commands)」 以及 「Markdown 字體格式化」。它不僅能根據指令回應,還能在 Telegram 的輸入欄位自動顯示指令列表。

以下是逐行詳細說明:


1. 指令選單設定:bot_setup

這是本範例的核心亮點。它定義了機器人在 Telegram 介面中顯示的「指令列表」。

C++
void bot_setup() {
  // 定義 JSON 格式的指令列表,包含 command (指令) 與 description (說明)
  const String commands = F("["
                            "{\"command\":\"help\",  \"description\":\"Get bot usage help\"},"
                            "{\"command\":\"start\", \"description\":\"Message sent when you open a chat with a bot\"},"
                            "{\"command\":\"status\",\"description\":\"Answer device current status\"}" 
                            "]");
  // 將這個列表同步到 Telegram 伺服器
  bot.setMyCommands(commands);
}
  • 功能:當你在 Telegram 輸入 / 時,會自動彈出 helpstartstatus 選單。

  • F() 巨集:將字串儲存在 Flash 記憶體中,節省 RAM。


2. 訊息處理邏輯:handleNewMessages

這裡使用了結構化的邏輯來根據指令產生不同的「Markdown」格式回應:

C++
void handleNewMessages(int numNewMessages) {
  String answer;
  for (int i = 0; i < numNewMessages; i++) {
    telegramMessage &msg = bot.messages[i]; // 取得訊息物件引用

    // 根據文字指令進行判斷
    if (msg.text == "/help")
      answer = "So you need _help_, uh? me too!"; // _文字_ 代表斜體
    else if (msg.text == "/start")
      answer = "Welcome my new friend! You are the first *" + msg.from_name + "*"; // *文字* 代表粗體
    else if (msg.text == "/status")
      answer = "All is good here, thanks for asking!";
    else
      answer = "Say what?";

    // 傳送訊息並指定使用 "Markdown" 模式解析文字格式
    bot.sendMessage(msg.chat_id, answer, "Markdown");
  }
}
  • Markdown 格式

    • *粗體文字* $\rightarrow$ 粗體文字

    • _斜體文字_ $\rightarrow$ 斜體文字


3. 初始化與網路連線:setup

負責環境準備,讓 ESP32 具備溝通能力:

  1. 連線 WiFi:使用 Wokwi 模擬器環境。

  2. 設定 SSL 憑證:Telegram API 是加密的 HTTPS,必須載入根憑證。

  3. 同步網路時間 (NTP):這是機器人運作的關鍵。如果 ESP32 的時間不準確,與 Telegram 伺服器建立 SSL 握手時會失敗。

  4. 呼叫 bot_setup():在開機時就將指令選單註冊到 Telegram。


4. 主迴圈輪詢:loop

C++
void loop() {
  if (millis() - bot_lasttime > BOT_MTBS) { // 每秒檢查一次
    // 獲取新訊息數量
    int numNewMessages = bot.getUpdates(bot.last_message_received + 1);

    while (numNewMessages) { 
      handleNewMessages(numNewMessages); // 處理並回傳訊息
      numNewMessages = bot.getUpdates(bot.last_message_received + 1);
    }
    bot_lasttime = millis();
  }
}

💡 程式亮點小結

  1. 專業感:透過 setMyCommands 讓使用者不需要背指令,點選選單即可操作。

  2. 可讀性:回應訊息中使用了 Markdown(粗體、斜體),讓資訊呈現更具層次感。

  3. 引用技術telegramMessage &msg = bot.messages[i] 使用引用 (&) 可以減少記憶體複製,提高程式效能。

ESP32 Telegram SendMessageFromEvent

 ESP32 Telegram SendMessageFromEvent

當 ESP32 開機或重啟完成並連上網路後,主動發送一則通知訊息給指定的 Telegram 使用者。


/*******************************************************************
    A telegram bot that sends you a message when ESP
    starts up
 *******************************************************************/
#include <WiFi.h>
#include <WiFiClientSecure.h>
#include <UniversalTelegramBot.h>

// Wifi network station credentials
#define WIFI_SSID "Wokwi-GUEST"
#define WIFI_PASSWORD ""
// Telegram BOT Token (Get from Botfather)
#define BOT_TOKEN "7738940254:AAHbrWu9ovb1BKPQyWsbNSjNxfCGCrEWU-o"

// Use @myidbot (IDBot) to find out the chat ID of an individual or a group
// Also note that you need to click "start" on a bot before it can
// message you
#define CHAT_ID "7965218469"

WiFiClientSecure secured_client;
UniversalTelegramBot bot(BOT_TOKEN, secured_client);

void setup() {
  Serial.begin(115200);
  Serial.println();

 // attempt to connect to Wifi network:
  Serial.print("Connecting to Wifi SSID ");
  Serial.print(WIFI_SSID);
  WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
  secured_client.setCACert(TELEGRAM_CERTIFICATE_ROOT); // Add root certificate for api.telegram.org
  while (WiFi.status() != WL_CONNECTED)
  {
    Serial.print(".");
    delay(500);
  }
  Serial.print("\nWiFi connected. IP address: ");
  Serial.println(WiFi.localIP());

  Serial.print("Retrieving time: ");
  configTime(0, 0, "pool.ntp.org"); // get UTC time via NTP
  time_t now = time(nullptr);
  while (now < 24 * 3600)
  {
    Serial.print(".");
    delay(100);
    now = time(nullptr);
  }
  Serial.println(now);

  bot.sendMessage(CHAT_ID, "Bot started up", "");
}

void loop() {

}

這段程式碼的邏輯非常簡單且實用,它的主要目的是:當 ESP32 開機或重啟完成並連上網路後,主動發送一則通知訊息給指定的 Telegram 使用者。

這在遠端監控設備時非常有用,能讓你第一時間知道設備是否因為斷電後重啟。


1. 關鍵定義:指定對象

這段程式碼與前面幾則範例最大的不同點在於:

C++
#define CHAT_ID "7965218469"
  • CHAT_ID:這是你的個人 Telegram 帳號 ID(或是群組 ID)。

  • 之前的範例是「收到誰的訊息就回給誰」,但這個程式是主動發送,所以必須事先寫死(Hardcode)接收者的 ID。

  • 註記:你可以透過 Telegram 上的 @myidbot 機器人來查到自己的 CHAT_ID


2. 初始化設定:setup()

這個程式的核心全部都在 setup() 內,因為它只需要在開機時執行一次。

  • 網路與憑證設定

    • 連接 WiFi 並載入 Telegram 的 SSL 根憑證 (TELEGRAM_CERTIFICATE_ROOT),確保 HTTPS 連線安全。

  • 網路對時 (NTP)

    • configTime(0, 0, "pool.ntp.org")

    • 重要性:Telegram 伺服器會檢查訊息的時間戳記,如果 ESP32 的時間與網路時間相差太大,訊息會發送失敗。

  • 發送啟動訊息

    C++
    bot.sendMessage(CHAT_ID, "Bot started up", "");
    
    • 當上述連線與對時都完成後,機器人會立即向 7965218469 發送「Bot started up」這段文字。


3. 主迴圈:loop()

C++
void loop() {
  // 這裡是空的
}
  • 因為這個範例的目的只是「開機通知」,不需要持續檢查新訊息,所以 loop() 保持空白。這意味著機器人不會回應你傳給它的任何話。


4. 運作流程圖解

  1. 電源接通:ESP32 啟動。

  2. WiFi 連線:取得 Wokwi-GUEST 的 IP 位址。

  3. 時間同步:向 NTP 伺服器要求目前時間。

  4. 安全握手:使用 SSL 憑證與 Telegram 建立 HTTPS 連線。

  5. 主動出擊:呼叫 sendMessage 將啟動成功的訊息推送到你的手機。

  6. 進入休眠/閒置:完成任務,不再執行任何動作。


💡 實戰建議

這個程式雖然簡單,但它是**「警報系統」**的基礎。你可以稍微修改這段程式,例如:

  • 跌倒偵測:如果偵測到感測器數值異常,就執行 bot.sendMessage

  • 低電量警告:當電池電量低於 20% 時,主動傳訊通知你充電。

習題解答 (5/6)

  第五章 習題解答 一、 錯誤偵測技術 1. 何謂循環冗餘檢查法 (CRC)? 是一種根據傳輸資料產生簡短固定位數校驗碼的演算法。發送端將資料除以一個特定的多項式,得到的「餘數」即為 CRC 碼並隨資料發送;接收端以同樣多項式除之,若餘數為 0 則代表資料傳輸正確。 2. 何...