2025年6月12日 星期四

互動式IMU步態分析:Transformer模型深度解析

互動式IMU步態分析:Transformer模型深度解析

解鎖步態中的健康密碼

探索如何利用Transformer深度學習模型,從穿戴式感測器(IMU)數據中,洞察生理年齡並識別潛在的運動神經健康警訊。

為何步態如此重要?

步態不僅是行走,更是反映神經、肌肉骨骼和心血管系統綜合功能的「生物標記」。微小的步態變化,就能揭示健康狀態的宏觀趨勢。

步態參數群組比較

透過IMU感測器,我們能精準量化不同群體的步態差異。下方圖表展示了「年輕健康成人」、「年長健康成人」及「運動神經疾病(MND)患者」在幾個關鍵步態參數上的示意性差異。例如,隨著年齡增長或疾病影響,步速通常會減慢,而步態的變異性則會增加,反映出穩定性的下降。

Transformer模型能從原始感測器數據中,自動學習並辨識這些複雜且細微的模式,實現精準分類。

Transformer如何解讀IMU信號?

這是一個將連續、嘈雜的感測器數據轉化為清晰、有意義分類的自動化流程。

📡

1. 原始信號

收集多通道IMU時間序列數據。

🧩

2. 分塊 (Patching)

將長序列切割成小的「塊」,便於模型處理。

🔖

3. 嵌入與定位

將塊轉為向量,並添加位置資訊以理解順序。

💡

4. Transformer編碼器

核心所在。自注意力機制捕捉全局模式。

🎯

5. 分類輸出

模型輸出分類結果,如「年輕步態」。

互動式模型藍圖

一個典型的IMU Transformer分類器是如何建構的?透過下方的互動式儀表板,探索關鍵的架構與超參數。

探索超參數

點擊下方按鈕,了解不同超參數如何影響模型的性能、複雜度與學習能力。

點擊按鈕查看說明

超參數是建構模型的基石,共同決定了模型的學習方式。

模型配置可視化

架構佔比

超參數平衡

未來展望:邁向更智能的健康監測

這項技術仍在不斷演進。以下是幾個關鍵的未來研究方向,將使模型更強大、更可靠。

🎭

合成數據增強

利用生物力學模型生成數據,解決真實世界數據稀缺的問題,提升模型穩健性。

📚

遷移學習

在大型通用數據集上預訓練模型,再於特定步態任務上微調,以提高效率和性能。

🔍

模型可解釋性

可視化注意力權重,理解模型決策依據,以增強臨床醫學的信任度與應用價值。

📲

端側部署

優化模型效率,使其能夠在手機或穿戴設備上實時運行,實現個人化健康監測。

© 2025 AI驅動的健康洞察。本應用程式根據「基於Transformer深度學習之慣性測量單元步態分析」報告創建。

IMU步態分析Transformer技術趨勢

IMU步態分析Transformer技術趨勢

解鎖人體運動密碼

應用Transformer模型革新IMU步態分析

本資訊圖表提煉了「基於Transformer深度學習之慣性測量單元步態分析」報告的核心發現,展示了這項尖端技術如何從感測器數據中洞察生理年齡與潛在的運動神經健康指標。

從傳統到革新:HAR的演進之路

人體活動識別(HAR)技術的演進,旨在更精準地捕捉複雜的人類運動模式。

⚙️

傳統機器學習

依賴手動特徵工程,需要大量領域知識,難以捕捉複雜的時間動態。

🧠

早期深度學習 (CNN/RNN)

能自動學習特徵,但RNN受限於長期依賴,CNN則專注於局部特徵。

🚀

Transformer 模型

憑藉自註意力機制,能有效捕捉全局和長期依賴關係,並支持並行訓練,成為當前最佳解決方案。

步態:健康的關鍵生物標記

步態的微小變化,可能揭示生理年齡和神經系統健康的秘密。

步態參數比較

步態分析不僅僅是測量走路。它是對神經、肌肉骨骼和心血管系統綜合功能的量化評估。透過IMU感測器,我們可以精準地比較不同群體之間的步態差異。例如,隨著生理老化,步速通常會減慢,步長縮短,而步態的變異性增加。在患有運動神經元疾病(MND)或相關神經系統疾病的個體中,這些變化可能更為顯著,為早期診斷和病情監測提供了客觀依據。

  • 步速 (Gait Speed): 反映整體功能狀態的重要指標。
  • 步長 (Step Length): 與平衡能力和肌肉力量相關。
  • 步態變異性: 衡量步態穩定性和運動控制的精細程度。

Transformer如何解讀IMU信號?

一個將連續感測器數據轉化為有意義分類的流程。

📡

1. 原始IMU信號

收集多通道時間序列數據(加速度、角速度)。

🧩

2. 分塊 (Patching)

將長序列切割成小的、可管理的「塊」,以降低複雜性。

🔢

3. 嵌入與定位

將塊轉換為向量,並添加位置信息,讓模型理解順序。

💡

4. Transformer編碼器

核心所在。自註意力機制權衡每個塊的重要性,捕捉全局模式。

