USBでPCと接続するハイパワーステッピングモーター

今回は、いままでになくまっとうな電気回路工作っぽいです.ハイパワーなステッピングモーターをドライブする回路を作ります.PCからコマンドを打つと、 それに従ってステッピングモーターが回転するというシステムです.フライス盤をNC制御に改造したいなぁと思って買った大型のステッピングモータです.

注意:
末尾に書きましたように、この製作記事は、失敗すると基板やモーターが燃えることがあります.
わたしも燃やしました!!!
ズブズブの素人の方がトライするにはリスクが伴いますので、覚悟の上でやってください.
火事になってもわたしは知りません.
USB系統に誤って12Vを与えてしまいPCがオシャカになってもわたしは知りません.


ありふれたドライバ回路の考察
ステッピングモータとそのドライバ回路がどんなものかというと、下の写真のような小さなステッピングモータであれば、下図のような常時通電型のドライバ回路でOKです.OKとはどういう意味かというと、ドライバトランジスタが焼け焦げはしないという意味です.ステッピングモータの回路が焼けるの?と思うでしょうが、ステッピングモーターの種類によりますが、運が悪いと確実に焼け焦げます
下記のステッピングモータと下記のドライバ回路の組み合わせだとどうして幸運にもトランジスタが焼け焦げないのか?
カギはステッピングモータにあります.下記は秋月電子で売られているステッピングモータの一種ですが、その主要スペックはこうなっています.
サイズ:43x43x34mm
コイル抵抗:34Ω/相
入力定格電圧:12V
定格電流:0.33A/相
意外に思われるかもしれませんが、下図のドライバ回路 が最大電力を消費するのは、停止状態のときです.なぜかというと、静止トルクを発生させるために静止状態でも通電するからです.ステッピングモータの動作 原理について詳しい解説は割愛させていただきますが、たとえ静止状態でも最低どれか1つのコイルには、12Vの電圧が加わったままになります.すると、コ イル抵抗が34Ωですから、12V/34Ω=350mAの電流がダダモレ的に流れ続けます.12Vx350mA=4.2Wの電力を消費します.この 4.2Wのほぼ全部がステッピングモータの熱になりますので、静止状態のステッピングモーターは熱燗ぐらいの熱を持つことになるでしょう.一部はトランジ スタの熱にもなります.トランジスタのON抵抗が0.5Ωあると仮定すると、トランジスタは350mAx350mAx0.5Ω=61mWの発熱をします. この程度の発熱ならトランジスタは全然問題ないです.
発熱するとはいえども、熱燗程度の熱で済んだので、運が良くて焼け焦げずに済んだわけです.つまり、焼け焦げずに済んだ理由は、ステッピングモータの直流抵抗が34Ωもあったからなんです.


では、今回の製作に使うステッピングモータはどんなスペックなのでしょうか?
秋月で買ったステッピングモータで、正しいスペックは不明なんですが、似た製品から類推すると、次のようなスペックだと推測します.
サイズ:56x56x75mm
200ステップ
コイル抵抗:1Ω/相
コイルインダクタンス:2mH   (推測)
入力定格電圧:24V
定格電流:3A/相以上

さて、このステッピングモーターに、上図のドライバ回路で通電すると何が起きるでしょうか?
12V をコイルに通電しますと、コイル抵抗+トランジスタのオン抵抗=1.5Ωしかないので、電流は8A流れます.するとモータの発熱は8Ax8Ax1Ω= 64Wという途方もない値になります.すぐにスイッチを切らないとモーターがアッチンチンになって焼損してしまいます.トランジスタの発熱はというと、オ ン抵抗が0.5Ωあるとすると、8Ax8Ax0.5Ω=32Wとなります.いくら放熱器を付けていたとしても32Wもの発熱は焼け石に水で、トランジスタ が焼け焦げてしまいます.


わたしの体験では、トランジスタが焼けるというよりも、トランジスタをハンダづけしたハンダが溶けて流れ出しまして、いったい何が起きたのかと ビックリしちゃいました.その他には、ステッピングモータを焼損したりもました.その分解写真を末尾に書きましたのでご覧ください.

教訓: ハイパワーステッピングモータには、単純な通電制御をしてはいけません.コイルの巻き線抵抗が小さすぎるからです.


ハイパワーステッピングモータのドライバ回路はどういう制御をするべきか?

