2017-06-05 188 views
1

我有大約6個傳感器(GPS,IMU等),我需要不斷收集數據。出於我的目的,我需要從每個(在很短的時間範圍內)讀取一個完整的數據包。現在我正在使用中斷,但是這會導致來自某些傳感器的更多數據,而且如前所述,我需要將數據匹配起來。嵌入式系統 - 輪詢

移動到基於輪詢的系統中,我可以按設定的順序輪詢每個傳感器嗎?這樣我可以從每個「週期」的每個傳感器獲取數據。

但是,我擔心輪詢的速度,因爲這個系統需要接近實時運行。

+3

所以問題是...?測試你的投票循環時間,看看它是否符合你的要求... – LPs

+0

我個人不喜歡投票。你的傳感器沒有中斷嗎? – Alex

+0

既不僅僅是輪詢,也不是中斷只與實時有關,你必須做你的系統工程,這會給出所有的答案。輪詢當然是最容易的,你可以確定每條事件路徑的時間,只要最慢的一條不干擾其他條件的要求,你就很好。有時候你可以只通過輪詢來做到這一點,或者只能打斷它,但可能會在中間的某個地方結束。中斷並不意味着你在那裏處理它們,有時候不好,所以沒有人回答。 –

回答

1

輪詢結合「主定時器中斷」可能是你的朋友在這裏。假設您的「最慢」傳感器可以提供20ms間隔的數據,並且可以更快地讀取其他數據。這是50更新每秒。如果這個距離足夠接近實時(可能對於IMU是近距離的),那麼你可能會這樣做:

  1. 設置一個20ms定時器。
  2. 當計時器熄滅,設置一個標誌中斷服務程序中:

    volatile uint8_t timerFlag = 0; 
    
    ISR(TIMER_ISR_whatever) 
    { 
        timerFlag = 1; // nothing but a semaphore for later... 
    } 
    
  3. 然後,在你的主循環行爲時timerFlag說,它的時間:

    while(1) 
    { 
        if(timerFlag == 1) 
        { 
         <read first device> 
         <read second device> 
         <you get the idea ;) > 
         timerflag = 0; 
        } 
    } 
    

通過這種方式,您可以讀取每個設備並保持其讀數同步。這是解決嵌入式空間中這個問題的典型方法。現在,如果你需要的數據速度超過20ms,那麼你縮短了計時器等等。像這樣的情況下,最大的問題是「你能輪詢多快」與「你需要輪詢多快」。 「只有實驗並瞭解各種設備的特性和時間才能告訴你。但是,當所有時機「合適」時,我提出的是一個通用解決方案。

編輯,採用不同的方法

更基於中斷的例子:

volatile uint8_t device1Read = 0; 
volatile uint8_t device2Read = 0; 
etc... 

ISR(device 1) 
{ 
    <read device> 
    device1Read = 1; 
} 
ISR(device 2) 
{ 
    <read device> 
    device2Read = 1; 
} 
etc... 


// main loop 
while(1) 
{ 
    if(device1Read == 1 && device2Read == 1 && etc...) 
    { 
     //< do something with your "packet" of data> 
     device1Read = 0; 
     device2Read = 0; 
     etc... 
    } 
} 

在這個例子中,你的所有設備可以中斷驅動,但主循環處理仍然是制約,由最慢的中斷節奏來調節。無論速度或延遲如何,均可使用每個設備的最新完整讀數。這種模式更接近您的想法嗎?

+1

@Clifford確實。在這樣的情況下,我所做的是外圍設備採樣速率大不相同的情況,就是使用計數器「減速」timerFlag。平衡機器人的IMU可能需要50次更新/秒才能保持直立,而GPS只能輪詢50次。 – TomServo

+1

這就是爲什麼我不喜歡投票。使用這種方法,您必須計算所有傳感器組合的數據處理延遲,並確保第一個輪詢間隔不超過20ms(作爲示例)。只要您將來添加新的傳感器,或者傳感器在數據處理或輪詢間隔方面發生變化,您的所有環路方案就會陷入癱瘓,變得完全不可維護且不可擴展。 – Alex

+1

@亞歷克斯同意。我更喜歡在可能的情況下中斷。然而,OP的問題是關於投票的問題,事實是,有可能這樣做。 OP可能沒有興趣在這裏擴展任何東西,只是一次性的解決方案。因此,無需判斷我用可能的解決方案回答了她的問題。 – TomServo

1

輪詢是一個相當不錯的,容易實現的想法,以防您的傳感器可以(你期望的輸出頻率比較)提供的數據幾乎瞬間。如果數據源需要大量(甚至可變)時間來提供讀數或需要異步「啓動/收集」循環,它確實會陷入惡夢。您必須對輪詢週期進行排序以適應「最慢」數據源。

如果您知道每個數據源的平均「數據轉換率」,可以採用什麼方法來設置多個定時器(每個數據源),這些定時器在poll time - data conversion rate處觸發,並從這些數據源中啓動測量定時器ISR。然後在poll timer + some safety margin上觸發最後一個計時器,收集所有轉換結果。另一方面,只要你沒有任何合理的處理浪費的CPU/CPU資源,你從「快速」數據源中看到的「有太多測量結果」的明顯問題就不會對我造成太大的影響,傳感器負載。

如果您有一些浪費的週期,最後一個更簡單的方法是:簡單地將數據源從「最慢」排序到「最快」,然後按照該順序開始測量,然後等待結果以相同順序和民意調查。

+0

嗯!?輪詢和中斷混合。我喜歡。好的方法,將牢記在心。 – Alex