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

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

サーボモーターSG90

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

スポンサーリンク

お買い物

マイクロサーボ9g SG-90: 制御部品・駆動部品 秋月電子通商-電子部品・ネット通販
電子部品,通販,販売,半導体,IC,LED,マイコン,電子工作マイクロサーボ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のせいなのかな?

スポンサーリンク

参考

https://www.arduino.cc/en/Reference/Servo
Arduino日本語リファレンス
その9 Arduinoでサーボモータをキュイキュイ動かす!
Hzとは - IT用語辞典
Hz【ヘルツ】とは、周期的な現象の頻度を表す単位で、1秒あたりの生起回数(毎秒何回起きるか)を示したもの。1Hzは毎秒1回を意味し、周波数や振動数の単位として用いられる。国際単位系(SI)に定められた単位で、19世紀に電磁波の研究をしていた...

コメント

  1. 齊藤 朝秀 より:

    ATTiny202でサーボを動かそうと思っていました。Servoライブラリを使ってしまうとコンパイル後のサイズが2メガを超えてしまい、困っていました。本サイトを拝見して2メガを超えないものが作れました。
    とても助かりました。ありがとうございます。

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