使用有限狀態機(FSM)可以使代碼結構更清晰,特別是處理復雜的狀態和過渡時。以下是如何根據你提供的步驟,用有限狀態機來實現自動校準和中斷觸發邏輯的示例代碼。
狀態定義
- IDLE: 空閑狀態,等待數據輸入。
- CALIBRATING: 進行基準值更新。
- ACT_THRESHOLD_EXCEEDED: 超過自校準閾值,暫停基準值更新。
- PERMANENT_STRESS: 檢測到永久/半永久性應力改變。
- INTERRUPT_TRIGGERED: 中斷已觸發狀態。
狀態轉移條件
這段代碼展示了如何使用有限狀態機來管理傳感器的自動校準和中斷觸發邏輯。你可以根據實際需求對具體邏輯進行調整和擴展。
- IDLE -> CALIBRATING: 啟動自動校準。
- CALIBRATING -> ACT_THRESHOLD_EXCEEDED: 讀值超過自校準閾值。
- ACT_THRESHOLD_EXCEEDED -> PERMANENT_STRESS: 超過自校準閾值且時間超過設定值。
- PERMANENT_STRESS -> CALIBRATING: 基準值更新。
- ANY -> INTERRUPT_TRIGGERED: 讀值超過中斷觸發閾值并超過預設采樣數。
- INTERRUPT_TRIGGERED -> IDLE: 讀值恢復正常。
#include <stdio.h> #include <stdlib.h> #include <stdbool.h> #include <time.h>#define CAL_PERIOD 4 // 基準值更新周期 (秒) #define CAL_RESET 10 // 基準值停止更新時間 (秒) #define ACT_THRESHOLD 5 // 自校準閾值 #define LIFT_DELAY 2 // 延遲時間 (秒) #define SAMPLE_THRESHOLD 3 // 觸發中斷的預設采樣數typedef enum {IDLE,CALIBRATING,ACT_THRESHOLD_EXCEEDED,PERMANENT_STRESS,INTERRUPT_TRIGGERED } State;typedef struct {int value; // 傳感器當前值int baseline; // 基準值int act; // 自動校準閾值int interrupt_threshold; // 中斷觸發閾值time_t last_update; // 上次基準值更新的時間State state; // 當前狀態int consecutive_samples; // 連續超過閾值的樣本計數 } Sensor;void update_baseline(Sensor *sensor) {// 更新基準值的邏輯sensor->baseline = sensor->value; // 簡單示例,實際可能需要更復雜的邏輯sensor->last_update = time(NULL);sensor->act = sensor->baseline + ACT_THRESHOLD;sensor->interrupt_threshold = sensor->baseline + ACT_THRESHOLD * 2; }void fsm_update(Sensor *sensor) {time_t current_time = time(NULL);switch (sensor->state) {case IDLE:if (sensor->value < sensor->act) {sensor->state = CALIBRATING;update_baseline(sensor);}break;case CALIBRATING:if (sensor->value > sensor->act) {sensor->state = ACT_THRESHOLD_EXCEEDED;sensor->last_update = current_time;} else if (current_time - sensor->last_update > CAL_PERIOD) {update_baseline(sensor);}break;case ACT_THRESHOLD_EXCEEDED:if (sensor->value <= sensor->act) {sensor->state = CALIBRATING;} else if (current_time - sensor->last_update > CAL_RESET) {sensor->state = PERMANENT_STRESS;}break;case PERMANENT_STRESS:update_baseline(sensor);sensor->state = CALIBRATING;break;case INTERRUPT_TRIGGERED:if (sensor->value < sensor->interrupt_threshold) {sensor->state = IDLE;}break;}if (sensor->value > sensor->interrupt_threshold) {sensor->consecutive_samples++;if (sensor->consecutive_samples >= SAMPLE_THRESHOLD) {sensor->state = INTERRUPT_TRIGGERED;}} else {sensor->consecutive_samples = 0;} }int main() {Sensor sensor = {0};sensor.baseline = 0;sensor.act = ACT_THRESHOLD;sensor.interrupt_threshold = ACT_THRESHOLD * 2;sensor.state = IDLE;sensor.last_update = time(NULL);// 模擬數據輸入int values[] = {1, 2, 3, 6, 8, 9, 3, 4, 5};int num_values = sizeof(values) / sizeof(values[0]);for (int i = 0; i < num_values; i++) {sensor.value = values[i];fsm_update(&sensor);printf("Value: %d, State: %d\n", sensor.value, sensor.state);}return 0; }
代碼說明
- State:定義不同狀態。
- Sensor:包含傳感器當前值、基準值、自動校準閾值、中斷閾值、上次更新基準值時間、當前狀態和連續超過閾值的樣本計數。
- update_baseline:更新基準值并調整閾值。
- fsm_update:根據當前狀態和傳感器值更新狀態。
- main:模擬數據輸入,更新傳感器狀態并輸出結果。