步進馬達

      在〈步進馬達〉中尚無留言

用途

步進馬達可以控制比較精密的動作, 例如4相步進馬達, 可以把一圈360度分為2048 or 4096 個等分, 程式碼可以精密的控制馬達轉動等分.

步進馬達定位較精確, 可使用1000rpm以內的速度運轉, 適合動作頻繁與距離短的應用, 比如自動門的開啟. 步進馬達通常搭配控制晶片, 程式比較容易設計, 以下使用整合ULN2003晶片的控制模組, 可連接步進馬達的插座、指示燈號與連接到Raspberry Pi的針腳‧

至於伺服馬達, 也可精確的控制馬達定位角度, 反應速度比步進馬達快, 運轉的扭力也較大, 但轉向只能在0-180度之間, 通常適用於方向機之類的應用.

照片

28BYJ-48 會附有一個控制板, 控制板的編號為 ULN2003. 透過控制板就可以容易的控制步進馬達. 請注意, UL2003的電源可使用5V 及12V. 而本版本的右邊是+ 極, 左邊是 – 極.

小編曾參照網路上的接法, 將正反極接反而無法運轉, 還好沒有燒掉.

steppermoter_1

規格

28BYJ-48的規格如下

Rated voltage : 5VDC
Number of Phase : 4 相
Speed Variation Ratio : 1/64
Stride Angle : 5.625° /64
Frequency : 100Hz
DC resistance : 50Ω±7%(25℃)
Idle In-traction Frequency : > 600Hz
Idle Out-traction Frequency : > 1000Hz
In-traction Torque  >34.3mN.m(120Hz)
Self-positioning Torque >34.3mN.m
Friction torque : 600-1200 gf.cm
Pull in torque : 300 gf.cm
Insulated resistance >10MΩ(500V)
Insulated electricity power :600VAC/1mA/1s
Insulation grade :A
Rise in Temperature  <40K(120Hz)
Noise  <35dB(120Hz,No load,10cm)
Model : 28BYJ-48

28BYJ-48 是四相 5線的規格

運作方式

下圖為四相圖面, 所謂四相是指有四個定子, 也就是四組線圈. 而下圖的激磁方式為一次激發一組線圈, 稱為一相激磁.
1. 先激發北方的線圈, 把轉子的N極吸到北方.
2. 激發西方的線圈, 把轉子的N極及到西方.
3. 激發南方的線圈, 把轉子的N極及到南方.
4. 激發東方的線圈, 把轉子的N極及到東方.

此種方式電力消耗小, 缺點是振動大, 轉距小.

一相激磁

phars4_0

二相激磁

二相激磁是一次激發二組線圈, 如下圖. 此種方式振動小、轉距大

phars4_1

半相激磁

先激發北方, 再激發北/西, 然後西, 西/南, 南, 南/東, 東, 東/北

phars4_2

角度控制

上述不論是一相激磁, 二相激磁, 還是一/二相激磁(半相), 不是四個方向, 頂多也才八個方向而以. 那如何控制在精準的其他角度呢.

原來是每次送一個脈衝, 就改變一個基本步進角, 然後停住.

一相激磁, 二相激磁

先看一下官方原文的說法
There are 32 steps per revolution on my sample motor, and inside is a 1/64 reduction gear set. Gear reduction is actually : (32/9)/(22/11)x(26/9)x(31/10)=63.683950617, This means is that there are really 32*63.683950617 steps per revolution =  2037.88641975 ~ 2038 steps!

上述說明,  在一相激磁或二相激磁時, 轉子每轉一圈是32步(齒), 也就是每一次脈衝, 就會轉1齒, 需要32次脈衝才會轉一圈. 但裏面有一個減速齒輪組, 是1:64的比率. 也就是說轉子轉64圈, 輸出軸心才會轉一圈.
說的更白話一點, 也就是輸出軸心轉一圈, 轉子需轉64圈, 而轉子一圈為32步, 所以轉子64圈就是 64*32=2048步, 所以輸出軸心一圈就是 2048步.

由上換算出基本步進角為 : 360/2048=0.17578125°

半相激磁

半相激磁時, 轉子一圈是64步(齒), 再套上 1:64的減速齒輪組, 因此輸出軸心轉一圈是 64*64=4096步

由上算出基本步進角為 360/4096 = 0.087890625°.

ps. 但更精細的規格是, 減速齒輪組其實是 (32/9)/(22/11)/(26/9)/(31/10)=63.683950617, 也就是轉子跟傳輸軸比為 1:63.683950617, 所以傳輸軸的正確步數為 2038步及4075步

接線

stepper_wire

簡易程式

Pi4J提供GpioStepperMotorComponent 類別, 是控制步進馬達是最方便的作法。GpioStepperMotorComponent類別包裝在 pi4j-device.jar中, 所除了加入pi4j-core.jar外,也要加入pi4j-device.jar.

請注意, 經本人測試, 使用一相或二相激磁, 就是約2048步, 使用 一/二相激磁, 就是4096步. 

