google-site-verification: google3bd66dd162ef54c7.html
fc2ブログ

DVDのスピンドルモーターを低速回転させる-続編

◆まえがき
以前DVDのスピンドルモーターを低速回転させましたが、回転速度に少しムラがあるのが気になっていました。

セルシンを作った時も回転ムラの問題があったのですが、この時のモーターは3相(3ポール)のコイルに対して磁石は1対。つまり1回転の中で磁気的にロックされるポジションは1つしか無いので、まあ仕方ないかなという感じでした。

一方で、このDVDのモーターは1回転で磁気的にロックされる位置が6箇所あります。つまり、もっと滑らかに回転出来るはずなのに、目に見えるような回転ムラが発生するが残念でした。

回転ムラを減らすには、マスダンパーを付けるなどのメカニカルな対策が考えられますが、電気的な駆動条件の調節で対策出来ればそれに越したことはありません。

そんなことで、駆動力と回転速度を運転中に変更出来るようにして、その効果を確認してみました。

◆回路図
回路図
VR1とVR2でモーター電流と回転速度を運転中に変更出来るようにしました。

モーター電源は最大1.5Aくらい流れるので別ルートから供給しています。回路図に示していませんが、Arduino NANOの電源はUSB電源など別系統から供給する必要があります。パワーを上げないならモーター電源をNANOの+5Vから取る手もありますが、その場合はボードの電流供給能力に注意する必要があります。
・外観
ブレッドボード

◆プログラム
Arduino UNO/NANOで使うことを想定したスケッチです。
// DVDスピンドルモーターの3相アナログ駆動テスト
// 可変抵抗で駆動パワー、回転速度を指定可能にした
// 20230427_3PhaseMotorDrive

int ax;          // モーターの角度

void setup() {
  pinMode(8, OUTPUT);          // 動作速度測定用
  pinMode(7, INPUT_PULLUP);    // 回転方向設定(HIGH or LOW)
  Serial.begin(115200);
  ax = 0;                      // 角度設定変数(0-360度で指定)
  angle(ax);                   // ホームポジションに移動 
  delay(1000);
}

void loop() {
  if (digitalRead(7) == HIGH) {  // 回転方向スイッチがOFFなら
    ax ++;                       // CW
    if (ax > 360) {
      ax = 0;
    }
  } else {                       // OFFなら
    ax --;                       // CCW
    if (ax < 0) {
      ax = 360;
    }
  }
  angle(ax);                     // 指定角度に回転
}

void angle(int a) {                     // 指定された位相でコイルを駆動.位相は度の値で指定
  int r, s, t;
  float pow_r, pow_s, pow_t;
  float magPow;
  int  rotInt;                          // インターバル

  magPow = 120.0 * analogRead(A0) / 1024.0;             // 磁界の強さ設定 (130us)
  rotInt = 500 * (1.0 - analogRead(A1) / 1024.0) - 30;  // 回転速度決定、値は0.1usステップ、-30はオフセット補正(130us)
  if (rotInt < 0) {                                     // 負の値になった時の後始末
    rotInt = 0;
  }

  pow_r = cos(PI * a / 180.0);          // 位相に相当するパワーを設定(175us)
  pow_s = cos(PI * (a + 120 ) / 180.0); // 位相 +120度            (175us)
  pow_t = cos(PI * (a - 120 ) / 180.0); // 位相 -120度            (175us)
  r = (pow_r * magPow) + 125;           // 振幅125±magPowでスイング(255近傍は怪しいので避ける)
  s = (pow_s * magPow) + 125;
  t = (pow_t * magPow) + 125;
  analogWrite( 9, r);                   // アナログ(PWM)出力
  analogWrite(10, s);
  analogWrite(11, t);
  delay100us(rotInt);                   // 指定時間待機して回転速度を調整
  Serial.print(magPow); Serial.print(", "); Serial.print(rotInt); Serial.print(", ");
  Serial.print(r); Serial.print(", "); Serial.print(s); Serial.print(", "); Serial.println(t);
}

