アフィリエイト広告
アフィリエイト広告

Arduino のマルチタスク (6) すべてを一緒に

PSO2NGS のレベリングをしているかと思いきや、ちょいと忙殺されてまして、全然レベルが上がってません (;´Д`)

さて、Arduino のマルチタスクとクラスについての勉強も、Part 1 の最終回です。
参考にさせていただいた下記サイトには、さらに Part 2 、Part 3 として割り込み処理などの解説もありますので、興味のある方はご覧いただければと思います。

Multi-tasking the Arduino - Part 1
Once you have mastered the basic blinking leds, simple sensors and buzzing motors, it’s time to move on to bigger and better projects. That usually involves com...

前回は、C++ クラスを使ってインスタンス化した複数の LED とサーボモータを、それぞれ独立して制御することができました。

Arduino のマルチタスク (5) サーボと Lチカを独立して動かす
もう何年もタラタラと遊んでいた「ファンタシースターオンライン 2 (PSO2)」という MMORPG が、「PSO2 ニュージェネシス (PSO2NGS)」にアップデートされたので、せっせとレベリングに勤しんでおります。またタラタラと何年も...

入力も欲しいです

今回はこれにタクトスイッチをプラスして、スイッチの状態を監視できるようにしてみましょう。

With our millis()-based timing, the processor is free to check on button states and other inputs regularly. This allows us to build complex programs that do many things at once, but still remain responsive.

https://learn.adafruit.com/multi-tasking-the-arduino-part-1/all-together-now

All together now 回路図

回路図です。

D2 ピンにタクトスイッチをつなぎ、22KΩ の抵抗でプルアップしています。もちろん、内部プルアップでもかまいません。

スケッチです。

  1. #include <Servo.h>
  2. class Flasher {
  3.   byte ledPin;
  4.   unsigned long OnTime;
  5.   unsigned long OffTime;
  6.   bool ledState;
  7.   unsigned long previousMillis;
  8.   public:
  9.   Flasher(byte pin, unsigned long on, unsigned long off) {
  10.     ledPin = pin;
  11.     pinMode(ledPin, OUTPUT);
  12.     OnTime = on;
  13.     OffTime = off;
  14.     ledState = LOW;
  15.     previousMillis = 0;
  16.   }
  17.   void Update() {
  18.     unsigned long currentMillis = millis();
  19.     if ((HIGH == ledState) && (OnTime < currentMillis - previousMillis)) {
  20.       ledState = LOW;
  21.       previousMillis = currentMillis;
  22.       digitalWrite(ledPin, ledState);
  23.     }
  24.     else if ((LOW == ledState) && (OffTime < currentMillis - previousMillis)) {
  25.       ledState = HIGH;
  26.       previousMillis = currentMillis;
  27.       digitalWrite(ledPin, ledState);
  28.     }
  29.   }
  30. };
  31. class Sweeper {
  32.     Servo myservo;
  33.     byte updateInterval;
  34.     unsigned long lastUpdate;
  35.     byte pos;
  36.     byte increment;
  37.   public:
  38.   Sweeper(byte interval) {
  39.     updateInterval = interval;
  40.     lastUpdate = 0;
  41.     pos = 0;
  42.     increment = 1;
  43.   }
  44.   void Attach(byte pin) {
  45.     myservo.attach(pin);
  46.   }
  47.   void Update() {
  48.     if (updateInterval < millis() - lastUpdate) {
  49.       lastUpdate = millis();
  50.       pos += increment;
  51.       myservo.write(pos);
  52.       if (180 <= pos || 0 >= pos) increment = -increment;
  53.     }
  54.   }
  55. };
  56. Flasher led1(11, 123, 400);
  57. Flasher led2(12, 350, 350);
  58. Flasher led3(13, 200, 222);
  59. Sweeper sweeper1(15);
  60. void setup() {
  61.   sweeper1.Attach(10);
  62. }
  63. void loop() {
  64.   if(HIGH == digitalRead(2)) {
  65.     led1.Update();
  66.     sweeper1.Update();
  67.   }
  68.   led2.Update();
  69.   led3.Update();
  70. }

All together now!

変更したのは 79~82 行です。
タクトスイッチが押されている間 D2 は LOW になりますので、led1 と sweeper1 の状態は更新されず、停止状態となります。離すと再び動き始めます。

loop() は常に動いていますから、ボタンの状態も早いタイミングで検知されます。

まとめ

これまでの一連の「Arduino のマルチタスク」で、Arduino がボタン入力などの外部イベントに応答しながら、複数の独立したタスクをすばやく操作できることがわかりました。
このテクニックにより、小さなプロセッサを最大限に活用することができます。

In this guide we have demonstrated that it is indeed possible for the Arduino to juggle multiple independent tasks while remaining responsive to external events like user input.
These techniques won’t turn your Arduino into a supercomputer.  But they will help you to get the most out of this small, but surprisingly powerful little processor.

https://learn.adafruit.com/multi-tasking-the-arduino-part-1/conclusion
タイトルとURLをコピーしました