Arduinoでサーボモーター使ってみたい

スポンサーリンク
スポンサーリンク

サーボモーターSG90

回転を角度にできるやつ。使ってみたいので使い方調べる。

スポンサーリンク

お買い物

マイクロサーボ9g SG−90: パーツ一般 秋月電子通商-電子部品・ネット通販
電子部品,通販,販売,半導体,IC,マイコン,電子工作マイクロサーボ9g SG−90秋月電子通商 電子部品通信販売

秋月で売ってる。スタンダードなやつみたい。

ちっちゃい!

プレート?ガイド?なんていうのか分かんないけど付いてた。

スポンサーリンク

接続

直で繋いだ。大丈夫かな。

茶=GND、赤=電源[+]、橙=制御信号 [JRタイプ]

スポンサーリンク

スケッチ

0-90-180度の繰り返し

#include <Servo.h>

int pwmpin = 9;
Servo myservo;

void setup() {
  myservo.attach(pwmpin);
}

void loop() {

  myservo.write(0);
  delay(1000);
  myservo.write(90);
  delay(1000);
  myservo.write(180);
  delay(1000);

}

Servo.hをincludeするだけで使える。

0.1秒毎に0-180度に動かす

#include <Servo.h>

int pwmpin = 9;
Servo myservo;

void setup() {
  myservo.attach(pwmpin);
}

void loop() {

  for (int i = 0 ; i < 180 ; i++) {
    myservo.write(i);
    delay(100);
  }

}

こんなとか。

0.5秒ごとにランダム

#include <Servo.h>

int pwmpin = 9;
int deg = 0;
Servo myservo;

void setup() {
  myservo.attach(pwmpin);
  randomSeed(analogRead(0));
}

void loop() {

  deg = random(0, 180);
  myservo.write(deg);
  delay(500);
}

こんなんも。

 

気になることがあって、ピニオンギアとプレートの歯を合わせると、0度ないし180度の時に筐体と直交しないから見た目的に若干角度がついているように見える。なんかヤダな。まぁ安いしちっちゃいからそこは我慢か。

スポンサーリンク

なぜanalogWrite()だとちゃんと動かないのか

最初、analogWriteの説明にPWMって書いてあったので

int pwmpin = 9;
int deg = 0;
Servo myservo;

void setup() {

  pinMode(pwmpin, OUTPUT);
}

void loop() {

  analogWrite(pwmpin, 0);
  delay(1000);
  analogWrite(pwmpin, 127);
  delay(1000);
  analogWrite(pwmpin, 255);
  delay(1000);
}

ていうコードを書いた。analogWriteは0-255の範囲で値を書き込めるっていうから、0-127-255で0-90-180度になると考えたわけだ。でもこの考えは間違ってた。サーボ全然動かんし。

サーボモーターは電圧の変化で角度を変えているわけではない

秋月にあるSG90の資料を見てみると

電圧は4.8V(5V)で、20msの周期での、0.5-2.4msのデューティサイクルによって角度が決まる。PWMを電圧を低く見せるためではなくて(結果的に低くなっているように見えるけど)、パルス幅を使ってるだけってことみたい。PWM=電圧を変化させること、みたいな雑な理解だったから駄目なんだな。

analogWriteの周期とSG90の周期は違う

analogWriteの周波数は、こちらを見ると約490Hz(≒2.04msに1回)で、SG90は上記から50Hz(=20msに1回)なので、都合10倍ぐらい違う。analogWriteの方が短い。ていうかanalogWriteでこの制御信号を作ろうとしてはいけない。なのでdigitalWriteとdelayMicrosecondsを組み合わせて制御信号を作らないといけないみたい。

踏まえたスケッチ

int pwmpin = 9;

void setup() {

  pinMode(pwmpin, OUTPUT);

}

void loop() {

  pulse(0, 1000);
  pulse(90, 1000);
  pulse(180, 1000);

}

void pulse(int deg, int ms) {
  int d = 0;
  int startms = millis();
  int endms = startms + ms;

  d = map(deg, 0, 180, 500, 2400);

  do {
    digitalWrite(pwmpin, HIGH);
    delayMicroseconds(d);
    digitalWrite(pwmpin, LOW);
    delayMicroseconds(20000 - d);
  } while (endms < millis());

  delay(ms);

}

一応動く。

ただ1分ぐらいすると勝手に止まっちゃう。たぶんこれはintのせいなのかな?

スポンサーリンク

参考

Arduino - Servo
Open-source electronic prototyping platform enabling users to create interactive electronic objects.
Arduino 日本語リファレンス
その9 Arduinoでサーボモータをキュイキュイ動かす!
http://e-words.jp/w/Hz.html
スポンサーリンク
したい
スポンサーリンク
スポンサーリンク
スポンサーリンク
dalomo

コメント

タイトルとURLをコピーしました