要請は、あまりにも大きな電流が流れないように制限したい、ということです.

電流制限したいわけですから、定電流駆動すればよいです.定電流駆動型のステッピングモータドライバ回路は、市販のモータドライバユニットで実用化されて います.しかし、手作りで実現するには、定電流駆動回路はいろいろとめんどくさいです.コイルのような誘導負荷を定電流駆動するのは、コイルがそんな簡単 に電流を流さしてくれないデバイスなので、駆動電圧を高くしなくちゃいけないとか、スルーレートを制限しなくちゃいけないとか、とにかくいろいろと大変な ことになります.多額な開発費をかけた市販の回路ならまだしも、ホビーでやれる回路の範囲ではかなり難易度が高いと思われます.

なので、ここでは定電流駆動はあきらめます.

定電流駆動をあきらめた先には、どういう選択肢があるのでしょうか?  それは、チョッパ制御です.

12Vをコイルに加えっぱなしにするのではなく、下図のように、ON/OFFすれば平均電流は小さくなるというのがチョッパ制御のあらましです.下図で は、duty比が半分なのでおおよそ半分になると思えばだいたい合ってます.チョッパ制御なら簡単に電流制限できそうです.

ステッピングモータの静止状態ではブレーキトルクを与えるだけで済むので、下図のようにdutyが痩せた12Vを与えれば、ブレーキトルクを与えるぐらいの役にはたちます.消費電力も抑えられるので、問題解決できそうです.


さて、次の疑問です.チョッパ制御しようと決めたものの、チョッパ周波数はいくつにしたらいいでしょうか?

それは、モータ巻き線コイルのインダクタンスを根拠として以下のような理屈で決めます.

上でコイルインダクタンス=2mHと推測しました.それを前提として計算します.
コイルは、電流変化で電圧を発生させる性質があります.それを、次の式で表します.
e = L di / dt
eは電圧で、ここでは12Vです. Lはインダクタンスで、ここでは2mHです. di/dtは電流変化です.式を変形して、
e dt / L = di
e t / L = i
と変形した式に、値を代入すると、
12V t / 2.2mH = i
i = 5454 t
を得ます.この式は、通電時間が長くなると、電流もそれに比例して大きくなるという意味を表しています.

チョッパ周波数の候補を、1MHz,100kHz,10kHz,1kHzのどれかにするとします.強力にドライブしている状態を想定してduty90%のときの通電時間とピーク電流は下表のように計算されます.ステッピングモータの定格電流が3Aなので、
下表から、最適値は10kHz〜1kHzのあいだのどこかにありそうだという推定も同時にできます.ひとまず、10kHzでチョッパすることに結論づけます.
チョッパ周波数
duty90%の通電時間
ピーク電流
感想
1MHz
0.9uSec
4.9mA
小さすぎてトルク不足
100kHz
9uSec
49mA
小さすぎてトルク不足
10kHz
90uSec
490mA
ちょっと少ないくらい
1kHz
900uSec
4900mA
大きすぎて熱くなりそうで心配

つまり、下図のように10kHzでduty90%で12Vの電圧をモーターに加えると、

コイル電流は下図のように10kHzの三角波になり、ピークで490mAの電流が流れると上表は言っています.

もしも、5kHzでduty90%の12Vの電圧をモーターに加えると、コイル電流は下図のように5kHzの三角波で、ピークが約1Aの電流が流れると計算されます.
このように、コイル電流はdutyだけで決まるわけではなく、チョッパ周波数にも依存するんです.


モーターのスペックが24Vなのに、12Vで駆動しておかしなことになりはしないか?と心配なさる方もいらっしゃるでしょう. これは、やってみて問題な ければOKという考え方でいいです.12V電源は入手容易なので、できれば12Vで済ませたいところです.やってみたところ、とりあえず回転させるだけで あれば12Vでも問題ありませんでした.モーターのトルクを最大限に引き出したいのなら24V電源を用意すればいいでしょう.


ステッピングモータドライバ回路
以上の机上計算を元に、ドライバ回路を書きますと下図のようになります. (pdfはこちら)

●回路図の右側にある4つのコイルがステッピングモータのコイルです.4つのコイルをX+,Y+,X-,Y-と名づけると、下表の3種類の駆動方法があり ます.表のマスが”1”になっているところがコイルに通電しています.このように、コイルを順番にオンしてゆけばステッピングモータは回転するわけです. --------ちなみに今回の製作例は簡単な1相駆動にしました.