📊

5. 分類輸出

模型最終輸出分類結果,如「年輕步態」或「MND風險」。

模型建構藍圖:PyTorch實作

將理論轉化為代碼的關鍵組件與超參數配置。

關鍵超參數配置

模型的性能高度依賴於超參數的精確設定。這些參數共同定義了模型的學習能力、複雜度和計算效率。例如,`d_model` 決定了資訊的豐富度,而 `n_heads` 則讓模型能從不同角度關注數據。下方的雷達圖直觀地展示了一組用於步態分析的典型超參數配置,平衡了模型容量與訓練效率。

模型架構分解

一個完整的Transformer分類器由幾個關鍵部分組成。編碼器層是核心,佔據了大部分參數,負責深度特徵提取。嵌入層將原始數據轉換為模型能理解的格式,而分類頭則做出最終的預測。

未來展望:邁向個人化健康監測

持續的研究將使模型更穩健、更智能,並最終應用於實際場景。

🧬

合成數據增強

利用生物力學模型生成數據,以解決真實數據稀缺的問題。

📚

遷移學習

在大型通用數據集上預訓練,再於特定任務上微調,以提高效率和性能。

🔍

模型可解釋性

可視化註意力權重,理解模型決策依據,以增強臨床信任度。

⌚️

端側部署

優化模型效率,使其能夠在可穿戴設備上實時運行。

© 2025 AI驅動的健康洞察。基於前沿研究的數據可視化。

MCP_n8n_Docker Build

MCP 與 AI Agent 發展:互動指南

MCP 與 AI Agent 發展:互動指南

歡迎來到這份互動指南,您可以在此瀏覽並複製關於模型上下文協定(MCP)與AI代理發展的關鍵資訊,包括相關技術、工具套件以及Docker快速部署的詳細步驟。

AI代理開發的領先工具套件與框架

AI代理框架領域正在經歷多元化和專業化。以下表格提供了目前領先的AI代理開發框架的核心功能、優勢和理想用例的比較分析。

特性 / 框架 LangChain LlamaIndex CrewAI AutoGen (Microsoft) LangGraph MetaGPT n8n (作為AI工作流程平台)
主要焦點 工具鏈與管道 數據管理與RAG 任務編排 多代理對話與工作流程 圖形化多代理工作流程 模擬軟體開發團隊 工作流程自動化與AI整合
核心架構方法 模組化組件 索引機制與查詢介面 基於角色代理 對話式代理互動 圖形化架構 標準操作程序 (SOP) 視覺化工作流程構建器
記憶體管理 短期/長期記憶,RAG,實體記憶體 數據索引與上下文層 短期/長期記憶 (RAG, SQLite3),用戶記憶體 消息列表,外部整合 短期/長期記憶,實體記憶體 任務上下文,知識庫 對話記憶體,RAG,向量資料庫整合
多代理支持 ✅ (通過鏈接) ✅ (通過工作流程) ✅ (核心功能:Crew) ✅ (核心功能:GroupChat) ✅ (核心功能) ✅ (核心功能) ❌ (但可編排多個AI節點)
工具整合 廣泛整合 數據連接器 靈活工具與API 內置工具代理支持 支持工具 部分內置支持 350+預建整合,自定義節點
代碼執行/生成 ✅ (通過工具) ✅ (代碼執行代理) ✅ (通過工具) ✅ (代碼生成) ✅ (JavaScript/Python 自定義代碼)
人類參與循環 (Human-in-the-Loop) ✅ (非原生) ✅ (CriticAgent, 反饋代理) ✅ (核心功能) ✅ (通過工作流程審批)
易用性/複雜度 中等 (需編碼) 中等 (需編碼) 高 (需Python知識) 中等 (有UI) 中等 (需編碼) 高 (需理解代理設計) 低-中 (視覺化構建器)
可擴展性 中等 中等 中高 (開發者導向) 低-中 高 (自託管選項)
開源/商業 開源 開源 開源 開源 開源 開源 開源 (有雲服務)
理想用例 聊天機器人,數據整合,RAG 問答,數據提取,自主代理 協作研究,自動化客戶支援 代碼生成,複雜問題解決 可靠/可控代理,多代理系統 軟體開發項目,系統設計模擬 業務流程自動化,AI聊天機器人,RAG,API整合

使用Docker快速部署:實用指南

Docker為AI和LLM應用程式的開發和部署帶來了顯著優勢。以下是使用Docker部署n8n的實用指南,包括基本設置、數據持久化和多組件系統編排。

基本Docker安裝與n8n容器設置

要快速啟動n8n,可以使用以下Docker命令:

docker run -it --rm --name n8n -p 5678:5678 n8nio/n8n

此命令將n8n容器的5678端口映射到主機的5678端口,使n8n可通過http://localhost:5678訪問 [1, 2]。

n8n官方提供了一個「自託管AI啟動套件」(Self-hosted AI Starter Kit),這是一個預配置的Docker Compose模板,用於快速建立本地AI和低代碼開發環境 [3]。

克隆儲存庫:

