ESP32でのSG90の使い方の説明です。SG90のマニュアルは秋月さんのHPに有りました=>SG90。これによると基本性能は
制御方法は
- 赤と茶色の線に電源を供給し、オレンジの線に信号を送る。
- 信号は幅20ms(50Hz)でHighの時間で角度が決まる
- 0.5ms: -90度
- 1.45ms: 0度
- 2.4ms: 90度
3.3Vから駆動する様ですがパルスHigh電圧が4.8から5Vなら供給電圧は5Vとなるのでしょうか。角度をPWMのパルス幅に換算するのは面倒と思っていたらESP32用のライブラリーが有りました。DwonloadしてArduinoのライブラリーに登録すれば使用出来ます。主な関数は以下の通り。
- int attach(pin ): モーター制御に使用するGPIOピンの定義。
- すべてのGPIOピンが使用出来ると有りますが2,4,12-19,21-23,25-27,32-33の使用を推奨。
- 戻り値
- 正常終了: 指定したピン番号
- 異常終了: 0
- int attach(pin, min, max ): 最大と最小のパルス幅と共にモーター制御に使用するGPIOピンの定義。
- パルスの幅を指定出来る以外はattach(pin )と一緒
- プログラムを見るとデフォルトの最小パルス幅は500us。最大は2500us。SG90に合わせている様です。
- SG90以外のパルス幅の違うモーターを使用する時にこの関数を使うのでしょうか。
- void write (): 回転角度指定(引数として0から180度を指定)
- void writeMicroseconds(): 回転角度指定(引数としてパルス幅を指定)
- int read():1つ前に指定した角度を0から180度の角度で返す。
- int readMicroseconds():1つ前に指定した角度をパルス幅で返す。
- bool attached(): ピン指定されていれば真。
- void detach(): 制御用に使用しているピンを開放する。
動作確認
動作確認の為下記の回路を作製。
- 5V電源をSG90とESP32に供給。
- 信号用にGPIO33を使用。
使用したプログラムは、
sg90.ino
#include "Arduino.h"
#include <ESP32Servo.h>
// Pin definition for Servo Motor
#define sg90_pin 33
void setup()
{
Servo sg90;
int a;
Serial.begin(115200);
sg90.attach(sg90_pin);
Serial.print("Attached PIN: ");
if(sg90.attached()) Serial.println("GPIO33");
else Serial.println("None");
for(a = 90; a > -1; a -= 10){
sg90.write(a);
Serial.println(String(a) + " / " + String(sg90.read()));
delay(1000);
}
for(a = 90; a < 181; a += 10){
sg90.write(a);
Serial.println(String(a) + " / " + String(sg90.readMicroseconds()));
delay(1000);
}
sg90.detach();
Serial.println("Detach GPIO32");
}
void loop()
{
delay(500);
}
- 12行: Servoクラスのインスタンス sg90を宣言
- 14行: GPIO33を信号に設定
- 16行: 設定されたか確認
- 20行: 回転角を角度で指定。
- 21行: 指定した角度と実際に指定された角度を表示
- 26行: 指定した角度と実際に指定された角度(us)の表示
- 30行: 使用ピンの開放
実行結果(シリアルモニタ)
serial monitor
ets Jun 8 2016 00:22:57
rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0030,len:1344
load:0x40078000,len:13964
load:0x40080400,len:3600
entry 0x400805f0
Attached PIN: GPIO33
90 / 89
80 / 79
70 / 68
60 / 58
50 / 49
40 / 38
30 / 28
20 / 19
10 / 9
0 / -1
90 / 1464
100 / 1562
110 / 1660
120 / 1777
130 / 1875
140 / 1972
150 / 2089
160 / 2187
170 / 2285
180 / 2382
Detach GPIO32
- 11行: GPIO33が使用されている事を確認
- 12から21行:回転角90度から0度に向けて10度毎に回転。
- 最初がプログラムで指定した角度。/の後は実際の回転角(read()関数の戻り値)
- 指定値とRead()の値は若干違う。(Read()の値の方が小さい)
- 22から31行:回転角を角度で指定。実際の角度をusで表示(readMicroseconds()の戻り値)
- 90度が1500us。180度が2500us。という訳では無いようです。
- 30行: GPIOのピンを開放して終了。
気付いた事
- 指定した値と関数で確認した値(Read()等の戻り値)に若干のずれがある。
- これは角度で指定した場合もパルス幅で指定した場合も同じ。
- 回転速度の調整は出来ない。
- 回転速度が若干速い。もう少し遅くしたい。
- コマンドはESP32からモーターに送られるがモーター側に状態をESP32から確認出来ない。
- 今回のプログラムで、モーター側の電源を切ってもシリアルモニタに同じ結果を表示する。
- 今回使用した回路でGPIOの出力はHigh:3.3Vのはずだが問題無く動作した。
- 総合的に非常に良いライブラリーと思います。