1相駆動
2相駆動
1−2相駆動


X+Y+X-Y-
11000
20100
30010
40001


X+Y+X-Y-
11100
20110
30011
41001


X+ Y+ X- Y-
11000
21100
30100
40110
50010
60011
70001
81001
ステップ角1.8度
1.8度
0.9度
消費電力比 

1.5
特徴

高トルク
高角度精度
●コイルの両端についているダイオードは、コイルに蓄積したエネルギーをオフ時に速やかに放電させる役割があります. 600V1A程度以上の整流用ダイオードならなんでもOKです.ここに60V150mA程度の小信号ダイオードをつけると、チカッと発光してすぐに燃え尽 きてしまいますので、小信号ダイオードは使用不可能です.わたしは1N4007(1000V1A)を使いました.
2SK2936でスイッチングしています.データシートによると、2SK2936は最大45Aまで流せますので、数A程度で使おうとしているこの回路には十分な性能です.
● インバータの4049は電源電圧12Vで動かします.FETのゲート電圧となる12Vのパルスを作るためです.2SK2936のゲートON電圧は4Vとス ペックに書いてありますので、7408が出力する5Vのパルスで直接2SK2936のゲートを駆動できるはずですが、念のためにきちんと12Vのパルスを 作ってから2SK2936のゲートを駆動しました.
●7408は5Vで動作します.4049は12Vで動作します.なので、10KΩと5600Ωで4049との電圧変換をしています.
●7408は、チョッパするためのアンドゲートです.
各アンドゲートの入力は、STM8Sの出力ポートから来る単純なパルス(下図の上)と、STM8Sのタイマ出力ポートから来る10kHzです.すると7408の出力は10kHzでチョッパされた波形(下図の下)になります.

遅い回転数では、下図のようにパルス周波数が低くなります.しかしチョッパ周波数は10kHzで不変です.

トルクを増したいときには、下図のようにdutyを太らせて駆動します.
チョッパ制御のステッピングモータドライバなら、回転数とトルクを両方制御できる
というわけです.



回路の写真
ドライバ回路の全体像はこうなります.汚い配線ですがお許しを.
PCとのUSB接続はこのウェブページでおなじみの、シリアル-USB変換基板(秋月電子)を使います.

2SK2936には放熱器をつけてありますが、あまり発熱しません.
左からGDS
下はステッピングモーターの接続状態の写真です.


PCとの接続のシステムブロック図


ステッピングモータコマンド
機能はシンプルです.terminal softから指令します.
●f 20 100  と打つと、100Hzの速さで20ステップ正回転して止まります.
●r 200 600  と打つと、600Hzの速さで200ステップ逆回転して止まります
●行頭でenterを打つと、前回のコマンドを実行します.



ハードウエアの製作

@CPUの回路図
STM8S CPUの結線は下図のようにします.USBシリアル変換基板、リセットSW、ステッピングモータドライバ基板を接続します.

AUSBシリアル変換回路
UARTをUSBに変換する回路を、STM8S-DISCOVERYにどうやって取り付けるか?
秋月のUSBシリアル変換基板をSTM8S-DISCOVERYに取り付けます.
回路図は下記です.配線は上記回路図の4本です.
●STM8SのPD5とPD6には、UARTの送信信号と受信信号が出てきますので、それをUSBシリアル基板に配線しています.
STM8S-DISCOVERYでは、電源はFLASH焼き回路から5V or 3.3Vが供給されますが、これを切断し、USBシリアル変換基板から5Vが供給されるようにします.このウェブページの他の回路は全て3.3V電源でSTM8Sを動かしてきましたが、ここでは5Vで動かします.理由はロジックレベルを5V→12Vに変換したいからです.
そのために、ジャンパーをつぎの1)2)のように設定 してください.
  1) USBシリアル変換基板のジャンパーピンは、下図の赤色の位置にします.
  2) STM8S-DISCOVERYのJP1のジャンパーピンは、外しておきます.

