サーボモータの概要と制御原理
MG90Sのような標準的なサーボモータは、内部でモータ、ギアヘッド、フィードバック用ポテンショメータ、制御回路を統合したアクチュエータです。入力されたPWM信号に基づいて目標角度を維持する閉ループ制御を行います。一般的に、電源(VCC)、グランド(GND)、制御信号(PWM)の3本の配線で構成されます。
角度制御には周期20ms(50Hz)のPWM信号を使用します。パルス幅を変化させることで角度を指定し、標準的には0.5msで0度、2.5msで180度の回転範囲となります。
STM32CubeMXの設定
STM32のタイマーをPWM出力モードに設定し、サーボモータを駆動します。主な設定手順は以下の通りです。
- クロックソース: Internal Clockを選択します。
- チャンネル設定: 使用するタイマーチャンネルをPWM Generation modeに設定します。
- PWMパラメータの計算: サーボ制御に適した周波数と分解能を設定します。ここでは、タイマーのクロックを1MHz(1カウント=1μs)に設定する方法を推奨します。例えば、メインクロックが150MHzの場合、Prescaler (PSC) を149、Counter Period (ARR) を19999に設定します。これにより、PWM周期は20ms(20000μs)となり、パルス幅をマイクロ秒単位で直感的に指定できます。
ドライバコードの実装
可読性と移植性を高めるため、制御ロジックを関数化します。角度からPWMのパルス幅(マイクロ秒)への変換式を用いて、タイマーの比較レジスタ(CCR)値を更新します。
mg90s_driver.h
#ifndef MG90S_DRIVER_H
#define MG90S_DRIVER_H
#include "main.h"
// ユーザー設定:使用するタイマーハンドルとチャンネル
#define SERVO_TIMER_HANDLE htim1
#define SERVO_PWM_CHANNEL TIM_CHANNEL_1
extern TIM_HandleTypeDef SERVO_TIMER_HANDLE;
// 関数プロトタイプ
void MG90S_Init(uint16_t start_angle);
void MG90S_SetAngle(uint16_t angle);
void MG90S_DemoLoop(void);
#endif
mg90s_driver.c
#include "mg90s_driver.h"
// 0度~180度に対応するパルス幅(マイクロ秒)
#define PULSE_MIN_US 500 // 0度相当
#define PULSE_MAX_US 2500 // 180度相当
#define ANGLE_RANGE 180
/**
* @brief サーボモータの初期化
* @param start_angle 初期角度 (0-180)
*/
void MG90S_Init(uint16_t start_angle)
{
// PWM信号の出力開始
HAL_TIM_PWM_Start(&SERVO_TIMER_HANDLE, SERVO_PWM_CHANNEL);
// 初期位置へ移動
MG90S_SetAngle(start_angle);
}
/**
* @brief 指定角度へサーボを回転させる
* @param angle 目標角度 (0-180)
*/
void MG90S_SetAngle(uint16_t angle)
{
// 入力範囲の制限
if (angle > ANGLE_RANGE) angle = ANGLE_RANGE;
// 角度をパルス幅(μs)にマッピング
// 計算式: 最小幅 + (角度 * (最大幅 - 最小幅) / 最大角度)
uint32_t pulse_width = PULSE_MIN_US + ((uint32_t)angle * (PULSE_MAX_US - PULSE_MIN_US) / ANGLE_RANGE);
// CCRレジスタへ値を設定 (ARRが19999の場合、1単位で1μs)
__HAL_TIM_SET_COMPARE(&SERVO_TIMER_HANDLE, SERVO_PWM_CHANNEL, pulse_width);
}
/**
* @brief 動作確認用のデモ関数
*/
void MG90S_DemoLoop(void)
{
MG90S_SetAngle(0);
HAL_Delay(1000);
MG90S_SetAngle(90);
HAL_Delay(1000);
MG90S_SetAngle(180);
HAL_Delay(1000);
}
実装のポイントと注意点
タイマー設定の確認: 上記のコードは、タイマーのカウントクロックが1μs単位になるようにCubeMXで設定されている前提です。システムクロック周波数に合わせてPrescalerとCounter Periodを適切に調整してください。
電源供給: サーボモータは駆動時に大きな電流を消費する可能性があります。STM32の3.3V/5Vピンから直接電源を取るのではなく、外部電源を用意し、グランドをSTM32と共通にすることを推奨します。