git clone https://github.com/n8n-io/self-hosted-ai-starter-kit.git
cd self-hosted-ai-starter-kit

運行Docker Compose(CPU模式,適用於大多數用戶):

docker compose --profile cpu up

對於Nvidia GPU用戶:

docker compose --profile gpu-nvidia up

對於AMD GPU (Linux) 用戶:

docker compose --profile gpu-amd up

對於Mac / Apple Silicon 用戶:

docker compose up

如果Ollama在Mac本地運行,可能需要調整OLLAMA_HOST環境變數為host.docker.internal:11434 [3]。

確保數據持久化與安全配置

為了確保n8n工作流程和憑證數據的持久化,並增強安全性,建議進行以下配置:

數據持久化:

docker run -d --name n8n \
  -p 5678:5678 \
  -v ~/.n8n:/home/node/.n8n \
  n8nio/n8n

此命令將主機上的~/.n8n目錄掛載到容器內的/home/node/.n8n,n8n會將其數據儲存在此路徑下 [2, 4]。

環境變數(.env文件範例):

N8N_BASIC_AUTH_ACTIVE=true
N8N_BASIC_AUTH_USER=admin
N8N_BASIC_AUTH_PASSWORD=your_secure_password
WEBHOOK_URL=http://your_n8n_domain.com:5678/

然後使用--env-file參數運行Docker容器:

docker run -d --name n8n \
  --env-file./.env \
  -p 5678:5678 \
  -v ~/.n8n:/home/node/.n8n \
  n8nio/n8n

使用Docker部署MCP伺服器(例如,基於n8n的MCP伺服器)

n8n本身可以作為一個功能齊全的MCP伺服器。以下表格總結了用於配置n8n作為MCP伺服器的關鍵Docker命令和環境變數:

組件 Docker 命令/Compose 片段 關鍵環境變數 目的
n8n (作為MCP伺服器) docker run -d --name n8n -p 5678:5678 -v ~/.n8n:/home/node/.n8n --env-file./.env n8nio/n8n WEBHOOK_URL 設定n8n實例的外部可訪問URL,對於MCP伺服器觸發器節點生成正確的端點至關重要。
(或相應的 docker-compose.yml 片段) N8N_BASIC_AUTH_ACTIVE 啟用n8n的基本認證,增強安全性。
N8N_BASIC_AUTH_USER 設定基本認證的用戶名。
N8N_BASIC_AUTH_PASSWORD 設定基本認證的密碼。
備註 確保使用強密碼。對於生產環境,建議在n8n容器前配置Nginx等反向代理,以提供SSL加密和更高級的安全性 [5, 6]。

使用Docker Compose編排多組件AI系統

Docker Compose極大地簡化了多容器AI設置的管理,實現了AI代理、資料庫和其他服務之間的無縫通訊 [7]。以下是一個概念性的docker-compose.yml文件範例:

version: '3.8'

services:
  n8n:
    image: n8nio/n8n:latest
    container_name: n8n
    ports:
      - "5678:5678"
    volumes:
      - ~/.n8n:/home/node/.n8n # 持久化n8n數據
    environment:
      - N8N_BASIC_AUTH_ACTIVE=true
      - N8N_BASIC_AUTH_USER=admin
      - N8N_BASIC_AUTH_PASSWORD=your_secure_password # 請務必更改為強密碼
      - WEBHOOK_URL=http://localhost:5678/ # 或您的外部可訪問URL
      - OLLAMA_HOST=http://ollama:11434 # 連接到同一個Compose網絡中的Ollama服務
    networks:
      - ai_network

  ollama:
    image: ollama/ollama:latest
    container_name: ollama
    ports:
      - "11434:11434"
    volumes:
      - ollama_data:/root/.ollama # 持久化Ollama模型數據
    # 如果有GPU,可以添加以下配置
    # deploy:
    #   resources:
    #     reservations:
    #       devices:
    #         - driver: nvidia
    #           count: all
    #           capabilities: [gpu]
    networks:
      - ai_network

  vector_database: # 例如,使用Qdrant或Weaviate作為向量資料庫
    image: qdrant/qdrant:latest
    container_name: qdrant
    ports:
      - "6333:6333" # Qdrant API端口
      - "6334:6334" # Qdrant gRPC端口
    volumes:
      - qdrant_data:/qdrant/storage
    networks:
      - ai_network

  # custom_mcp_server: # 如果您有自定義的MCP伺服器服務
  #   build:./custom-mcp-server # 指向您的Dockerfile目錄
  #   container_name: custom_mcp_server
  #   ports:
  #     - "8080:8080"
  #   networks:
  #     - ai_network

volumes:
  ollama_data:
  qdrant_data:

networks:
  ai_network:
    driver: bridge

2025年6月9日 星期一

IOT_PCB CODE 4G LTE 數據機狀態機分析

4G LTE 數據機狀態機分析器

4G LTE 數據機狀態機分析器

本頁提供 `modem_main()` 函式的核心流程控制邏輯解析、相關輔助函式的功能查詢,以及關鍵資料結構的詳細說明。

modem_main() 流程控制邏輯