USBシリアル変換基板の取付完了状態はこのようになります.
右の黄色の囲いがUSBシリアル変換回路です.同基板に刺さっているMini-USBがPCのUSBへ行きます.
中央の水色の囲いがSTM8Sマイコンです.USBシリアル変換回路と配線されています.
左の赤い囲いは、ブロック図には描きませんでしたがSTM8Sを焼くために必須な回路です.同基板に刺さっているUSBケーブルは、STM8Sを焼くためのケーブルです.やはりPCに接続します.
この回路は、PCのUSBポートを都合2ヶ占有することになります.

プログラムを焼いてしまえば、焼き用のUSBケーブルは不要になるわけで、下図のようにUSBを外してしまいたくなるのが人情です.
ところが、USBケーブルを外しただけでは、STM8Sにリセットがかかってしまって動かなくなってしまいます.
そこで、下の写真の丸の中にあるSB1とSB2をハンダごてでOPENにしてやればリセット線が切断されるので、STM8Sが動きます.
この方法は憶えておきましょう.

BリセットSW
これはプッシュSWを適当につけてください.

プルアップ抵抗は不要で、対GNDへ落とす形式でOKです.

Cステッピングモータドライバ基板
下記の回路図になります.
 (pdfはこちら)
この回路図を見てチャチャッと作れない人には、この製作記事は難しいと思います.
R1は、リセット時にモーターに12Vが加わるのを防止するpull-down抵抗です.回路図には書き忘れましたが10kΩでいいでしょう.

DOPTION BYTEの設定
この製作記事では、PD4には常時10kHzのチョッパ制御信号が出ているはすです.
もし出なかった場合のトラブルシュートです.
チョッパ制御に使うSTM8Sのポート PD4は、BEEPとタイマ2とでピンを共有しています.もしもBEEP機能に設定されていると、チョッパ信号が出ず、この回路は動きません.-----それどころかどこかが焼ける恐れがある-----
BEEPとタイマ2の機能選択は、OPTION BYTEで選択します.OPTION BYTEの設定変更方法についてはこちらのページをご覧ください.
見るべき所は下図のPort D4 Alternate Function = TIM2_CH1 っていうところです.ここが BEEP になっているとダメなんです.



ソースコードの解説

サンプルプログラムをこちらに置きます

今回は、ソースコードサイズが小さめなので、STVDをこの設定でbuildしました.
Global Variables = in Zero Page
Program model = STM8 Small model


main.c

#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "stm8s.h"
#include "usrlib-uart.h"
インクルードです.上3つはCの標準関数.stm8s.hはSTMicro社のライブラリを使うため.uselib-uart.hはPCと通信するための関数.

// clock configrations
#define CK_Hz            16000000  // cpu clk
#define INT_Hz           10000     // interrupt freq. 10kHz=0.1ms
#define CHOPPER_Hz  10000     // CHOPPER 10kHz
#define TIM3_ARR         ((float)CK_Hz/(float)INT_Hz)
#define TIM2_ARR         ((float)CK_Hz/(float)CHOPPER_Hz)
今回は外部水晶発振子の16MHzを使います.
16MHzをクロックとして、タイマ2で10kHzのチョッパ周波数を発生させます.
タイマ3で10kHzの割り込みをかけます.
TIM2_ARRとTIM3_ARRは、10kHzでタイマをぐるっと一周させるためのカウント数で、1600になるはずです.

// prototypes
void UART_Menu(void);
void menu_display(void);
あとで出てくるので説明は割愛します.

// groval variables
char UARTstrTX[80];
PCへ文字列を送信するためのバッファ.