void delay100us(int t) {           // 引数*100μs 待機
  // delayMicroseconds は16383us以上の値が設定出来ないのでこの関数を使う
  for (int i = 0; i < t; i++) {    // 指定回数
    delayMicroseconds(100);        // 100us待機
  }
}
PWMで三相のパワーを調整してモーターを駆動するようになっています。

37, 38行目のAnalogReadで可変抵抗の値を読み、励磁パワーと回転速度を設定しています。

回転速度は1回転当たり4.7秒から1分45秒の範囲で変更可能になっています。

angle( ) の関数内でモーターのコイルの励磁条件を設定しており、コメント内に書き込んである(130us)などの数字はその行の実行時間です。cosの値を計算するのに175us掛かっているのがこの関数の実行時間の足を引っ張っています。ここをテーブル参照方式などに変更すれば、処理時間を短く出来て最高回転速度をもっと上げることが出来るはずです。

◆動作テスト
全体
ターンテーブルに載せる物を変えたりしてテスト。

パワーを調節することで、(目で見る限りは)回転ムラを感じない駆動条件に設定することが出来ました。なお、パワーを下げ過ぎるとスリップして回転停止。パワーを必要以上に上げると回転ムラが発生し、またモーターが加熱します。

・動画(ツイッター)
回転数を調整している様子です。

◆HDDのスピンドルモーターを回す
面白いので、同じ回路を使って壊れたHDDのスピンドルモーターを回してみました。コイルはY結線になっていてピンは4本出ているので、中点以外の3ピンに接続します。(中点はピン間の抵抗を測定すれば判ります)

HDDのスピンドル

HDD
流軸のスピンドルを低速で廻したのでは本来の性能は出ませんが、それでもそのあたりに転がっている軸受けよりは精度が高いと思います。

◆まとめ
駆動パワーを調整することで回転ムラを目立たなくすることが出来ました。作品をデモする時などにあれば便利かも知れません。

こういうエレメカ物は対策の効果が目で見て判るので、いじっていて楽しいですね。

Arduinoを使ってDVDのスピンドルモーターを高速回転

◆まえがき
Arduinoを使ってモーターを回す実験のたぶん最終回になると思います。前回はDVDのスピンドルモーターを低速回転させましたが、今回は思いっきり高速で回転させてみます。

◆回路図
ずっと同じ回路なのですが、再度掲載しておきます。
回路図
NANOをUSB電源で動かす場合は、VINに繋がっている線を外します。
同時にモーターの2つのコイルに通電しているので、2Aくらいの容量の電源が必要になります。

◆外観
DVDのスピンドルモーターをArduinoで廻す

◆プログラム
ちょっと長いですが、見える形で掲載しておきます。
// 誘導モーターの実験(外側回転子)20230106_DVDmotorHighSpeedDriveCharange
// 三相矩形波駆動。6ポジション励磁, 1回転=36パルス
// 2023/1/6 ラジオペンチ http://radiopench.blog96.fc2.com/

#define PERIOD_MIN  42.0      // 最速周期(x10usの値) 42=0.42ms、1回転36パルスなので60/(0.42ms*36)=3968rpm
#define PERIOD_MAX  1000.0    // 開始時周期(x10usの値)
#define ACC_RATE    0.998     // 加速レート(1パルス毎の周期の変化率)

float periodF;
int   period;

void setup() {
  Serial.begin(115200);
  pinMode( 9, OUTPUT);  // R相
  pinMode(10, OUTPUT);  // S
  pinMode(11, OUTPUT);  // T
  pinMode(13, OUTPUT);
}