modem_main() 函式主要透過一個大的 switch 語句來根據 info->session (當前數據機會話狀態) 執行不同的邏輯。每個 case 代表一個特定的數據機操作階段。

case _AT_SESSION_RESET: (數據機重置階段)

目的: 等待數據機完成硬體重置後的初始化延遲。

邏輯:

  • 檢查自 at_cmd_reset_tick 以來的時間是否超過 AT_RESET_INITIAL_TIMEOUT_MS (5 秒)。
  • 如果超過,表示重置延遲已滿足,則將會話切換到 _AT_SESSION_INIT (初始化階段)。
  • 同時初始化 at_cmd_polling_tickat_cmd_poll_gps_tick,為後續的命令輪詢和 GPS 數據讀取計時。
case _AT_SESSION_INIT: (數據機初始化階段)

目的: 執行一系列初始化的 AT 命令,包括基本設定、讀取 UUID、檢查訊號品質、設定 RTC 時間、以及 MQTT 相關參數載入和訂閱主題等。

邏輯:

  • 呼叫 cmd_processing(info):這是處理單個 AT 命令的核心函式,負責發送命令、等待響應、解析響應並更新命令狀態。
  • if(info->status == STATUS_CMD_OK)
    • 重置 info->statusSTATUS_CMD_NONE
    • 檢查訊號品質 (chk_cmd_response()==CMD_STATUS_BAD_SQ): 如果當前命令響應指示訊號品質不佳 (例如 AT+CSQ 命令返回的值低於預設閾值),則:
      • 增加 _modem.chk_sq_cnt
      • 根據當前會話是否為 _AT_SESSION_CHK_SQ,決定是直接切換到 _AT_SESSION_WAIT_TO_CHK_SQ 還是保留原會話並切換到 _AT_SESSION_WAIT_TO_CHK_SQ (使用 switchATSessionK 保留原會話)。
      • 更新 at_cmd_reset_tick
    • 檢查是否為命令集的末尾 (commands[info->index+1].mode == _CMD_MODE_END): 如果當前命令是會話中的最後一個命令:
      • 增加 info->index
      • 根據不同的會話類型執行相應的收尾工作:
        • _AT_SESSION_CHK_SQ: 恢復到之前的會話 (restoreToOrgSession())。
        • _AT_SESSION_TX: 將 _modem.lte_4G_TX_flag 清零,表示數據已發送,然後切換到 _AT_SESSION_FREE_RUN
        • _AT_SESSION_POLLING: 更新 at_cmd_polling_tick,然後切換到 _AT_SESSION_FREE_RUN
        • _AT_SESSION_GET_GPS: 更新 at_cmd_poll_gps_tick,然後切換到 _AT_SESSION_FREE_RUN
        • _AT_SESSION_INIT / _AT_SESSION_LOG_OUT_IN: 設定 _send_ping_data 為 1 (表示需要發送 PING 數據)、設定 _connected 為 1 (表示已連接 MQTT)、清除 _relog_request 旗標。
        • default: 切換到 info->cmdSet[info->index].sleeps 所指定的下一個會話。
  • else if (info->status == STATUS_CMD_ERROR)
    • 重置 info->statusSTATUS_CMD_NONE
    • 如果 _modem.error_count 超過 20 次,則執行 modem_reset() (硬體重置數據機)。
  • else if (info->status == STATUS_CMD_TIMEOUT)
    • STATUS_CMD_ERROR 處理方式類似,如果超時次數過多,也執行 modem_reset()
case _AT_SESSION_WAIT_TO_CHK_SQ: (等待檢查訊號品質階段)

目的: 在訊號品質不佳時,暫停其他操作,等待一段時間後重新檢查訊號。

邏輯:

  • 如果 _modem.chk_sq_cnt 小於 5 次 (表示還在初始的快速重試階段),且自 at_cmd_reset_tick 以來超過 5 秒,則切換到 _AT_SESSION_CHK_SQ
  • 如果 _modem.chk_sq_cnt 大於等於 5 次 (表示已經進行多次重試,需要更長的等待時間),且自 at_cmd_reset_tick 以來超過 30 秒,則切換到 _AT_SESSION_CHK_SQ
case _AT_SESSION_FREE_RUN: (自由運行階段)

目的: 釋放數據機物件的控制權 (semaphore),並切換到下一個自由運行階段。

邏輯:

  • 呼叫 releaseSemaObj(_OWNER_MODEM) 釋放數據機的互斥鎖。
  • 切換到 _AT_SESSION_FREE_RUN_1
  • 更新 at_cmd_reset_tick
case _AT_SESSION_FREE_RUN_1: (自由運行子階段)

目的: 提供一個短暫的窗口,允許其他模組 (例如 CAN) 處理數據,然後再進入數據機的輪詢階段。

邏輯:

  • 如果自 at_cmd_reset_tick 以來超過 1 秒,則切換到 _AT_SESSION_WAIT_TO_GET_GPS
case _AT_SESSION_WAIT_TO_GET_GPS: (等待獲取 GPS 或輪詢數據階段)

