我有几个与arduino有关的任务,但其中一个需要很长时间,所以我想用线程同时运行它们。 我有一个Arduino Mega
[更新] 最后四年后,我可以在我的arduino mega中安装FreeRTOS。这是link
答案 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环境而设计。特性:
当我需要从蓝牙/网络/串行接收新命令时执行旧命令并且旧命令有延迟时,我使用它。 一个线程是执行以下循环的服务器线程:
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。