サーボSG90を20度/秒ぐらいで滑らかに動かしたいと思ったのですが、どうも難しいです。割り箸をホットボンドで接着するといういかにも共振したりハンチング起こしそうな条件ではありますが。
試行錯誤としては、
- Arduino標準のServoライブラリのexample
- 同じく、値を変えるごとにdetachしてdelayし再度attach
- ESP32のLEDCを使って15bit PWM
- ESP32 / Arduino unoでdelayMicrosecondsを使って正確なパルスを出す
などを試みたのですが、いずれも動画のようなブルブルっぷりでした。強いて言えばLEDCを使ったものが一番良かったですが、やっぱり震えます。今回使ったのはSG90のパチ品です。本物あるいはもっと高価なサーボを使えば滑らかに動いてくれるのでしょうか?
うーむ。
一応LEDC版のソースです。delayは「次のPWMパルスが出そうなところでledcWrite命令を出すとパルス列がコケるのではないか?」ということで一つだけ出るようなタイミングにしてみたりPWM周期を変えてみたりしましたが特に大きな変動は見られません。
こっちはdelayMicroseconds版。
うーむ。
一応LEDC版のソースです。delayは「次のPWMパルスが出そうなところでledcWrite命令を出すとパルス列がコケるのではないか?」ということで一つだけ出るようなタイミングにしてみたりPWM周期を変えてみたりしましたが特に大きな変動は見られません。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#define servoPin 12 | |
#define servoCh 0 | |
#define servoBits 15 | |
#define servoMax 32767 | |
void degreeToLED(float inDegree) { | |
float msec = inDegree / 90.0 * 0.5 + 1.5; | |
int duty = msec / 20.0 * (float)servoMax; | |
Serial.println(duty); | |
ledcWrite(servoCh, duty); | |
} | |
float pos = 0; | |
void setup() { | |
Serial.begin(115200); | |
ledcSetup(servoCh, 50, servoBits); | |
ledcAttachPin(servoPin, servoCh); | |
} | |
void loop() { | |
for (pos = -90; pos <= 90; pos += 0.1) { // goes from 0 degrees to 180 degrees | |
// in steps of 1 degree | |
degreeToLED(pos); // tell servo to go to position in variable 'pos' | |
delay(15); | |
} | |
for (pos = 90; pos >= -90; pos -= 0.1) { // goes from 180 degrees to 0 degrees | |
degreeToLED(pos); // tell servo to go to position in variable 'pos' | |
delay(15); | |
} | |
} |
こっちはdelayMicroseconds版。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#define servoPin 12 | |
void setup() { | |
Serial.begin(115200); | |
pinMode(servoPin, OUTPUT); | |
} | |
void loop() { | |
for (float pos = -90; pos <= 90; pos += 0.1) { | |
float msec = pos / 90.0 * 0.5 + 1.5; | |
long limitUSec = msec * 1000; | |
digitalWrite(servoPin, HIGH); | |
delayMicroseconds(limitUSec); | |
digitalWrite(servoPin, LOW); | |
delayMicroseconds(10000-limitUSec); | |
delay(10); | |
} | |
delay(1000); | |
} |
0 件のコメント:
コメントを投稿
注: コメントを投稿できるのは、このブログのメンバーだけです。