目的: 這是數據機在穩定連接後的主要運行階段,負責根據不同的條件觸發數據傳輸、重新登錄或 GPS/訊息輪詢。

邏輯:

  • 優先處理數據發送 (_modem.lte_4G_TX_flag==1): 如果有待發送的數據:
    • 嘗試獲取數據機的互斥鎖 (acquireSemaObj(_OWNER_MODEM))。
    • 如果成功,則切換到 _AT_SESSION_TX
  • 處理重新登錄請求 (chk_relog_request()): 如果有 MQTT 重新登錄請求:
    • 嘗試獲取數據機的互斥鎖。
    • 如果成功,則切換到 _AT_SESSION_LOG_OUT_IN,並將 _connected 設為 0。
  • 平衡 GPS 數據讀取和訊息輪詢: 這部分邏輯比較複雜,旨在交替執行 GPS 請求和輪詢接收到的數據,以避免阻塞:
    • 高頻率同時觸發 (chk_timeup_ms(timer1ms,at_cmd_poll_gps_tick, _modem.at_gps_read_time) && chk_timeup_ms(timer1ms, at_cmd_polling_tick, 5*1000)): 如果 GPS 讀取時間和輪詢時間都到期:
      • 嘗試獲取互斥鎖。
      • 根據 _prev_action_gps 的值,決定是切換到 _AT_SESSION_POLLING (輪詢) 還是 _AT_SESSION_GET_GPS (獲取 GPS),並更新 _prev_action_gps
    • 僅輪詢時間到期 (chk_timeup_ms(timer1ms, at_cmd_polling_tick, 5*1000)): 如果只有輪詢時間到期:
      • 嘗試獲取互斥鎖。
      • 切換到 _AT_SESSION_POLLING,並將 _prev_action_gps 設為 0。
    • 僅 GPS 時間到期 (chk_timeup_ms(timer1ms,at_cmd_poll_gps_tick, _modem.at_gps_read_time)): 如果只有 GPS 時間到期:
      • 嘗試獲取互斥鎖。
      • 切換到 _AT_SESSION_GET_GPS,並將 _prev_action_gps 設為 1。
cmd_processing(COMMAND_STATE_INFO *info) (輔助函式但與主邏輯緊密相關)

功能: 這是執行單個 AT 命令的核心。

邏輯: 根據 info->state (當前命令狀態) 進行處理:

  • _AT_CMD_TO_SEND: 準備並發送 AT 命令到 UART 0。如果命令類型是 _CMD_MODE_PUB, _CMD_MODE_DOWN, _CMD_MODE_UP,則需要處理 UUID 或將 IoT 數據轉換為十六進制格式發送。
  • _AT_CMD_WAIT_TO_RECEIVE: 等待 UART 0 接收到足夠的數據 (通過判斷 \r\n 的數量)。如果超時,則將 info->status 設為 STATUS_CMD_TIMEOUT
  • _AT_CMD_TO_RECEIVE: 檢查接收到的數據是否包含 "OK" 或 "ERROR"。
    • 如果包含 "OK",表示命令成功,清除錯誤計數,複製數據到 platformrxbuffer,並將狀態切換到 _AT_CMD_WAIT_TO_SEND
    • 如果包含 "ERROR",增加錯誤計數,如果錯誤是 MQTT 登錄相關且不影響後續流程,則切換到 _AT_CMD_WAIT_TO_SEND;否則切換到 _AT_CMD_ERROR_RESEND
    • 如果超時,則將 info->status 設為 STATUS_CMD_TIMEOUT
  • _AT_CMD_WAIT_TO_SEND: 等待一段時間後,將狀態切換到 _AT_CMD_TO_SEND 並增加命令索引,準備發送下一個命令。
  • _AT_CMD_ERROR_RESEND: 等待一段時間後,將狀態切換到 _AT_CMD_TO_SEND (重發當前命令)。
chk_cmd_response() (輔助函式但與主邏輯緊密相關)

功能: 解析 platformrxbuffer 中接收到的 AT 命令響應,並根據響應內容更新 _modem 結構中的相關資訊 (如 UUID, 訊號品質, RTC 時間, GPS 數據)。

邏輯: 根據解析結果返回 CMD_STATUS_OK, CMD_STATUS_BAD_SQCMD_STATUS_BAD_GPS

switchATSessionK(), switchATSession()restoreToOrgSession() (會話切換輔助函式)
  • switchATSessionK(AT_SESSION_STATES session):切換到新的 AT 會話,並保留當前會話的狀態資訊,以便後續恢復。
  • switchATSession(AT_SESSION_STATES session):切換到新的 AT 會話,不保留當前會話的狀態資訊。
  • restoreToOrgSession():恢復到之前保存的 AT 會話狀態。
modem_reset() (數據機硬體重置輔助函式)

功能: 執行數據機的硬體重置,包括 GPIO 控制電源和重置引腳,並初始化 _modem 結構中的所有相關變數。

acquireSemaObj()releaseSemaObj() (互斥鎖輔助函式)

