前回は、3個のLED、2台のサーボモーター、1個のスイッチを使って、それぞれ独立して動作するマルチタスクのレッスンを、Arduino Nano Every で試してみました。
今回は、ちょっと後先になるのですが、サーボモータを動かすレッスンを、もう一度やってみます。
サーボモータを動かす方法
サーボモータを動かすにはどうすればよいのか。過去に試してみたことがあります。
サーボモータは、規定の幅のパルスを 1 回与えると、その幅に応じた角度まで動きます。そして、連続して動かすため、あるいは、その位置で止めておくために、20ms 周期でパルスを与える、のでした。
20ms という周期はラフです。周期が半分でも倍でも、サーボモータは動きます。なぜ 20ms なのか。データシートにそう書いてあるから、ですね m(_ _;)m
Arduino には、servo.h というライブラリがあります。これを使えば、そんな動作原理など気にせずにサーボモータは使えます。
でも、そこはそれ、勉強ですから、ライブラリを使わずに動かしてみることにしましょう。
回路図
サーボモータを動作させる回路は、スケッチ例の Knob にならいますが、サーボモータは 2 台にしています。2 台のサーボモータを、独立して、同時に動くようにします。
入力のボリュームの電源は、Arduino の 5V 出力を使用し、モータの電源と分離します。
アナログ入力のコンデンサ C5 、C6 は、ノイズ除去と、入力のインピーダンスを下げる目的です。
モータ用の 5V 電源容量は、3A 程度以上をお勧めします。Arduino の 5V 出力は避けるのが吉です。
スケッチ
スケッチは、ライブラリを使っていません。ライブラリを使うもよし、使わんでもよし。お好みでどうぞ。
マルチタスクを行なうスケッチなので、クラスを使ってみました。まだよくわからんですが、まぁこんなもんでしょ (^_^;)
- // Servo to follow (class) 2022.06.30 meyon
- // without library
- class Follow {
- byte servoPin;
- byte potentiometerPin;
- int value;
- unsigned long pwmPeriod;
- int minDutyCycle;
- int maxDutyCycle;
- unsigned long prevMillis;
- int dutyCycle;
クラスの宣言とメンバ変数。
- public:
- Follow(byte pot, byte serv) {
- potentiometerPin = pot;
- servoPin = serv;
- pinMode(servoPin, OUTPUT);
- pwmPeriod = 20;
- minDutyCycle = 600;
- maxDutyCycle = 2300;
- prevMillis = 0;
- }
コンストラクタは、全ての変数を初期化します。
pwmPeriod は、パルスの周期 20ms を規定しています。が、ループを回るのに時間がかかるので、実際には 22ms ぐらいで、わりと不安定です。
minDutyCycle と maxDutyCycle は、0° と 180° のときのパルス幅 (μs) です。データシートでは、それぞれ 0.5ms 、2.4ms ですが、個体によってばらつきがあり、今回使ったサーボモータでは、この値が良い感じでした。
- void update() {
- value = analogRead(potentiometerPin);
- dutyCycle = map(value, 0, 1023, minDutyCycle, maxDutyCycle);
- if(pwmPeriod < millis() - prevMillis) {
- digitalWrite(servoPin, HIGH);
- delayMicroseconds(dutyCycle);
- digitalWrite(servoPin, LOW);
- prevMillis = millis();
- }
- }
- };
メンバ関数。サーボモータの制御を行ないます。
ボリュームの位置を読み取り、パルス幅に変換します。更新時間を過ぎていれば、パルスを出力します。パルス出力中は delay させているので、その分が周期の遅れになります。
- Follow follow1(0, 9);
- Follow follow2(1, 10);
- void setup() {
- }
- void loop() {
- follow1.update();
- follow2.update();
- }
オブジェクトの生成。
setup() はすること、ないです。
loop() で、インスタンスごとに update() を呼び出します。
言葉が面倒くさい (;´Д`)
ブレッドボード
動画ではないですが、とりあえずこんな感じでやってます。ってことで。
まとめ
サーボモータを動かすことはこれまでもやってきているので、特に問題はないでしょう。気をつけなければならないことは、モータ用の電源の容量。1 台あたり 1.2A 以上を確保するのが吉です。
今回試したかったのは、Arduino Nano Every でもそのまま動くか、ってところです。こちらも、特に Arduino Nano と置き換えて比較してませんが、これまでと同様にスケッチ書いて制御できていますので、問題はないだろうと思います。
なお、リファレンスによれば、ライブラリ servo.h は Arduino Nano Every に対応しています。