2015-05-29 185 views
1

我在Arduino Uno中面臨一個應用程序的問題。Arduino Uno,多進程,多線程

董事會有一個傳感器,它每秒計算產品,一段時間後它將產品數量發送到服務器,但此過程需要一秒多的時間,所以它正在註冊產品的代碼不會直到此過程已完成,因此有時不會計算一件產品。

我一直在尋找是否Arduino支持多線程爲了有一個線程發送數據到服務器和另一個用於註冊產品數量,但我到目前爲止沒有明確的答案。

面對這個問題最好的解決方案是什麼?

const long MAX_ITERATION = 100000; 
const int OFF = 1; 
const int ON = 0; 
const int PHOTOELECTRIC_SENSOR = 3; 

int counter = 0; 
long iteration = 0; 
int state = OFF; 

void loop() { 
    registerProduct(); 
    if (iteration >= MAX_ITERATION) { 
     // this process takes more than a second 
     sendDataToServer(); 
     iteration = 0; 
    } 
    iteration++; 
} 

void registerProduct() { 
    int currentSensorState = digitalRead(PHOTOELECTRIC_SENSOR); 
    if (currentSensorState != state) { 
     if (currentSensorState == ON) { 
      counter++; 
     } 
    } 
    state = currentSensorState; 
} 

void sendDataToServer() { 
    // Sends data through HTTP protocol, and sets counter to zero 
} 

回答

2

看起來你可能想重新設計這個。雖然您可能想要在桌面平臺上使用線程等功能,但您在Arduino UNO上沒有以這種方式支持併發的任何硬件支持。但是,您確實有可以用於當前問題的中斷。

將傳感器置於引腳更改中斷。針對該引腳更改中斷增加ISR中的計數器。 Arduino UNO有幾個通用引腳電平變化中斷,請查看數據表瞭解更多信息。

然後使用其中一個內部定時器創建一個定時器。把它附加到一箇中斷,當定時器中斷觸發計數器時,然後把它放在一邊。您需要將該值發送到服務器。嘗試使發送不阻止。您可能需要在多個循環中爲主循環中的發送提供服務。

通過使用中斷,特別是定時中斷,您將釋放大量處理器週期。儘量保持每個ISR中的代碼數量儘可能少,以免丟失丟失中斷的數據。

+0

非常感謝,我會嘗試你的建議。 – jahepi

1

單片機硬件或語言沒有併發性。

正確的做法是使用interrupt以異步方式接受傳感器的更新。

你也不應該阻止發送,你應該發送幾個字節,然後在每個循環中發送幾個字節。

+0

謝謝Jarrod,會閱讀關於中斷。 – jahepi

0

使用中斷將是首選方法,但您也可以使用簡單或定時調度程序。

我一直在研究一個剛纔需要的項目,你可以找到source code here。它基於Zuph更廣泛的排隊庫AVRQueue

調度程序庫的簡單實現。我最初寫它是用avr-c編譯器編譯的,並沒有用arduino IDE進行測試,但它不應該成爲問題。

Scheduler m(); 

void setup() { 
    m.addTask(querySensor, "q_sens", 0, 1000); 
    m.addTask(doStuffWithData, "stuff", 0, 5000); 
} 

void loop() { 
    m.run(millis()); 
} 

int querySensor(unsigned long now) { 
    ... 
} 

int doStuffWithData(unsigned long now) { 
    ... 
}