功能: 用於實現對數據機操作的互斥鎖,確保在同一時間只有一個模組可以控制數據機,避免競爭條件。

輔助函式與資料結構查詢

  • chk_connected()
  • chk_require_ping_data()
  • clr_require_ping_data()
  • get_TX_flag()
  • set_TX_flag(uint8_t flag)
  • get_internal_rtc()
  • acquireSemaObj(uint8_t _tag)
  • releaseSemaObj(uint8_t _tag)
  • set_gps_timer(uint32_t ntime)
  • get_latitude()
  • get_longitude()
  • RTC_set_time()
  • RTC_get_time()
  • modem_reset()
  • resetModem()
  • chk_mqttlogin(uint8_t *msg)
  • chk_signal(uint8_t *msg)
  • updateTimeInfo(uint8_t *msg, UTC_TIME *tm)
  • update_msg_timestamp(uint8_t *msg, UTC_TIME *tm)
  • stringSplit(char arr[][64], char *s, char *delim)
  • updateGpsInfo(uint8_t *msg, GPS_LOCATION *gps)
  • addToQueue(uint8_t *msg)
  • chk_msg_queue()
  • get_unread_msg()
  • chk_cmd_response()
  • switchATSessionK(AT_SESSION_STATES session)
  • switchATSession(AT_SESSION_STATES session)
  • restoreToOrgSession()
  • chk_relog_request()
  • clr_relog_request()
  • set_relog_request()
  • get_tx_msg()
  • hexMsgConverting(char *hexMsg, char *strMsg)
  • chk_str_key_count(char *adr, char *keypt)
  • get_modem_uuid()

請從左側列表選擇一個項目,或在上方搜尋。

核心資料結構定義

以下是 4G LTE 數據機狀態機中使用的核心資料結構定義,您可以展開查看詳細內容。

typedef enum COMMAND_STATUS

功能: 定義 AT 命令的執行狀態。

typedef enum
{
    STATUS_CMD_NONE=0,
    STATUS_CMD_OK,
    STATUS_CMD_ERROR,
    STATUS_CMD_TIMEOUT,
    STATUS_CMD_IN_PROCESS,
} COMMAND_STATUS;
  • STATUS_CMD_NONE: 無狀態,或初始狀態。
  • STATUS_CMD_OK: 命令執行成功。
  • STATUS_CMD_ERROR: 命令執行失敗或返回錯誤。
  • STATUS_CMD_TIMEOUT: 命令執行超時。
  • STATUS_CMD_IN_PROCESS: 命令正在處理中。
typedef enum AT_SESSION_STATES

功能: 定義數據機狀態機的各個會話階段。

typedef enum
{
    _AT_SESSION_INIT =0,
    _AT_SESSION_RESET,              //1
    _AT_SESSION_CHK_SQ,             //2 check signal quality when error or timeout happens.
    _AT_SESSION_WAIT_TO_CHK_SQ,     //3
    _AT_SESSION_FREE_RUN,           //4
    _AT_SESSION_TX,                 //5 MQTT up send json message
    _AT_SESSION_WAIT_TO_GET_GPS,    //6
    _AT_SESSION_GET_GPS,            //7
    _AT_SESSION_LOG_OUT_IN,         //8
    _AT_SESSION_POLLING,            //9
    _AT_SESSION_FREE_RUN_1,         //10
}AT_SESSION_STATES;
  • _AT_SESSION_INIT: 初始化會話。
  • _AT_SESSION_RESET: 數據機重置後等待階段。
  • _AT_SESSION_CHK_SQ: 檢查訊號品質會話。
  • _AT_SESSION_WAIT_TO_CHK_SQ: 等待檢查訊號品質的延遲階段。
  • _AT_SESSION_FREE_RUN: 自由運行階段 (釋放鎖)。
  • _AT_SESSION_TX: 數據上傳 (MQTT) 會話。
  • _AT_SESSION_WAIT_TO_GET_GPS: 等待獲取 GPS 或輪詢數據的決策階段。
  • _AT_SESSION_GET_GPS: 獲取 GPS 數據會話。
  • _AT_SESSION_LOG_OUT_IN: MQTT 登出再登入會話。
  • _AT_SESSION_POLLING: 輪詢接收數據會話。
  • _AT_SESSION_FREE_RUN_1: 自由運行子階段 (短暫延遲)。
typedef enum AT_CMD_STATES

功能: 定義單個 AT 命令的執行狀態,用於 cmd_processing() 函式。

typedef enum
{
    _AT_CMD_NONE = 0,
    _AT_CMD_TO_SEND,
    _AT_CMD_TO_RECEIVE,
    _AT_CMD_TO_RECEIVE1,
    _AT_CMD_WAIT_TO_SEND,
    _AT_CMD_ERROR_RESEND,
    _AT_CMD_WAIT_TO_RECEIVE,
}AT_CMD_STATES;
  • _AT_CMD_NONE: 無命令狀態。
  • _AT_CMD_TO_SEND: 準備發送命令。
  • _AT_CMD_TO_RECEIVE: 準備接收響應。
  • _AT_CMD_TO_RECEIVE1: 另一種接收響應狀態。
  • _AT_CMD_WAIT_TO_SEND: 等待下次發送命令。
  • _AT_CMD_ERROR_RESEND: 錯誤後等待重發。
  • _AT_CMD_WAIT_TO_RECEIVE: 等待接收響應數據。
