13
9

arduinoで並列処理(ノンプリエンプティブ)

Last updated at Posted at 2020-02-09

概要

Arduino Unoに使用されているAVRはシングルスレッドのため、x86 CPUのようなマルチスレッド処理はできませんが、代わりにプロトスレッド処理を組み込むライブラリがあります。
https://playground.arduino.cc/Code/TimedAction/

プロトスレッドとは簡易的なマルチスレッドであり、各スレッドはノンプリエンプティブ(あるタスクがCPUを専有している間は他の処理を開始できない)です。
今回はこのライブラリを用いて、Arduinoにマルチスレッド的な動作を組み込みます。

環境

  • Arduino UNO
  • Sparkfun Wireless Motor Driver Shield
  • サーボ:SG90

ライブラリ導入

  1. このページの"Download here: Attach:TimedAction-1_6.zip"からzipをダウンロード&解凍。中身をarduinoIDEのライブラリディレクトリに入れてください。
  2. このままですとコンパイル時にエラーが出る場合があるので、1で配置した中身のTimedAction.hの#include "WProgram.h"#include "Arduino.h"に変更してください。

コード

サーボは2秒毎に反転動作、LEDは3秒毎にLチカさせてます。

#include <TimedAction.h>
#include <Servo.h> 

Servo swivel;

#define ledPin 13
boolean ledState = false;
boolean servoState = false;

void blink();
void toggle_servo();

TimedAction ledAction = TimedAction(3000,blink);
TimedAction servoAction = TimedAction(2000,toggle_servo);

void setup(){
  delay(5000);
  pinMode(ledPin,OUTPUT);
  digitalWrite(ledPin,ledState);

  swivel.attach(11); // Attach servo to pin 11
  swivel.write(90); 
}
 
void loop(){
  ledAction.check();
  servoAction.check();
}

void blink(){
  ledState ? ledState=false : ledState=true;
  digitalWrite(ledPin,ledState);
}

void toggle_servo(){
  servoState ? servoState=false : servoState=true;
  if (servoState){
    swivel.write(90); 
  }else{
    swivel.write(100); 
  }
}

動作検証

サーボは2秒毎、LEDは3秒毎に動作をしています。

今後

ここでプリエンプティブな実装を行っているので、試したいです。

Haskellによる実装

以下にてHaskellのAtomライブラリを使用した並列処理を掲載しています。
https://zenn.dev/4ergfbv547uezdf/scraps/2fe2002b0ebfb0
コード載せていないですがArduinoでも利用可能でした。ただしこのライブラリの難易度は超高いです。

参考サイト

https://playground.arduino.cc/Code/TimedAction/
https://learn.sparkfun.com/tutorials/wireless-motor-driver-shield-hookup-guide/all

13
9
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
9