⚙
サーボを動かす方法
0度と180度を行き来する
サーボの主な仕様を確認する
SG90 がよく使われる
項目 | 値 |
---|---|
PWMサイクル | 20ms |
制御パルス | 0.5ms 〜 2.4ms |
制御角 | ±約90°(180°) |
配線 | 茶:GND 赤:電源 橙:制御信号 |
動作速度 | 0.1秒/60度 |
動作電圧 | 4.8 〜 5 V |
ここからわかること
- 一周期が 20ms (サーボが360度回転するのにかかる時間ではない)
- そのうちの 0.5ms だけ HIGH にすると0度になる
- そのうちの 2.4ms だけ HIGH にすると180度になる
- 電圧は 5 V なので Arduino の 5V をそのまま使える
角度と時間の対応
角度 | ms | μs |
---|---|---|
0 | 0.5 | 500 |
45 | 0.975 | 975 |
90 | 1.45 | 1450 |
135 | 1.925 | 1925 |
180 | 2.4 | 2400 |
- 0.5ms 〜 2.4ms が 0〜180度 に対応する
- なので時間(ms) は
0.5 + (2.4 - 0.5) / 180.0 * 角度
で求まる
配線
色 | 場所 | |
---|---|---|
橙 | 10 | PWM対応のピンならどこでもいい |
赤 | 5V | |
茶色 | GND |
抵抗もブレッドボードもいらない
0度に設定する例
void setup() {
pinMode(10, OUTPUT);
}
void loop() {
digitalWrite(10, HIGH);
delayMicroseconds(500);
digitalWrite(10, LOW);
delayMicroseconds(20000 - 500);
}
- HIGH を 500μs 続けたあとLOW を
20000μs - 500μs
続ける- 20000 はPWMサイクル 20ms のこと
- 仮に500を2400にすると180度になる
0度と180度を行き来する例 (間違い)
void setup() {
pinMode(10, OUTPUT);
}
void loop() {
digitalWrite(10, HIGH);
delayMicroseconds(500);
digitalWrite(10, LOW);
delayMicroseconds(20000 - 500);
delay(1000);
digitalWrite(10, HIGH);
delayMicroseconds(2400);
digitalWrite(10, LOW);
delayMicroseconds(20000 - 2400);
delay(1000);
}
- 最初このように書いてしまってちょっとはまった
- PWM は繰り返さないといけない
- この例だと単発パルスなのでサーボは正しく動いてくれない
- 最初の例が動いていたのはたまたま loop() が繰り返されているからだった
0度と180度を行き来する例 (正しい)
void setup() {
pinMode(10, OUTPUT);
}
void loop() {
for (int i = 0; i < 3000000/20000; i++) {
digitalWrite(10, HIGH);
delayMicroseconds(500);
digitalWrite(10, LOW);
delayMicroseconds(20000 - 500);
}
delay(1000);
for (int i = 0; i < 3000000/20000; i++) {
digitalWrite(10, HIGH);
delayMicroseconds(2400);
digitalWrite(10, LOW);
delayMicroseconds(20000 - 2400);
}
delay(1000);
}
- 連続パルスにすると目的の角度まで正しく移動する
- ただしどれだけ繰り返せばいいのかはよくわからない
- 上で例では仮に3秒(=3000000μs)とした
- 3秒は目的の角度まで移動するには十分だろうと考えて勝手に決めた値
- 本当は仕様にある60度あたり0.1秒で計算しないといけないのかも
- 実際やってみたら動かなかった
- 180度が0.3秒は速すぎるのでなにか勘違いしているかも
- あとからこのコードを見ても何をやってるかわからなそう
ライブラリを使う
#include <Servo.h>
Servo servo;
void setup() {
servo.attach(10);
}
void loop() {
servo.write(0);
delay(1000);
servo.write(180);
delay(1000);
}
- なんと角度を指定するだけでよくなった
- ここまで抽象化してくれるならメソッド名は angle とかにしといてほしかったが(小声)
- どれだけPWMを繰り返すかもうまく制御してくれているっぽい
サーボが使えると何ができる?
- SwitchBotのように物理的なスイッチが押せる
- タッチペンと連動すればスマホの物理的な操作を自動化してテストできる
Discussion