void main(void){
メインルーチンはじまり.

CLK_ClockSwitchConfig ( CLK_SWITCHMODE_AUTO, CLK_SOURCE_HSE, DISABLE, CLK_CURRENTCLOCKSTATE_DISABLE );
クロックを外部水晶発振子の16MHz(HSEモード)にします.
プリスケーラの設定は、HSEモードではタイマもCPUも16MHzそのままになります.

GPIO_Init(GPIOB, 0b10101010, GPIO_MODE_OUT_PP_LOW_FAST);  // motor output PB1,PB3,PB5,PB7
モータを回すためのパルスを出力する4つのポートをPB1,PB3,PB5,PB7に設定しています.

GPIO_Init(GPIOD, GPIO_PIN_0, GPIO_MODE_OUT_PP_HIGH_FAST); // LED indicator
LED indicatorをチカチカさせます.モータのX+相コイルの通電に同期して光らせます.

    // 10kHz CHOPPER source
    TIM2_DeInit();
    TIM2_TimeBaseInit( TIM2_PRESCALER_1, (u16)TIM2_ARR-1);  // 16MHz/TIM2_ARR=10kHz
    TIM2_OC1Init(TIM2_OCMODE_PWM1, TIM2_OUTPUTSTATE_ENABLE, (u16)(TIM2_ARR/2), TIM2_OCPOLARITY_HIGH); // output D4
    TIM2_Cmd(ENABLE);
この設定で、タイマ2に10kHzをハードウエア的に発生させます.パルスdutyは別途動的に設定します.

  // 10kHz motor pulse interrupt
  TIM3_DeInit();
  TIM3_TimeBaseInit( TIM3_PRESCALER_1, (u16)(TIM3_ARR-1) );
  TIM3_ITConfig(TIM3_IT_UPDATE, ENABLE);
  TIM3_Cmd(ENABLE);
モーターを駆動するパルス(10kHzとは違う)を発生させるためのソフトウエアタイマを駆動するための10kHz割り込みをタイマ3で発生させます.

    // UART2
    UART2_DeInit();
  UART2_Init((u32)115200, UART2_WORDLENGTH_9D, UART2_STOPBITS_1, UART2_PARITY_ODD, UART2_SYNCMODE_CLOCK_DISABLE, UART2_MODE_TXRX_ENABLE);
  UART2_ITConfig(UART2_IT_RXNE_OR, ENABLE);
    UART2_Cmd(ENABLE);
UARTでPCと通信するための設定です.PCのterminalsoftでは、115200、8bit、odd parity、stop1bit の設定にします.

enableInterrupts();
割り込み許可

menu_display();
メニューをterminalsoftに表示させます.

while(1) { UART_Menu(); } // Main loop
}
UART経由でPCと通信するルーチンを呼び出す無限ループでメインルーチンの仕事はおしまいです.


//*************************************************
//    MOTOR routine
//*************************************************
モーター制御で使うグローバル変数の定義です.
float CHOPPER_DUTY_ON=0;        // chopper duty (on)
チョッパ10kHzのdutyを変えることで、モーターのトルクを変えます.

float CHOPPER_DUTY_BRAKE=0;    // chopper duty (brake)

チョッパ10kHzのdutyを変えることで、モーターのトルクを変えますが、これはブレーキ時のトルクです.

float duty;                            // chopper duty
チョッパ10kHzのdutyです.

char     DIRECTION='f';        // rotation forward/reverse
回転方向、fならforward、rならreverseです.

u16     STEP_MAX=10;          // motor step number
モーターを何ステップ回転させるか?

u16     HZ=10;                      // motor step speed Hz
ステップ周波数

int     CNT_MAX=1000;          // 1000 means that 10kHz/1000=10Hz of motor step speed
所望のステップ周波数を発生させるための、ソフトウエアカウンタの最大カウント数.
1000だと、10kHz/1000=10Hzとなり、10Hzでステップさせます.

u8      MOTOR_START_REQ=0;// start motor rotation
PCからモーターコマンドが来ると1になります

u8      MOTOR_BUSY=0;       // busy flag
モーター回転中は1

u8      MOTOR_CMPL=0;       // motor complete
モーター回転が終わった時に一瞬だけ1になります

u16     int_cnt;                   // count up by 10kHz
所望のステップ周波数を発生させるための、ソフトウエアカウンタ

u16     step_cnt;                 // pulse number counter
モーターを何ステップ回転させたか?

char     MTR[5]="1000";         // motor drive pattern

モーターコイルの通電パターン

// motor coil drive pattern
// MTR[0:3]={xp,yp,xm,ym}
void next_pattern(void)
{
         if(strcmp(MTR,"1000")==0) strcpy(MTR,"0100");
    else if(strcmp(MTR,"0100")==0) strcpy(MTR,"0010");
    else if(strcmp(MTR,"0010")==0) strcpy(MTR,"0001");
    else                           strcpy(MTR,"1000");
    return;
}
この関数が呼び出されるたびに、モーターコイルの駆動パターンが回転的に変化します.
このルーチンは1相駆動ですが、このルーチンを変えると2相駆動とか、1−2相駆動に変更できます.