typedef enum _CMD_MODES

功能: 定義 AT 命令的處理模式,影響命令的發送和響應解析方式。

typedef enum {
    _CMD_MODE_0 = 0,    //normal command, just send it to modem
    _CMD_MODE_PUB,
    _CMD_MODE_DOWN,
    _CMD_MODE_UP,
    _CMD_MODE_P0,
    _CMD_MODE_CSQ,
    _CMD_MODE_TM,
    _CMD_MODE_E,        //ignore the error
    _CMD_MODE_TEST,
    _CMD_MODE_GPS,
    _CMD_MODE_TX,
    _CMD_MODE_POLL,         //poll reading the data of Link Commands from uBlox catched buffer.
    _CMD_MODE_MQTTLOGIN,        //=== 20241111 handel check mqtt login === "+UUMQTTC: 1 ,1"
    _CMD_MODE_END,
}_CMD_MODES;
  • _CMD_MODE_0: 普通命令,直接發送。
  • _CMD_MODE_PUB: MQTT 發布相關命令。
  • _CMD_MODE_DOWN: MQTT 訂閱下載相關命令。
  • _CMD_MODE_UP: MQTT 上傳相關命令。
  • _CMD_MODE_P0: 可能用於特定參數設定或檔案操作。
  • _CMD_MODE_CSQ: 查詢訊號品質命令。
  • _CMD_MODE_TM: 查詢時間命令。
  • _CMD_MODE_E: 忽略錯誤的命令模式。
  • _CMD_MODE_TEST: 測試模式命令。
  • _CMD_MODE_GPS: GPS 相關命令。
  • _CMD_MODE_TX: 數據傳輸命令。
  • _CMD_MODE_POLL: 輪詢 Link Command 數據命令。
  • _CMD_MODE_MQTTLOGIN: MQTT 登錄檢查命令。
  • _CMD_MODE_END: 命令集的結束標誌。
typedef struct AT_COMMANDS

功能: 定義單個 AT 命令的結構,包括其模式、延遲時間和命令字串。

typedef struct{
    _CMD_MODES mode;
    uint8_t sleeps;
    char *command;
} AT_COMMANDS;
  • mode: 命令的處理模式 (參考 _CMD_MODES)。
  • sleeps: 命令發送後的延遲時間或切換到的下一個會話狀態。
  • command: AT 命令字串。
typedef struct COMMAND_STATE_INFO

功能: 儲存數據機狀態機的當前運行資訊。

typedef struct{
    AT_SESSION_STATES   session;
    AT_SESSION_STATES   prev_session;
    AT_CMD_STATES       state;
    uint8_t             index;
    uint8_t             prev_index;
    COMMAND_STATUS      status;
    AT_COMMANDS* cmdSet;
    uint8_t             signal_bad; //the quality of 4G signal, 0: good, 1:bad
}COMMAND_STATE_INFO;
  • session: 當前會話狀態。
  • prev_session: 上一個會話狀態 (用於恢復)。
  • state: 當前命令執行狀態。
  • index: 當前命令在命令集中的索引。
  • prev_index: 上一個命令的索引。
  • status: 當前命令的執行結果狀態。
  • cmdSet: 指向當前使用的 AT 命令集陣列。
  • signal_bad: 4G 訊號品質標誌 (0: 好, 1: 差)。
typedef struct GPS_LOCATION

功能: 儲存 GPS 定位資訊。

typedef struct {
    char utcTime[16];
    char utcDate[16];
    char latitude[32];
    char longitude[32];
} GPS_LOCATION;
  • utcTime: UTC 時間字串。
  • utcDate: UTC 日期字串。
  • latitude: 緯度字串。
  • longitude: 經度字串。
typedef struct MODEM_DATA

功能: 數據機的整體數據和狀態儲存結構,包含了數據機運行所需的所有關鍵資訊。

