2015-07-19 120 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