我在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
}
答案 0 :(得分:2)
看起来你可能想重新设计它。虽然您可能希望在桌面平台上使用类似线程的东西,但您在Arduino UNO上不会以这种方式获得并发的任何硬件支持。但是,您可以使用中断来解决当前问题。
将传感器置于引脚更改中断。增加ISR中的计数器以用于该引脚更改中断。 Arduino UNO有一些通用的引脚更改中断,请查看数据表以获取更多信息。
然后使用其中一个内部计时器创建计时器。将此连接到一个中断,当定时器中断触发计数器数量然后把它放在一边。然后,您需要将该值发送到服务器。尝试使发送不阻止。您可能需要在多个循环周期内为主循环中的发送提供服务。
通过使用中断,尤其是时序中断,您将释放大量处理器周期。尽量减少每个ISR中的代码量,以免丢失中断数据。
答案 1 :(得分:1)
微控制器硬件或语言中没有并发性。
执行此操作的正确方法是使用interrupt
异步接受来自传感器的更新。
你也不应该阻止发送,你应该发送几个字节,然后在每个循环中再发送一些。
答案 2 :(得分:0)
使用中断是首选方法,但您也可以使用简单或定时调度程序。
我一直在做一个需要一个项目的项目,你可以找到source code here。它基于Zuph的更广泛的排队库AVRQueue。
Scheduler库的简单实现。我最初编写它是用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) {
...
}