void loop() {
  periodF = PERIOD_MAX;

  for (int n = 0; n < 50 * 36; n++) {   // 正転加速
    stepDrive(1, period);
    acc();
  }
  digitalWrite(13, HIGH);               // 最高速運転中表示ON
  for (int n = 0; n < 150 * 36; n++) {  // 高速運転
    stepDrive(1, period);
  }
  digitalWrite(13, LOW);                // 最高速運転中表示OFF

  for (int n = 0; n < 44 * 36; n++) {   // 減速
    stepDrive(1, period);
    deAcc();
  }

  stepDrive(0, period);        // モーター電源OFFして待機
  delay(1000);

  periodF = PERIOD_MAX;
  for (int n = 0; n < 50 * 36; n++) {   // 逆転加速
    stepDrive(-1, period);
    acc();
  }
  digitalWrite(13, HIGH);               // 定速運転中表示
  for (int n = 0; n < 150 * 36; n++) {  // 高速運転
    stepDrive(-1, period);
  }
  digitalWrite(13, LOW);                // 定速運転中表示

  for (int n = 0; n < 44 * 36; n++) {   // 減速
    stepDrive(-1, period);
    deAcc();
  }
  stepDrive(0, period);      // モーター電源OFFして待機
  delay(1000);
}

void acc() {                       // 加速
  if (periodF > PERIOD_MIN) {
    periodF = periodF * ACC_RATE;  // パルス間隔を短縮
    period = periodF;              // タイマー設定用に整数化
  }
}

void deAcc() {                     // 減速
  if (periodF < PERIOD_MAX) {
    periodF = periodF / ACC_RATE;  // パルス間隔を延長
    period = periodF;
  }
}

void stepDrive(int mode, int t) { // mode 1=CW, 0=OFF, -1=CCW、t=待機時間(10usステップ)
  static long phaseN = 1;         // 位相カウンタ
  if (mode != 0) {                // 停止指示で無く、
    if (mode > 0) {               // CW指定なら、
      phaseN++;                   // 位相を一つ進め
      if (phaseN == 7) {          // 1回転していたら、
        phaseN = 1;               // 先頭に戻す
      }
    } else if (mode < 0)  {       // CCW指定なら、      
      phaseN--;                   // 位相を一つ戻し
      if (phaseN == 0) {          // 1回転していたら、
        phaseN = 6;               // 先頭に戻す
      }
    }
    switch (phaseN) {                 // 位相番号に合わせコイルを励磁
      case 1:
        PORTB |= _BV(1);              // HIGH D9
        PORTB &= (~_BV(2) & ~_BV(3)); // LOW  D10, D11
        break;
      case 2:
        PORTB |= (_BV(1) | _BV(2));   // HIGH D9, D10
        PORTB &= ~_BV(3);             // LOW  D11
        break;
      case 3:
        PORTB |= _BV(2) ;             // HIGH D10
        PORTB &= (~_BV(1) & ~_BV(3)); // LOW  D9, D11
        break;
      case 4:
        PORTB |= (_BV(2) | _BV(3)) ;  // HIGH D10, D11
        PORTB &= ~_BV(1);             // LOW  D9
        break;
      case 5:
        PORTB |= _BV(3) ;             // HIGH D11
        PORTB &= (~_BV(1) & ~_BV(2)); // LOW  D9, D10
        break;
      case 6:
        PORTB |= (_BV(1) | _BV(3)) ;  // HIGH D9, D11
        PORTB &= ~_BV(2);             // LOW  D10
        break;
    }
    for (int n = 0; n < t; n++) {     // 10μ刻みの時間待つ
      delayMicroseconds(10);          // 実際には4μ刻みの値になるが気にしないことにする
    }
  }
  else {                              // 停止指示なら
    PORTB &= (~_BV(1) & ~_BV(2) & ~_BV(3)); // コイル励磁OFF(全ピンLow)
//    Serial.println("Moter pow OFF");
  }
}
出来るだけスイッチング速度を上げたいので digitalWriteは使わずPORTBレジスタを直接操作しています。

いきなり最大速度で廻すことは出来ないので、定率で加速/減速するようになっています。丁寧にやるならS字カーブで制御した方が良いのですが、そこまで手が回りません。

