Arduino Uno,多进程,多线程

Arduino Uno, multiple processes, multi-threading

我在 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
}

微控制器硬件或语言中没有并发性。

执行此操作的正确方法是使用 interrupt 异步接受来自传感器的更新。

你也不应该阻止发送,你应该发送几个字节,然后在每个循环中发送更多字节。

看来您可能想要重新设计它。虽然您可能想在桌面平台上使用诸如线程之类的东西,但您在 Arduino UNO 上没有任何硬件支持以这种方式进行并发。但是,您确实有可用于解决当前问题的中断。

将传感器置于引脚更改中断。为该引脚更改中断增加 ISR 中的计数器。 Arduino UNO 有一些通用引脚更改中断,请查看数据表了解更多信息。

然后使用其中一个内部计时器创建一个计时器。将其附加到中断上,当定时器中断触发时获取计数器数量,然后将其放在一边。然后您需要将该值发送到服务器。尝试使发送不阻塞。您可能需要在多个循环周期内为主循环中的发送服务。

通过使用中断,尤其是定时中断,您将释放大量处理器周期。尽量保持每个 ISR 中的代码量尽可能少,这样您就不会因错过中断而丢失数据。

使用中断是首选方法,但您也可以使用简单的或定时的调度程序。

我一直在做一个前段时间需要的项目,你可以找到 source code here. It's based on a more extensive queuing library by Zuph called 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) {
    ...
}