typedef struct MODEM_DATA
{
    uint8_t modem_uuid_md5[33];
    uint8_t lte_4G_TX_flag;
    uint8_t lte_4G_TX_data[UART_TX_RX_SIZE*2+100];

    uint8_t lte_4G_RX_index1;
    uint8_t lte_4G_RX_index2;
    uint8_t lte_4G_RX_data[LTE_4G_RX_DATA_COUNT][UART_TX_RX_SIZE];
    uint8_t error_count;
    uint8_t relog_request;

    uint8_t chk_sq_cnt;

    COMMAND_STATE_INFO at_cmd_info;

    uint8_t  lte_4G_gps_first_flag;
    uint8_t  lte_4G_gps_read_flag;
    uint32_t lte_4G_gps_tick;

    GPS_LOCATION gpsLoc;

    uint32_t at_gps_read_time;

    UTC_TIME rtc_time;
    uint8_t chk_mqtt_login;
    uint8_t lte_4G_csqval;
} MODEM_DATA;
  • modem_uuid_md5: 數據機的 UUID (MD5 格式)。
  • lte_4G_TX_flag: 4G 數據發送標誌。
  • lte_4G_TX_data: 用於發送 IoT 數據的緩衝區。
  • lte_4G_RX_index1, lte_4G_RX_index2: 接收數據緩衝區的索引。
  • lte_4G_RX_data: 接收到的訊息列表。
  • error_count: 錯誤計數。
  • relog_request: 重新登錄請求標誌。
  • chk_sq_cnt: 檢查訊號品質的計數。
  • at_cmd_info: 數據機狀態機的當前資訊。
  • lte_4G_gps_first_flag, lte_4G_gps_read_flag, lte_4G_gps_tick: GPS 讀取相關的標誌和計時。
  • gpsLoc: GPS 定位資訊。
  • at_gps_read_time: GPS 讀取時間間隔。
  • rtc_time: RTC 時間資訊。
  • chk_mqtt_login: MQTT 登錄狀態 (1: 登錄, 0: 登出)。
  • lte_4G_csqval: 4G 訊號品質 (CSQ 值)。
typedef enum CMD_STATUS (不同於 COMMAND_STATUS 的狀態)

功能: 定義命令響應的狀態,特別用於 chk_cmd_response() 函式的返回結果。

typedef enum {
    CMD_STATUS_OK = 0,
    CMD_STATUS_BAD_SQ,
    CMD_STATUS_BAD_GPS,
}CMD_STATUS;
  • CMD_STATUS_OK: 命令響應正常。
  • CMD_STATUS_BAD_SQ: 訊號品質不佳。
  • CMD_STATUS_BAD_GPS: GPS 數據不佳。
靜態 AT 命令集陣列

以下是數據機初始化、檢查訊號、獲取 GPS、發送數據、登出登入和輪詢等不同會話所使用的 AT 命令集定義。

這些陣列包含了 _CMD_MODESsleeps (延遲或下一會話) 和實際的 command 字串。

例如:

static AT_COMMANDS atCmdInit[]={
    // ...
    {_CMD_MODE_CSQ    ,2  ,"AT+CSQ\r\n"},
    {_CMD_MODE_TM     ,2  ,"AT+CCLK?\r\n"},
    // ...
    {_CMD_MODE_END    ,_AT_SESSION_FREE_RUN ,""}
};

static AT_COMMANDS atCmdChkSQ[] = {
    {_CMD_MODE_CSQ    ,1  ,"AT+CSQ\r\n"},
    {_CMD_MODE_END    ,99 ,""} //back to previous session
};

static AT_COMMANDS atCmdGetGPS[] = {
    {_CMD_MODE_TM     ,1  ,"AT+CCLK?\r\n"},
    {_CMD_MODE_GPS    ,1  ,"AT+UGRMC?\r\n"},
    {_CMD_MODE_END    ,_AT_SESSION_FREE_RUN  ,""}
};

static AT_COMMANDS atTxData[] = {
    {_CMD_MODE_TM     ,1  ,"AT+CCLK?\r\n"},
    {_CMD_MODE_UP     ,1  ,"AT+UMQTTC=2,0,0,1,\"EMOTO/DEV/"},
    {_CMD_MODE_END    ,_AT_SESSION_FREE_RUN  ,""}
};

static AT_COMMANDS atCmdLogOutIn[] = {
    {_CMD_MODE_0      ,2  ,"AT+UMQTTC=0\r\n"},
    {_CMD_MODE_0      ,2  ,"AT+UMQTTC=1\r\n"},
    {_CMD_MODE_DOWN   ,2  ,"AT+UMQTTC=4,0,\"EMOTO/DEV/"},
    {_CMD_MODE_PUB    ,2  ,"AT+UMQTTC=4,0,\"EMOTO/DEV/"},
    {_CMD_MODE_END    ,_AT_SESSION_FREE_RUN  ,""}
};

static AT_COMMANDS atCmdPolling[] = {
    {_CMD_MODE_TM     ,1  ,"AT+CCLK?\r\n"},
    {_CMD_MODE_POLL   ,1  ,"AT+UMQTTC=6\r\n"},
    {_CMD_MODE_END    ,_AT_SESSION_FREE_RUN ,""}
};

static void* atCommands[] = {
    atCmdInit,          //_AT_SESSION_INIT
    0,                  //_AT_SESSION_RESET
    atCmdChkSQ,         //_AT_SESSION_CHK_SQ
    0,                  //_AT_SESSION_WAIT_TO_CHK_SQ
    0,                  //_AT_SESSION_FREE_RUN
    atTxData,           //_AT_SESSION_TX
    0,                  //_AT_SESSION_WAIT_TO_GET_GPS
    atCmdGetGPS,        //_AT_SESSION_GET_GPS
    atCmdLogOutIn,      //_AT_SESSION_LOG_OUT_IN
    atCmdPolling,       //_AT_SESSION_POLLING
    0                   //_AT_SESSION_FREE_RUN1
};