発熱量を出来るだけ減らすため、停止時にはコイルの励磁を切っていますが、これによりホールディングトルクが無くなっています。ホールドしたい場合はモーター電源OFFの行をコメントアウトします。なお、こんな小技では無く、低速時はコイルの通電角を狭くして消費電流を減らす制御を行った良いのですがそこまで出来ませんでした。

◆動いている様子
オシロに表示しているのはコイルへの通電指定パルスです。(停止時OFF機能は切っています)

◆まとめ
DVDのスピンドルモーターを最高で約4000rpmで廻すことが出来ました。PM同期モーターとして動いているのでパルスモーターと同じで、ぴったりと同じ角度で停止させることが出来ます。パルスモーターは(たぶん)こんな高速では回らないと思います。

DVDのスピンドルモーターをいろいろいじってきました。本来はホールセンサーを使ったDCブラシレスモーターなのですが、ホールセンサーを使わないでマイコンからコイルの通電を制御する、つまりオープン制御で動かしても結構まともに動くことが判りました。ちょっとしたメカを動かすのに便利だと思います。

もちろんホールセンサーを使ってローターの位置を把握した制御を行った方が効率は良くなりますが、急に難易度が高くなるので簡単ではありません。

Arduinoを使ってDVDのスピンドルモーターを低速回転

◆まえがき
モーターいじりの話の続きです。おもちゃなどによく使われている3極のブラシモーターで出来ることは前回の記事でやりつくした感があるので、今度はブラシレスモーターをいじってみたいと思います。素材はDVDのドライブを分解した時に回収しておいたスピンドルモーターです。

◆DVDのスピンドル用のブラシレスモーター
DVDのスピンドルモーター
これはたぶん8倍速くらいまで書けるドライブのスピンドルモーターだったと思いますが、アウターローターのホールセンサー付きのモーターです。ちなみに、標準速だけのドライブのモーターは普通のブラシモーターが使われていることが多いので今回の実験には使えません。

ローターが外せないので詳しく調べることが出来ないのですが、中心のコイルは9極(スロット)で外側のローターの磁石はたぶん12極?6極?

写真のようにコイルから線を引き出して外部から通電出来るようにします。因みにコネクタにはコイル以外にホール素子などの接続ピンも出ているのピン数が多くなっていますが、コイルへの接続ピンはパターンが太目になっているので見て判りました。

◆駆動回路
前の記事の回路と同じなので省略します。

◆ソフト
前の記事の物とほとんど同じですが、2回転させるためのパルス数が6倍になっています。
20221230_3PhaseSteppingMotor.ino (UTF-8, BOM付き)

励磁パワー(MAG_POW)の値は負荷に合わせて調整した方が良いかも知れません。

◆動いている様子
ツイッターにも書いてますが、静かに回転するので、イベントなどで全周から見てもらいたい展示物を置くと良さそうです。ちなみに、消費電流は0.25Aだったので普通のUSB電源で動きます。

◆まとめ
以前模型のモーターで同じことをやった時は、目で見てはっきり判る回転ムラがあったのですが、このモーターはスムーズに回ります。固定子が9スロットと多く、ローターの磁石の極数も多そうなので回転ムラが少ないのでしょう。これだったらアナログのアクチェーターとして使えるかも知れません。それに軸の精度が高いので使い易そうです。

ただ、このモーターは1回転の中で磁気的にロックされる角度が6か所あります。アブソリュートな角度が必要な場合は、初期化の時に何らかの工夫が必要になります。
カレンダー
05 | 2023/06 | 07
- - - - 1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 -
プロフィール

ラジオペンチ

Author:ラジオペンチ
電子工作を中心としたブログです。たまに近所(東京都稲城市)の話題など。60過ぎて視力や器用さの衰えを感じつつ日々挑戦!
コメントを入れる時にメールアドレスの記入は不要です。なお、非公開コメントは受け付けていません。
記事の内容のご利用は読者の自己責任でお願いします。

記事が気に入ったらクリックを!
最新記事
カテゴリ
最新コメント
リンク
FC2カウンター
検索フォーム
月別アーカイブ
RSSリンクの表示
QRコード
QRコード