2015-07-19 89 views
0

我得到了問題,下面的代碼不是多任務處理。 我怎麼能意識到這一點? 我的代碼現在工作如下: 我開始我的Android應用程序,在那裏我確認USB請求。 按下「開始按鈕」後,我的應用程序發送一個字節數組到我的arduino板。 問題是,「stepper2(ingredient1value);」只能在「stepper1 ...」完成時啓動。Arduino多任務

我知道arduino不是多線程的正確平臺,但我看到了一些解決方案,但是我無法將它們集成到我的代碼中。

感謝您的幫助!

#include <Max3421e.h> 
#include <Usb.h> 
#include <AndroidAccessory.h> 



#define VALUE_OFF 0x0 
#define VALUE_ON 0x1 
#define COMMAND_LED 0x2 
#define TARGET_PIN_12 0x12 

int stepperPin1 = 9; 
int stepperPin2 = 10; 
int stepperPin3 = 11; 
int stepperPin4 = 12; 
int stepperPin5 = 13; 



//change this to the number of steps on your motor 
#define STEPS 48 

AndroidAccessory acc("Manufacturer", "Model", "Description", "1.0", "URI","Serial"); 
byte ingredient1value, ingredient2value, ingredient3value, ingredient4value, ingredient5value; 
byte rcvmsg[8]; 



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


pinMode(stepperPin1, OUTPUT); 
pinMode(stepperPin2, OUTPUT); 
pinMode(stepperPin3, OUTPUT); 
pinMode(stepperPin4, OUTPUT); 
pinMode(stepperPin5, OUTPUT); 
    acc.powerOn(); 
} 


void stepper1(int turns1){ 
for(int i=0;i<turns1*STEPS;i++){ 
    digitalWrite(stepperPin1, HIGH); 
    delayMicroseconds(800); 
    digitalWrite(stepperPin1, LOW); 
    delayMicroseconds(800); 
    } 
} 



void stepper2(int turns2){ 
for(int i=0;i<turns2*STEPS;i++){ 
    digitalWrite(stepperPin2, HIGH); 
    delayMicroseconds(800); 
    digitalWrite(stepperPin2, LOW); 
    delayMicroseconds(800); 
    } 
} 



void stepper3(int turns3){ 
for(int i=0;i<turns3*STEPS;i++){ 
    digitalWrite(stepperPin3, HIGH); 
    delayMicroseconds(800); 
    digitalWrite(stepperPin3, LOW); 
    delayMicroseconds(800); 
    } 
} 




void stepper4(int turns4){ 
for(int i=0;i<turns4*STEPS;i++){ 
    digitalWrite(stepperPin4, HIGH); 
    delayMicroseconds(800); 
    digitalWrite(stepperPin4, LOW); 
    delayMicroseconds(800); 
    } 
} 




void stepper5(int turns5){ 
for(int i=0;i<turns5;i++){ 
    digitalWrite(stepperPin5, HIGH); 
    delay(1000); 
    digitalWrite(stepperPin5, LOW); 
    delay(1000); 
    } 
} 



void loop() { 
    delay(50); 
    if (acc.isConnected()) { 
    acc.read(rcvmsg, sizeof(rcvmsg), 1); 

    if (rcvmsg[0] == COMMAND_LED && rcvmsg[1] == TARGET_PIN_12) { 
     byte value = rcvmsg[2]; 

     if (value == VALUE_ON){ 
     ingredient1value=rcvmsg[3] ; 
     ingredient2value=rcvmsg[4] ; 
     ingredient3value=rcvmsg[5] ; 
     ingredient4value=rcvmsg[6] ; 
     ingredient5value=rcvmsg[7] ; 

     stepper1(ingredient1value); 
     stepper2(ingredient2value); 
     stepper3(ingredient3value); 
     stepper4(ingredient4value); 
     stepper5(5); 

     } 
    } 
    } 


} 
+0

這是我不清楚在多任務/多線程應該做的。在Android或Arduino上?那是Arduino或Android應用程序的C代碼?我看不到任何Android代碼。那是對的嗎? – greenapps

+0

@greenapps:這是毫無疑問的沒有C代碼,所以我刪除了標籤。 – Olaf

+0

你爲什麼不說出它是什麼?你爲什麼不回答我的其他問題? – greenapps

回答

2

一種方法可能是避免你的代碼delay()(或delayMicroseconds())與代碼模式,不中斷主循環,並允許Arduino的在特定頻率或時間執行命令替換這些代碼通道。

下面是一個例子可以如何執行一個功能每秒不使用delay()(並且沒有塊之外的命令,應具有較高的頻率被執行):

// 1 sec. frequency 
unsigned long interval=1000; // the time we need to wait 
unsigned long previousMillis=0; // millis() returns an unsigned long. 

// 3 sec. frequency 
unsigned long interval1=3000; // the time we need to wait 
unsigned long previousMillis1=0; // millis() returns an unsigned long. 

void setup() { 
    //... 
} 

void loop() { 

if ((unsigned long)(millis() - previousMillis) >= interval) { 
    previousMillis = millis(); 
    // every second 
    // ... 
} 

if ((unsigned long)(millis() - previousMillis1) >= interval1) { 
    previousMillis1 = millis(); 
    // every third second 
    // ... 
} 

// other CMD's... 
} 

編輯:

這種方法沒有集成真正的多任務,但可以讓您在項目中集成僞並行。

我增加了第二個條件(每三秒執行一次)來舉例說明原理。

+1

非常好!我不得不看兩次。您可以使用第二個3000毫秒的時間間隔發佈它。會更清楚。但無論如何好。 – greenapps

1

研究我對這個問題的回答。我解釋了一種實現虛擬多任務的方法;它非常適合您的問題:

http://stackoverflow.com/questions/13583419/arduino-interrupt-alternatives/32375444#32375444 
1

通過user3704293基本上回答是正確的:

  1. 對於要定期執行,創建一個變量 保持動作之間的時間間隔,以毫秒爲單位的每個動作。

  2. 創建第二個變量來保存時間,最後一個 被觸發。

  3. 創建一個if語句來檢查自上次觸發了多少時間已經過去了,並觸發動作,如果時間比間隔大於最後觸發的
  4. 寫入時間爲變量

然而,這天真的算法失敗,如果Arduino運行超過一個月。大約50天后,millis();函數將達到最大值,並翻轉回零。一旦發生這種情況,您的代碼將不再觸發。

請關注arduino操場上的this guide,這是許多業餘愛好者混淆的原因。這對您的項目可能無關緊要,但可能適用於其他項目。

如果您的項目變得更加複雜,它將受益於有一個真正的調度程序,而不是讓你重新發明輪子。它就像一個小型操作系統,爲您管理多項任務。有些可用作Arduino庫。 DuinOS是一個很好的看看,它基於FreeRTOS - 非常流行,你會看到它無處不在。如果你學會了如何使用它,那將會很好地爲你服務。 如果程序內存不足,請改爲使用Protothreads。還有其他的選擇,但這些是開始的好地方。

最後,如果你需要安排在一個日曆日期,您將需要連接一個實時時鐘,看看the Time library