もう何年もタラタラと遊んでいた「ファンタシースターオンライン 2 (PSO2)」という MMORPG が、「PSO2 ニュージェネシス (PSO2NGS)」にアップデートされたので、せっせとレベリングに勤しんでおります。
またタラタラと何年も遊べるように、もうちょっとだけレベルを上げておきたいの。
そんなわけで、電子工作は放り出して、PSO2NGS 三昧な日々を過ごしております (^_^;)
閑話休題。
Arduino のマルチタスクとクラスについて、勉強中です。
前回は、C++ クラスを使ってサーボモータをインスタンス化しました。これにより、複数のサーボモータを独立して動かすことができるようになりました。
まぁサーボモータが 1 台しかないので、目出度さもちう位也、な気分ですが (;´Д`)
サーボと L チカはいくつ必要ですか?
Multi-tasking the Arduino – Part 1 では、サーボモータ 2台と LED 3 個を制御していますが、残念ながら俺の部品箱にサーボモータは 1 台しかなかったので、サーボモータ 1 台と LED 3 個を制御することにします。
どちらも必要な数だけインスタンス化すれば良いので、考え方は変わりません。
回路図です。
これまでに作っていた L チカの回路と、サーボモータの回路を組み合わせただけです。
前回も書きましたが、サーボモータは意外と電気食いますから、5V 電源はしっかりしたものにしましょう。
データシートに記述がないので実験してみたいと考えていますが、グーグル先生によると 300~500mA はみておかないといけなさそうです。もちろん負荷をかければ電流値は大きくなりますし、台数が増えれば台数分だけの容量が必要です。
なので Arduino の 5V 出力は避けたほうがいいでしょう。
スケッチ
これも、これまでに作った L チカのスケッチと、サーボモータのスケッチをマージしただけです。少し書式や変数名を修正した部分がありますが、機能に違いはありません。
- #include <Servo.h>
- class Flasher {
- byte ledPin;
- unsigned long OnTime;
- unsigned long OffTime;
- bool ledState;
- unsigned long previousMillis;
- public:
- Flasher(byte pin, unsigned long on, unsigned long off) {
- ledPin = pin;
- pinMode(ledPin, OUTPUT);
- OnTime = on;
- OffTime = off;
- ledState = LOW;
- previousMillis = 0;
- }
- void Update() {
- unsigned long currentMillis = millis();
- if ((HIGH == ledState) && (OnTime < currentMillis - previousMillis)) {
- ledState = LOW;
- previousMillis = currentMillis;
- digitalWrite(ledPin, ledState);
- }
- else if ((LOW == ledState) && (OffTime < currentMillis - previousMillis)) {
- ledState = HIGH;
- previousMillis = currentMillis;
- digitalWrite(ledPin, ledState);
- }
- }
- };
- class Sweeper {
- Servo myservo;
- byte updateInterval;
- unsigned long lastUpdate;
- byte pos;
- byte increment;
- public:
- Sweeper(byte interval) {
- updateInterval = interval;
- lastUpdate = 0;
- pos = 0;
- increment = 1;
- }
- void Attach(byte pin) {
- myservo.attach(pin);
- }
- void Update() {
- if (updateInterval < millis() - lastUpdate) {
- lastUpdate = millis();
- pos += increment;
- myservo.write(pos);
- if (180 <= pos || 0 >= pos) increment = -increment;
- }
- }
- };
- Flasher led1(11, 123, 400);
- Flasher led2(12, 350, 350);
- Flasher led3(13, 200, 222);
- Sweeper sweeper1(15);
- void setup() {
- sweeper1.Attach(10);
- }
- void loop() {
- led1.Update();
- led2.Update();
- led3.Update();
- sweeper1.Update();
- }
Now we have 5 independent tasks running non-stop with no interference. And our loop() is only 5 lines of code!
https://learn.adafruit.com/multi-tasking-the-arduino-part-1/a-clean-sweep
ブレッドボード
実験に使ったブレッドーボードのようすです。
サーボモータはお馴染みの SG90 です。コネクタの左に LED が 3 個あります。
Arduino は UNO を使いました。いつぞや AVR が故障して交換したやつですが、順調に働いてくれています。
一番下のブレッドボードは電源回路です。三端子レギュレータ 7805 なので 1A の電流は十分にとれると思います。
が、それでもサーボモータを動かすと出力電圧はかなりパルス状になります。電流だけが原因ではないのかもしれません。この辺も今度調べてみたいですね。
Next we’ll add a button so we can interact with some of these tasks.
https://learn.adafruit.com/multi-tasking-the-arduino-part-1/a-clean-sweep
さて、次回はこれにスイッチを取り付けて、一部のタスクの操作ができるようにしてみましょう。