Arduino支持线程吗?

时间:2012-12-22 12:50:45

标签: multithreading arduino

我有几个与arduino有关的任务,但其中一个需要很长时间,所以我想用线程同时运行它们。 我有一个Arduino Mega

[更新] 最后四年后,我可以在我的arduino mega中安装FreeRTOS。这是link

10 个答案:

答案 0 :(得分:13)

简而言之:不。 但你可以试一试: http://www.kwartzlab.ca/2010/09/arduino-multi-threading-librar/

答案 1 :(得分:5)

还没有,但我总是将这个图书馆与大项目一起使用: https://github.com/ivanseidel/ArduinoThread

我将回调置于定时器中断内,并且vo!你在Arduino上运行了伪线程......

答案 2 :(得分:5)

只是为了让这个线程更加完整:还有 protothreads ,它的内存占用非常小(如果我没记错的话,还有几个字节)并保留线程本地的变量;非常方便和省时(远不如有限状态机 - >更可读的代码)。

示例和代码: arduino-class / ProtoThreads wiki

只是为了让您知道您可能会得到什么结果:串行通信@ 153K6波特率与线程:状态二极管闪烁,时间保持,请求的功能评估,IO处理和逻辑以及所有atmega328。

答案 3 :(得分:4)

不是真正的线程,但TimedActions是许多用途的好选择

http://playground.arduino.cc/Code/TimedAction#Example

当然,如果一个任务阻止,其他任务也会阻止,而线程可以让一个任务冻结而其他任务将继续......

答案 4 :(得分:1)

之前的答案是正确的,但是,arduino通常运行得非常快,所以如果你正确地计算代码,它可以或多或少同时完成任务。

最佳做法是创建自己的函数,避免在默认的void循环中放入过多的实际代码

答案 5 :(得分:1)

您可以使用arduinos

专为Arduino环境而设计。特性:

  • 仅静态分配(无malloc / new)
  • 延迟执行时支持上下文切换
  • 实现信号量
  • 轻量级,包括cpu和内存

当我需要从蓝牙/网络/串行接收新命令时执行旧命令并且旧命令有延迟时,我使用它。 一个线程是执行以下循环的服务器线程:

while (1) {
    while ((n = Serial.read()) != -1) {
        // do something with n, like filling a buffer
        if (command_was_received) {
            arduinos_create(command_func, arg);
        }
    }
    arduinos_yield(); // context switch to other threads
}

另一个是执行命令的命令线程:

int command_func(void* arg) {
    // move some servos
    arduinos_delay(1000); // wait for them to move
    // move some more servos
}

答案 6 :(得分:1)

不,你不能,但你可以使用定时器中断。

答案 7 :(得分:1)

Arduino不支持多线程编程。

不过,有一些解决方法,例如this project中的解决方法(您也可以从Arduino IDE安装它)。

似乎您必须自己定义计划时间,而在真正的多线程环境中,操作系统决定何时执行任务。

或者您可以使用protothreads

答案 8 :(得分:0)

Arduino不支持线程化。但是,您可以做第二件好事,并在交错运行的状态机周围构建代码。

虽然有很多方法可以将您的任务实现为状态机,但我还是建议您使用此库(https://github.com/Elidio/StateMachine)。该库抽象了大部分过程。

您可以像这样创建一个状态机作为类:

#include "StateMachine.h"
class STATEMACHINE(Blink) {
  private:
    int port;
    int waitTime;
    CREATE_STATE(low);
    CREATE_STATE(high);

    void low() {
      digitalWrite(port, LOW);
      *this << &STATE(high)<< waitTime;
    }
    void high() {
      digitalWrite(port, HIGH);
      *this << &STATE(low)<< waitTime;
    }
  public:
    Blink(int port = 0, int waitTime = 0) :
      port(port),
      waitTime(waitTime),
      INIT_STATE(low),
      INIT_STATE(high)
      {
        pinMode(port, OUTPUT);
        *this << &STATE(low);
      }
};

STATEMACHINE()抽象化类继承,宏CREATE_STATE()抽象化状态包装的创建,宏INIT_STATE()抽象化方法的包装,宏STATE()抽象化状态包装的参考在状态机类中。

状态转换是由<<运算符在状态机类和状态之间进行抽象的,如果要延迟状态转换,您要做的就是将该运算符与整数一起使用,其中整数为延迟以毫秒为单位。

要使用状态机,首先必须实例化它。在设置函数上用new实例化对全局类的引用时,可以达到目的

Blink *led1, *led2, *led3;


void setup() {
  led1 = new Blink(12, 300);
  led2 = new Blink(11, 500);
  led3 = new Blink(10, 700);
}

然后循环运行状态。

void loop() {
    (*led2)();
    (*led1)();
    (*led3)();
}

答案 9 :(得分:0)

直接的答案是不,不!有一些替代方法,但是您不能期望arduino mega拥有完美的多线程功能。您可以使用arduino due或lenado进行多线程处理,如下所示-

void loop1(){
}
void loop2(){
}
void loop3(){
}

通常,我会在后端处理这类案件。您可以在使用Arduino的同时在服务器中运行主要代码,以仅收集输入并显示输出。在这种情况下,我宁愿使用内置wifi的nodemcu。