STM32 HALを用いたMG90Sサーボモータ(180度)の制御手法

サーボモータの概要と制御原理

MG90Sのような標準的なサーボモータは、内部でモータ、ギアヘッド、フィードバック用ポテンショメータ、制御回路を統合したアクチュエータです。入力されたPWM信号に基づいて目標角度を維持する閉ループ制御を行います。一般的に、電源(VCC)、グランド(GND)、制御信号(PWM)の3本の配線で構成されます。

角度制御には周期20ms(50Hz)のPWM信号を使用します。パルス幅を変化させることで角度を指定し、標準的には0.5msで0度、2.5msで180度の回転範囲となります。

STM32CubeMXの設定

STM32のタイマーをPWM出力モードに設定し、サーボモータを駆動します。主な設定手順は以下の通りです。

  1. クロックソース: Internal Clockを選択します。
  2. チャンネル設定: 使用するタイマーチャンネルをPWM Generation modeに設定します。
  3. 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と共通にすることを推奨します。

タグ: STM32 HAL サーボモータ MG90S PWM制御

6月12日 18:24 投稿