// 10kHz interrupted
void Tim3Update(void) interrupt 15
{
10kHz割り込みでここへ飛んできます.

    u8 bit_pat,xp,xm,yp,ym;
    int_cnt++;  // interrupt counter
10kHzカウンタのカウントアップ

    // motor pattern changed
    if(int_cnt>=(CNT_MAX-1))
    {
        int_cnt=0;
int_cnt==CNT_MAXになったら、モーターの駆動パターンを変更すべき時がやってきました.

        if(MOTOR_START_REQ==1){ // starting
            @next_pattern();
            Aduty=CHOPPER_DUTY_ON;
            Bstep_cnt=1;
            CMOTOR_BUSY=1;
            DMOTOR_START_REQ=0;
        }
モータースタートが要求されていたら、@モーターパターンを先にするめる.Adutyを設定する.Bstepをカウントアップ.Cビジー.Dフラグクリア.

        else if(step_cnt==0); // braking
step==0ならブレーキ中なのでなにもしない

        else if(step_cnt<STEP_MAX){ // rotating
            next_pattern();
            step_cnt++;
        }
stepがMAXに達しないときは回転中であるから、パターンを先に進める.stepをカウントアップ.

        else if(step_cnt==STEP_MAX){ // braking
            @duty=CHOPPER_DUTY_BRAKE;
            AMOTOR_BUSY=0;
            BMOTOR_CMPL=1;
            Cstep_cnt=0;
        }
stepがMAXに達したら、@dutyをブレーキに必要な弱いdutyに変更する.A非ビジー.BCMPLフラグを立てる.Cstep=0

        // motor coil output
        xp = (MTR[0]=='1') ? 1 : 0; // --> PB1
        yp = (MTR[1]=='1') ? 1 : 0; // --> PB5
        xm = (MTR[2]=='1') ? 1 : 0; // --> PB3
        ym = (MTR[3]=='1') ? 1 : 0; // --> PB7
        if(DIRECTION=='f')      bit_pat = (ym<<7) + (yp<<5) + (xm<<3) + (xp<<1);
        else if(DIRECTION=='r') bit_pat = (xp<<7) + (xm<<5) + (yp<<3) + (ym<<1);
ここで、モーターコイルの駆動パターンを作ります.

        GPIO_Write(GPIOB,bit_pat);  // output to CN3-3579 pin
ポートに出力します.

        // change chopper duty
        TIM2_OC1Init(TIM2_OCMODE_PWM1, TIM2_OUTPUTSTATE_ENABLE, (u16)(TIM2_ARR*duty), TIM2_OCPOLARITY_HIGH); // output D4
ここで、チョッパ10kHzのdutyをタイマ2に設定します.

        if(MOTOR_BUSY){

            if(DIRECTION=='f')sprintf(UARTstrTX,"forward ");
            else              sprintf(UARTstrTX,"reverse ");
            SerialPutString(UARTstrTX);
            sprintf(UARTstrTX,"step=%3d %3dHz duty=%g\r\n",step_cnt,HZ,duty);
            SerialPutString(UARTstrTX);
        }
回転ごとにPCにステータスを送信します.

        // LED indicator
        if(xp) GPIO_WriteLow(GPIOD,GPIO_PIN_0);
        else  GPIO_WriteHigh(GPIOD,GPIO_PIN_0);
    }
LEDを点滅させます.

    TIM3_ClearFlag(TIM3_FLAG_UPDATE);
    return;
}
タイマ3の割り込みフラグをクリアします.


//*************************************************
//    UART MENU routine
//*************************************************
PCとコマンドをやりとりするルーチンです.

int chk(float a, float from, float to){if(a<from || a>to)return(1); else return(0);}
コマンドパラメータの値をチェックするサブルーチン