在半相之下, 使用setStepsPerRevolution(4096), motor.rotate(0.25)則會轉 1/4圈(90度), 但若設為 setStepsPerRevolution(2048), 則rotate(0.25)僅會轉 45 度.

setSetpInterval

Motor物件需設定 setStepInterval()方法, 也就是每走一步後, 要停留的時間, 本人測試, 只要低於 1.5ms, 就不會動, 甚至可能會燒掉. 其實設定停留時間是可以指定nano second的, 如下
motor.setStepInterval(1, 500000);

另外 setStepInterval() 是相當不精準的. 一來這是使用C語言 delay的方式來延遲, 本身就受執行緒條件限制, 所以很不精準. 二來是馬達每走一步也要時間, 但行進的時間並未算入, 所以千萬別用這個裝置來製作時鐘.

底下程式, 會讓步進馬達正向轉二圈, 然後再反向轉二圈

package steppermotor;
import com.pi4j.component.motor.impl.GpioStepperMotorComponent;
import com.pi4j.io.gpio.GpioController;
import com.pi4j.io.gpio.GpioFactory;
import com.pi4j.io.gpio.GpioPinDigitalOutput;
import com.pi4j.io.gpio.PinState;
import com.pi4j.io.gpio.RaspiPin;
public class StepperMotor {
    //一相激磁
    public static final byte[] SINGLE_STEP = { 
        (byte) 0b0001, 
        (byte) 0b0010, 
        (byte) 0b0100, 
        (byte) 0b1000 };
    //二相激磁
    public static final byte[] DOUBLE_STEP = { 
        (byte) 0b0011, 
        (byte) 0b0110, 
        (byte) 0b1100, 
        (byte) 0b1001 };
    //半相激磁
    public static final byte[] HALF_STEP = { 
        (byte) 0b0001, 
        (byte) 0b0011,
        (byte) 0b0010,
        (byte) 0b0110, 
        (byte) 0b0100,
        (byte) 0b1100, 
        (byte) 0b1000,  
        (byte) 0b1001 };
     // 4-Step sequence: 32 * 63.68395 = 2037.8864 (2038)
    public static final int STEPS_PER_REV = 2038;
     public static void main(String[] args) {
        System.out.println("StepperMotorDemo01 Start...");
         final GpioController gpio = GpioFactory.getInstance();
         // 建立控制步進馬達的GPIO輸出物件
        final GpioPinDigitalOutput[] pins = {
                gpio.provisionDigitalOutputPin(RaspiPin.GPIO_02, PinState.LOW),
                gpio.provisionDigitalOutputPin(RaspiPin.GPIO_03, PinState.LOW),
                gpio.provisionDigitalOutputPin(RaspiPin.GPIO_04, PinState.LOW),
                gpio.provisionDigitalOutputPin(RaspiPin.GPIO_05, PinState.LOW)};
         // 結束時把輸出針腳設定為低電壓
        gpio.setShutdownOptions(true, PinState.LOW, pins);
         // 建立步進馬達物件
        GpioStepperMotorComponent motor = 
                new GpioStepperMotorComponent(pins);
         // 設定每一步的間隔時間
        motor.setStepInterval(2);
        // 設定運作模式
        motor.setStepSequence(SINGLE_STEP);
        motor.setStepsPerRevolution(STEPS_PER_REV);
        while(true){ 
            // 正向轉一圈
            motor.rotate(1);
            delay(50);
            // 反向轉一圈
            motor.rotate(-1);
            delay(50);
        }
    }
     private static double angleToRev(int angle) {
        return angle / 360.0;
    }
    private static void delay(int ms) {
        try {Thread.sleep(ms);}
        catch (InterruptedException e) {}
    }
}

精準控制

指定角度

底下是在4096半相激磁時, 每次進1度的用法
motor.rotate(-1/360.0);
try {Thread.sleep(300);} catch (InterruptedException ex) {}

指定步數

底下是在4096半相激磁時, 每次進1步的用法
motor.step(-1);
try {Thread.sleep(300);} catch (InterruptedException ex) {}

另外還有 motor.forward(), motor.reverse();

自動門程式

底下程式, 使用超音波測距模組, 偵測若有人接近, 就啟動步進馬達開啟自動門. 若人離開, 就關閉自動門

下面程式碼有個特性, 假設開門跟關門, 輸出軸心要轉1.5圈才會全開跟全關.  所以在一開始的1.0圈要快速開啟, 但後面剩於的0.5圈為了防止撞擊力道太大, 又分為二部份, 前面0.25圈開始減速, 最後0.25圈速度更底.

那程式碼就可以寫成如下

        motor.setStepInterval(2);
        motor.rotate(-1.0);
        motor.setStepInterval(3);
        motor.rotate(-0.25);
        motor.setStepInterval(5);
        motor.rotate(-0.25);                
        motor.setStepInterval(2);
        motor.rotate(1.0);
        motor.setStepInterval(3);
        motor.rotate(0.25);
        motor.setStepInterval(5);
        motor.rotate(0.25); 

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *