Java Embedded (10)GPIO進階應用 – 步進馬達 by Michael | CodeData
top

Java Embedded (10)GPIO進階應用 – 步進馬達

分享:

Java Embedded (9)紅外線測距模組與類比數位轉換 << 前情

10-1 認識步進馬達

Raspberry Pi的GPIO有非常多不同的應用,例如前面已經討論過的LED控制,讀取按鈕與紅外線模組的資訊。應用程式經由GPIO與外界實體的零件與設備互動,現在有很多類似自動掃地機的裝置,它們可以經由馬達驅動,由程式控制裝置的行動路線,配合超音波測距模組,還可以自動避開障礙物。其它像是機器手臂或是一台具備手跟腳的機器人,這類裝置都需要馬達驅動,這一篇介紹可以讓裝置活動的應用,在應用程式控制步進馬達的運作。這個實作需要這些零件與設備:

  • 步進馬達一個、28YBJ-48、四相五線
  • 步進馬達控制模組、ULN2003
  • 杜邦線(母-母)、六條

各種電動控制的應用,需要搭配不同的馬達,大致有下列幾種:

  • 一般馬達:在一般的玩具裡面常用的馬達,通電以後就會開始運轉,關閉電源以後就停止運轉,不能執行比較精密的動作。
  • 步進馬達:可以控制比較精密的動作,例如4相步進馬達,可以把一圈360度分為500個等分,程式碼可以精密的控制馬達轉動等分。
  • 伺服馬達:可以精確的控制馬達定位角度,反應速度比步進馬達快,運轉的力量也較大,不過運作停止的定位沒有步進馬達那麼準確與快速。

步進馬達適合使用在很多常見的裝置,這是一般步進馬達的外觀,它的規格是四相五線:

JavaEmbedded_10_01

步進馬達的定位比較精確,可以使用1000rpm以內的速度運轉,適合動作頻繁與距離較短的應用。步進馬達通常會搭配控制晶片,應用程式比較容易設計,市面上可以找到整合ULN2003晶片的控制模組,提供連接步進馬達的插座、指示燈號與連接到Raspberry Pi的針腳。這是步進馬達與ULN2003控制模組的外觀:

JavaEmbedded_10_02

以四相的步進馬達來說,馬達裡面有四個控制方向的磁鐵,應用程式透過連接的線路,控制四個磁鐵的正、負極,讓步進馬達依照要的方向與速度運轉:

JavaEmbedded_10_03

10-2 連接步進馬達控制模組

認識步進馬達基本的概念後,搭配使用ULN2003晶片的控制模組,對Raspberry Pi來說會簡單很多。你必須選擇四個GPIO輸出針腳,連接到控制模組後,用來控制步進馬達的運轉。控制模組電源的部份需要5V與接地。依照下面的線路圖連接所有的零件:

JavaEmbedded_10_04

10-3 撰寫應用程式控制步進馬達

現在可以撰寫控制步進馬達的應用程式,Pi4J在「com.pi4j.component.motor.impl」套件,提供「GpioStepperMotorComponent」類別,使用它控制步進馬達是最方便的作法。GpioStepperMotorComponent類別包裝在「pi4j-device.jar」,所以這個應用程式除了主要的pi4j-core.jar外,也要記得加入pi4j-device.jar。參考下列的程式碼,完成控制步進馬達的應用程式:

package steppermotordemo01;

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 StepperMotorDemo01 {
    // 28BYJ-48、四相步進馬達
    // 單步、4 steps
    public static final byte[] SINGLE_STEP = { 
        (byte) 0b0001, 
        (byte) 0b0010, 
        (byte) 0b0100, 
        (byte) 0b1000 };

    // 雙步、4 steps
    public static final byte[] DOUBLE_STEP = { 
        (byte) 0b0011, 
        (byte) 0b0110, 
        (byte) 0b1100, 
        (byte) 0b1001 };

    // 半步、8 steps
    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...");

        // 建立GPIO控制物件
        final GpioController gpio = GpioFactory.getInstance();

        // 建立控制步進馬達的GPIO輸出物件
        final GpioPinDigitalOutput[] pins = {
                gpio.provisionDigitalOutputPin(RaspiPin.GPIO_00, PinState.LOW),
                gpio.provisionDigitalOutputPin(RaspiPin.GPIO_01, PinState.LOW),
                gpio.provisionDigitalOutputPin(RaspiPin.GPIO_02, PinState.LOW),
                gpio.provisionDigitalOutputPin(RaspiPin.GPIO_03, 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);

        // 正向轉一圈
        motor.rotate(1);
        delay(500);

        // 反向轉一圈
        motor.rotate(-1);
        delay(500);

        gpio.shutdown();
        System.out.println("StepperMotorDemo01 End...");
        System.exit(0);
    }

    private static double angleToRev(int angle) {
        return angle / 360.0;
    }

    /**
     * 暫停指定的時間(毫秒、1000分之一秒)
     * 
     * @param ms
     */    
    private static void delay(int ms) {
        try {
            Thread.sleep(ms);
        }
        catch (InterruptedException e) {
            System.out.println(e.toString());
        }
    }        

}

10-4 步進馬達進階控制

因為步進馬達與ULN2003控制模組是很常見的搭配與應用,所以Pi4J提供步進馬達的包裝類別「GpioStepperMotorComponent」,應用程式直接使用它來控制步進馬達是最方便的作法。這是GpioStepperMotorComponent類別提供的建構式,使用參數指定的GPIO輸出針腳物件陣列,建立步進馬達控制物件:

public GpioStepperMotorComponent(GpioPinDigitalOutput pins[])

建立好步進馬達控制物件以後,根據使用的步進馬達,使用下列方法執行正確的設定:

  • setStepsPerRevolution(int steps):設定步進馬達一圈的數量。28YBJ-48步進馬達的齒輪比是63.68395,採用四步的運轉方式,執行32 * 63.68395算出2037.8864,整數為2038。
  • setStepInterval(long milliseconds):設定每一步的間隔時間,控制運轉的速度,時間單位可以設定到微秒。
  • setStepInterval(long milliseconds, int nanoseconds):設定每一步的間隔時間,控制運轉的速度,時間單位可以設定到奈秒。
  • setStepSequence(byte[] sequence):設定步進馬達的運轉方式。

建立好步進馬達控制物件以後,使用下列的方法控制步進馬達的運轉:

  • forward():正向運轉。
  • reverse():反向運轉。
  • forward(long milleseconds):正向運轉指定的時間後停止。
  • reverse(long milleseconds):反向運轉指定的時間後停止。
  • stop():停止運轉。
  • step(long steps):運轉指定的數量。
  • rotate(double revolutions):運轉指定的圈數,1為一圈,0.5為半圈。正數與負數為正向與反向運轉。

之前說明的範例程式,把控制步進馬達運轉的部份,改為下列的程式碼片段,程式執行以後,可以讓步進馬達一次運轉四分之一圈:

motor.rotate(0.25);
delay(500);
motor.rotate(0.25);
delay(500);
motor.rotate(0.25);
delay(500);
motor.rotate(0.25);
delay(500);

示範影片:

在控制步進馬達的時候,要特別注意使用方法的特性。forward、reverse與step在呼叫以後,應用程式會繼續往後執行,所以它們通常使用在步進馬達運轉的時候,應用程式還有其它的工作需要同時執行。呼叫forward(long milleseconds)、reverse(long milleseconds)、rotate(double revolutions)方法,執行完成後才會繼續後面的流程。

課程相關的檔案都可以GitHub瀏覽與下載。

http://github.com/macdidi5/JavaEmbedded

後續 >> Java Embedded (11)控制直流馬達 – 使用L293D晶片

分享:
按讚!加入 CodeData Facebook 粉絲群

相關文章

留言

留言請先。還沒帳號註冊也可以使用FacebookGoogle+登錄留言

netsbig312/09

老師您好,很感謝老師提供的範例,我在實作時採用了和範例相同的步進馬達(28YBJ-48)和步進馬達控制模組(ULN2003),不過我所採用的樹莓派是Raspberry Pi 2 Model B(40 pin GPIO)。將檔案上傳到樹莓派並執行後,步進馬達無法順利轉動,出現了類似失步的現象(馬達有噪音及震動、確不回轉)。想請問老師這個錯誤該如何來修正?

熱門論壇文章

熱門技術文章