ステッピング モータ | RCサーボモー タ | |
制御 | ワンパルス送る度に一定の角度だけ回転します。 例えば、今回のモータならワンパルス(1step)で1.25度回転です。 |
送るパルスのONさせる幅により回転角度が決まります。 |
回転 | 連続回転OK 今回のモータは288ステップで1回転なので、 864パルス送れば3回転して止まります。 また、パルスのONさせる幅を変えると回転速度が変わります。 |
0〜180度までの回転です。 (360度回転する物もあり) 回転速度は制御不可、モータに依存します。 |
精度 | 停止制度は低くモータに依存します。 例えば、今回のモータなら1.25度まいです。 |
停止制度は高い 内部にエンコーダが有るので常に停止位置をキープする(フィードバック制御)。 |
トルク | 低速域でのトルクが大きい、高回転になればトルクが小さく なり、そのうち回転しなくなる。 | 低速〜高速域でトルクが安定している。 |
回路 | FET等でドライバーを作る必要がある。 (マイコンへの配線は4本:2相時) |
簡単、部品不要 (マイコンへの配線は1本) |
価格 | 安い | 高い |
正転出力(白赤->赤黄->黄緑->白緑 の4step繰り返し)
逆転出力(白緑->黄緑->赤黄->白赤 の4step繰り返し)
--------------------------------------------------------------------- #include <xc.h> #define _XTAL_FREQ 8000000 // delay用に必要(クロック8MHzを指定) // コンフィギュレーション1の設定 #pragma config FOSC = INTOSC // 内部クロックを使用する(INTOSC) #pragma config WDTE = OFF // ウオッチドッグタイマー無し(OFF) #pragma config PWRTE = ON // 電源ONから64ms後にプログラムを開始する(ON) #pragma config MCLRE = OFF // 外部リセット信号は使用せずにデジタル入力(RA5)ピンとする(OFF) #pragma config CP = OFF // プログラムメモリーを保護しない(OFF) #pragma config CPD = OFF // データメモリーを保護しない(OFF) #pragma config BOREN = ON // 電源電圧降下常時監視機能ON(ON) #pragma config CLKOUTEN = OFF // CLKOUTピンをRA6ピンで使用する(OFF) #pragma config IESO = OFF // 外部・内部クロックの切替えでの起動はなし(OFF) #pragma config FCMEN = OFF // 外部クロック監視しない(FCMEN_OFF) // コンフィギュレーション2の設定 #pragma config WRT = OFF // Flashメモリーを保護しない(OFF) #pragma config PLLEN = OFF // 動作クロックを32MHzでは動作させない(OFF) #pragma config STVREN = ON // スタックがオーバフローやアンダーフローしたらリセットをする(ON) #pragma config BORV = HI // 電源電圧降下常時監視電圧(2.5V)設定(HI) #pragma config LVP = OFF // 低電圧プログラミング機能使用しない(OFF) // 指定した時間(num x o.1ms)だけウエイトを行う処理関数 void Wait(unsigned int num) { int i ; // numで指定した回数だけ繰り返す for (i=0 ; i<num ; i++) { __delay_us(100) ; // 100usプログラムの一時停止 } } // ステッピングモータにパルスを出力する処理関数 // step : 回転させるステップ数を指定する(負数値ならモータは逆回転する) // speed: モータの回転速度を指定する、ONさせるパルスの幅を0.1ms単位に指定 // パルスのONする幅を短くすると速度が上がります。 void StepperOut(int step,long speed) { unsigned char dt[4] = { 0b11000000 , 0b01100000 , 0b00110000 , 0b10010000 } ; int c , cnt ; cnt = 0 ; if (step >= 0) { c = 0 ; // 指定したステップの数だけ繰り返す、モータは正転する while(cnt < step) { LATB = (0b00001111 & LATB) | dt[c] ; cnt++ ; c++ ; if (c > 3) c = 0 ; Wait(speed) ; // パルスのONする出力幅(速度)を調整する } } else { step = step * -1 ; c = 3 ; // 指定したステップの数だけ繰り返す、モータは逆転する while(cnt < step) { LATB = (0b00001111 & LATB) | dt[c] ; cnt++ ; c-- ; if (c < 0) c = 3 ; Wait(speed) ; // パルスのONする出力幅(速度)を調整する } } } // メインの処理 void main() { OSCCON = 0b01110010 ; // 内部クロックは8MHzとする ANSELA = 0b00000000 ; // AN0-AN4は使用しない全てデジタルI/Oとする ANSELB = 0b00000000 ; // AN5-AN11は使用しない全てデジタルI/Oとする TRISA = 0b00000000 ; // ピン(RA)は全て出力に割当てる(RA5は入力のみとなる) TRISB = 0b00000000 ; // ピン(RB)は全て出力に割当てる PORTA = 0b00000000 ; // RA出力ピンの初期化(全てLOWにする) PORTB = 0b00000000 ; // RB出力ピンの初期化(全てLOWにする) Wait(30000) ; // 3秒後に開始 while(1) { StepperOut(4,100) ; // 4step回転させ、速度のパルス幅は10ms } } ---------------------------------------------------------------------CコンパイルとPIC書き込みを実行して下さい。
while(1) { StepperOut(4,100) ; // 4step回転させ、速度のパルス幅は10ms }の部分を
StepperOut(288,100) ; while(1) ;に書き換えて見て下さい
step1 step2 step3 step4 dt[4] = { 0b11000000 , 0b01100000 , 0b00110000 , 0b10010000 } ;また、step4〜step1と逆に順次繰り返して出力すればモータは逆回転します。
--------------------------------------------------------------------- #include <xc.h> #define _XTAL_FREQ 8000000 // delay用に必要(クロック8MHzを指定) int PreVal ; // 前回読み込んだ可変抵抗の値を保存する変数 // コンフィギュレーション1の設定 #pragma config FOSC = INTOSC // 内部クロックを使用する(INTOSC) #pragma config WDTE = OFF // ウオッチドッグタイマー無し(OFF) #pragma config PWRTE = ON // 電源ONから64ms後にプログラムを開始する(ON) #pragma config MCLRE = OFF // 外部リセット信号は使用せずにデジタル入力(RA5)ピンとする(OFF) #pragma config CP = OFF // プログラムメモリーを保護しない(OFF) #pragma config CPD = OFF // データメモリーを保護しない(OFF) #pragma config BOREN = ON // 電源電圧降下常時監視機能ON(ON) #pragma config CLKOUTEN = OFF // CLKOUTピンをRA6ピンで使用する(OFF) #pragma config IESO = OFF // 外部・内部クロックの切替えでの起動はなし(OFF) #pragma config FCMEN = OFF // 外部クロック監視しない(FCMEN_OFF) // コンフィギュレーション2の設定 #pragma config WRT = OFF // Flashメモリーを保護しない(OFF) #pragma config PLLEN = OFF // 動作クロックを32MHzでは動作させない(OFF) #pragma config STVREN = ON // スタックがオーバフローやアンダーフローしたらリセットをする(ON) #pragma config BORV = HI // 電源電圧降下常時監視電圧(2.5V)設定(HI) #pragma config LVP = OFF // 低電圧プログラミング機能使用しない(OFF) // 指定した時間(num x o.1ms)だけウエイトを行う処理関数 void Wait(unsigned int num) { int i ; // numで指定した回数だけ繰り返す for (i=0 ; i<num ; i++) { __delay_us(100) ; // 100usプログラムの一時停止 } } // アナログ値の変換と読込み処理 unsigned int adconv() { unsigned int temp; GO_nDONE = 1 ; // アナログ値読取り開始指示 while(GO_nDONE) ; // 読取り完了まで待つ temp = ADRESH ; // PICは読取った値をADRESHとADRESLのレジスターにセットする temp = ( temp << 8 ) | ADRESL ; return temp ; } // ステッピングモータにパルスを出力する処理関数 // step : 回転させるステップ数を指定する(負数値ならモータは逆回転する) // speed: モータの回転速度を指定する、ONさせるパルスの幅を0.1ms単位に指定 // パルスのONする幅を短くすると速度が上がります。 void StepperOut(int step,long speed) { unsigned char dt[4] = { 0b11000000 , 0b01100000 , 0b00110000 , 0b10010000 } ; int c , cnt ; cnt = 0 ; if (step >= 0) { c = 0 ; // 指定したステップの数だけ繰り返す、モータは正転する while(cnt < step) { LATB = (0b00001111 & LATB) | dt[c] ; cnt++ ; c++ ; if (c > 3) c = 0 ; Wait(speed) ; // パルスのONする出力幅(速度)を調整する } } else { step = step * -1 ; c = 3 ; // 指定したステップの数だけ繰り返す、モータは逆転する while(cnt < step) { LATB = (0b00001111 & LATB) | dt[c] ; cnt++ ; c-- ; if (c < 0) c = 3 ; Wait(speed) ; // パルスのONする出力幅(速度)を調整する } } } // メインの処理 void main() { int num , i ; OSCCON = 0b01110010 ; // 内部クロックは8MHzとする ANSELA = 0b00000100 ; // AN2のみアナログ使用、他のAN0,1,3,4は使用しないデジタルI/Oとする ANSELB = 0b00000000 ; // AN5-AN11は使用しない全てデジタルI/Oとする TRISA = 0b00000100 ; // RA2のみ入力、他のピン(RA)は出力に割当てる(RA5は入力のみとなる) TRISB = 0b00000000 ; // ピン(RB)は全て出力に割当てる PORTA = 0b00000000 ; // RA出力ピンの初期化(全てLOWにする) PORTB = 0b00000000 ; // RB出力ピンの初期化(全てLOWにする) // A/Dの設定 ADCON1 = 0b10010000 ; // 読取値は右寄せ、A/D変換クロックはFOSC/8、VDDをリファレンスとする ADCON0 = 0b00001001 ; // アナログ変換情報設定(AN2から読込む) __delay_us(5) ; // アナログ変換情報が設定されるまでとりあえず待つ PreVal = 0 ; // 前回値は0として初期化 Wait(30000) ; // 3秒後に開始 while(1) { // 1番ピン(AN2)から可変抵抗の値を30回読み込み平均化する num = 0 ; for (i=0 ; i < 30 ; i++) { num = num + adconv() ; } num = num / 30 ; // 可変抵抗からの値を今回値とする // ステッピングモータに出力する StepperOut(num - PreVal,100) ; // 今回値−前回値の値だけ回転させる PreVal = num ; // 今回値を前回値として保存する } } ---------------------------------------------------------------------
num = 0 ; for (i=0 ; i < 30 ; i++) { num = num + adconv() ; } num = num / 30 ; // 可変抵抗からの値を今回値とすると、半固定抵抗の値を30回読み込み平均化していますが、
num = adconv() ;どうでしょう?、だいぶんモータの回転がフルフルしていて操作しにくいと思います。
リンク切れ見直し(*4) 2017/01/12
追記(*3) 2016/09/27
MPLAB X用に記事変更(*2) 2015/10/27
追記(*1) 2014/06/22
【きむ茶工房ガレージハウス】
Copyright (C) 2006-2020 Shigehiro Kimura All Rights Reserved.