void UART_Menu(void)
{
    if(MOTOR_BUSY==1) return;
メニュー処理ルーチンです.モーターがビジーの時にはすぐにreturnします.

    if(UART_STR_EXIST==1)
    {
        int fieldnumber;
        SerialPutString("\r\n");
        UART_STR_EXIST = 0;
UART_STR_EXISTは、コマンドを1行受け取ったら1になります.

        fieldnumber = separate_line(command);
コマンド行を、スペースで区切って単語にブツ切りにします.

        if(Field[0][0]=='f' && fieldnumber==3){
            @if(chk(atof(Field[1]),1,2000))goto NG; // step 1-2000
            Aif(chk(atof(Field[2]),1,2000))goto NG; // freq 1-2000
            BDIRECTION='f';
            CSTEP_MAX=(int)atof(Field[1]);
            DHZ=(int)atof(Field[2]);
        }
コマンドfなら、@第1パラメータが1〜2000であることをチェック.
A第2パラメータが1〜2000であることをチェック.
B方向変数=f   
CSTEP_MAXを第1パラメータにセット.
DHZを第2パラメータにセット.

        else if(Field[0][0]=='r' && fieldnumber==3){
            if(chk(atof(Field[1]),1,2000))goto NG;
            if(chk(atof(Field[2]),1,2000))goto NG;
            DIRECTION='r';
            STEP_MAX=(int)atof(Field[1]);
            HZ=(int)atof(Field[2]);
        }
コマンドrの処理.

        else if(fieldnumber==0) goto CAL;

単にenterが押されただけなら、前回のコマンドを実行します.

        else goto NG;
それ以外はNGを表示します.

    CAL:
コマンドパラメータを、内部変数に変換します.

        CHOPPER_DUTY_BRAKE=0.1;  // 0.43A
ブレーキ時のduty=0.1に設定します.実測で0.43Aが流れます.
ブレーキトルクを増やしたいなら、値を大きくすればOKです.

        CNT_MAX = (int)((float)INT_Hz/(float)HZ);
コマンドが要求する周波数を、10kHz割り込みカウント数に変換します.

        if(HZ<10)       CHOPPER_DUTY_ON=0.2;  // 1.1A
        else if(HZ<50)  CHOPPER_DUTY_ON=0.2;  // 1.1A
        else if(HZ<100) CHOPPER_DUTY_ON=0.25; // 1.6A
        else if(HZ<200) CHOPPER_DUTY_ON=0.3;  // 1.8A
        else if(HZ<300) CHOPPER_DUTY_ON=0.3;  // 1.8A
        else if(HZ<400) CHOPPER_DUTY_ON=0.4;  // 2.5A
        else if(HZ<500) CHOPPER_DUTY_ON=0.5;  // 3.0A
        else            CHOPPER_DUTY_ON=0.5;  // 3.0A
回転速度により、トルクを変えています.トルクを変えるためにdutyを変えています.
dutyを変えると流れる電流が増えるのでトルクが変わります.
速い速度で回転させるためには、より高いトルクが必要なようです.

        sprintf(UARTstrTX,
                        "direction=%c step=%d %dHz CHOPPER(ON)=%g CHOPPER(BRK)=%g %d\r\n",
                        DIRECTION,STEP_MAX,HZ,CHOPPER_DUTY_ON,CHOPPER_DUTY_BRAKE,CNT_MAX);
        SerialPutString(UARTstrTX);
コマンドパラメータと内部パラメータを表示します.

        MOTOR_START_REQ=1;
コマンドの解析が済んだので、モーターを回転させる要求フラグを立てます.

        goto RET;
正常終了.

    NG:
        SerialPutString("COMMAND NG!\r\n");
        goto RET;
    }
異常コマンド終了.

RET:
    if(MOTOR_CMPL){ menu_display(); MOTOR_CMPL=0; }
    return;
}
メニューを表示させて、リターンします.


void menu_display(void){
    // Display Menu on HyperTerminal Window
    SerialPutString("\r\nf 100 80 ---> forward 100 steps at 80 Hz\r\n");
    SerialPutString("r 150 30 ---> reverse 150 steps at 30 Hz\r\n");
}
メニュー表示ルーチンです.



焼損したステッピングモータの分解と修理

コイルに12Vを通電したまま放置したら、ステッピングモータがアッチンチンになってしまい、動かなくなってしまいました.

分解してみました.ところ、やはり焼損していましたので、分解して修理しました.

ステッピングモータ上面の4本のネジを外すと、上フタが外れます.

コイルとローターがむき出しになります.ローターは外すことができます.とりあえず焼損箇所は見当たりません.

ローター単品はこのようになっています.ずいぶん立派なボールベアリングが装備されています.

下面のフタを外してみたら、プリント基板が焼損していました.2本が完全に切れています.

もったいないので、線でつなぎなおして、組み立てたら治りました.以上で修理はおしまいです.

このように、この製作は燃える危険がありますので、回路技術についてズブズブの素人の方には難しいと思います.
リスクを覚悟の上で取り組んでください.

inserted by FC2 system