arduinoで行うタスクがいくつかありますが、そのうちの1つは非常に時間がかかるため、スレッドを使用して同時に実行することを考えていました。私はArduinoメガを持っています
[更新] ついに 4 年後、私の arduino メガに FreeRTOS をインストールできるようになりました。ここにリンクがあります
arduinoで行うタスクがいくつかありますが、そのうちの1つは非常に時間がかかるため、スレッドを使用して同時に実行することを考えていました。私はArduinoメガを持っています
[更新] ついに 4 年後、私の arduino メガに FreeRTOS をインストールできるようになりました。ここにリンクがあります
要するに:いいえ。しかし、あなたはそれを試してみることができます: http ://www.kwartzlab.ca/2010/09/arduino-multi-threading-librar/
まだですが、大きなプロジェクトでは常にこのライブラリを使用しています: https://github.com/ivanseidel/ArduinoThread
タイマー割り込み内にコールバックを配置すると、出来上がりです。Arduinoで実行されている疑似スレッドがあります...
このスレッドをより完全にするために、メモリフットプリントが非常に小さく(私の記憶が正しければ数バイト)、スレッドローカルの変数を保持するプロトスレッドもあります。非常に便利で時間を節約できます (有限状態マシンがはるかに少ない -> より読みやすいコード)。
例とコード: arduino-class / ProtoThreads wiki
どのような結果が期待できるかをお知らせします: シリアル通信 @ 153K6 ボーレートとスレッド: ステータス ダイオードの点滅、時間管理、要求された関数の評価、IO 処理とロジック、およびすべて atmega328 で。
実際のスレッドではありませんが、TimedActions は多くの用途に適した代替手段です
http://playground.arduino.cc/Code/TimedAction#Example
もちろん、1 つのタスクがブロックされると、他のタスクもブロックされますが、スレッドによって 1 つのタスクがフリーズしても、他のタスクは続行されます...
前の答えは正しいですが、arduino は一般に非常に高速に実行されるため、コードのタイミングを適切に設定すれば、多かれ少なかれ同時にタスクを実行できます。
ベスト プラクティスは、独自の関数を作成し、デフォルトの void ループに実際のコードを入れすぎないようにすることです。
Arduino環境向けに設計されています。特徴:
古いコマンドの実行中に bluetooth/network/serial から新しいコマンドを受信する必要があり、古いコマンドに遅延がある場合に使用します。1 つのスレッドは、次のループを実行するサーバー スレッドです。
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
}
もう 1 つは、コマンドを実行するコマンド スレッドです。
int command_func(void* arg) {
// move some servos
arduinos_delay(1000); // wait for them to move
// move some more servos
}
率直な答えは No No No! です。いくつかの代替手段がありますが、Arduino メガから完全なマルチスレッド機能を期待することはできません。以下のように、arduino due または lenado をマルチスレッドに使用できます。
void loop1(){
}
void loop2(){
}
void loop3(){
}
通常、私はそのようなケースをバックエンドで処理します。Arduinoを使用して入力を収集し、出力を表示しながら、サーバーでメインコードを実行できます。そのような場合、wifiが組み込まれているnodemcuを好むでしょう。
Arduino はマルチスレッド プログラミングをサポートしていません。
ただし、このプロジェクトのようないくつかの回避策があります (Arduino IDE からもインストールできます)。
実際のマルチスレッド環境では、いつタスクを実行するかを決定するのはOSですが、スケジュール時間を自分で定義する必要があるようです。
または、プロトスレッドを使用できます
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)();
}