2015-05-29 247 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) { 
    ... 
}