Arduino 入門程序示例之步進電機(2015-06-28)


概述

演示單極步進電機的控制。沒有現成的 H 橋模塊,雙極步進電機就不做實驗啦。

這里沒有使用 stepper 庫,用 IO 粗糙地原始地驅動,以加深對步進電機驅動的理解,實際使用的時候當然有庫就用庫啦。

 

示例程序

整步驅動

// ----------------------------------------------------------------------------
// unipolarStepperTest_fullStep.ino
// 
// Created 2015-06-27
// By seesea <seesea2517#gmail#com> 
// 
// 單極步進電機單相勵磁整步驅動方式測試
// 
// 通過 uln2003 來控制,arduino 每一個 IO 口接一個輸入,對應輸出分別接到電機上,因 uln2003 是集電極開路輸出,所以電機公共端接高電平
// ----------------------------------------------------------------------------

const unsigned char pins[]  = { 8, 9, 10, 11 };
const unsigned char pinNum  = sizeof(pins) / sizeof(pins[0]);
const unsigned char delayMs = 10;   // 每步動作間隔,控制速度
const char dir = 1;                 // 正負一用來控制轉動方向

void setup()
{
    for (unsigned char i = 0; i < pinNum; ++i)
    {
        pinMode(pins[i], OUTPUT);
        digitalWrite(pins[i], LOW);
    }
}

// 每次進入函數時輪換引腳,在輪換到的引腳上發出高電平后經 uln2003 反相成低電平給電機上電
void loop()
{
    static unsigned char pulsePin = 0;

    digitalWrite(pins[pulsePin], HIGH);
    delay(delayMs);

    digitalWrite(pins[pulsePin], LOW);
    pulsePin = (pulsePin + dir + pinNum) % pinNum;
}

 

半步驅動

// ----------------------------------------------------------------------------
// unipolarStepperTest_halfStep.ino
// 
// Created 2015-06-28
// By seesea <seesea2517#gmail#com> 
// 
// 單極步進電機單相勵磁半步驅動方式測試
// 使用兩種方式來實現,一種使用數組做控制序列的,一種使用算法來實現
// 
// 通過 uln2003 來控制,arduino 每一個 IO 口接一個輸入,對應輸出分別接到電機上,因 uln2003 是集電極開路輸出,所以電機公共端接高電平
// ----------------------------------------------------------------------------

const unsigned char pins[]  = { 8, 9, 10, 11 };
const unsigned char pinNum  = sizeof(pins) / sizeof(pins[0]);
const unsigned char delayMs = 10;   // 每次動作間隔,控制速度
const char dir = 1;                 // 正負一用來控制轉動方向

const unsigned char controlSeq[] = { 0x08, 0x0C, 0x04, 0x06, 0x02, 0x03, 0x01, 0x09 };    // 控制序列:以低四位來表示 pins 里的 4 個引腳某一次動作時需要通電的兩引腳
const unsigned char pinMask[]    = { 0x01, 0x02, 0x04, 0x08 };                            // 引腳對應掩碼
const unsigned char seqNum = sizeof(controlSeq) / sizeof(controlSeq[0]);
// 如果把控制序列改成這樣,就變成原來的單相勵磁整步前進的方式:const unsigned char controlSeq[] = { 0x08, 0x04, 0x02, 0x01 };
// 如果把控制序列改成這樣,就變成雙相勵磁整步前進的方式:const unsigned char controlSeq[] = { 0x0C, 0x06, 0x03, 0x09 };

// 使用控制序列的方式來實現的半步驅動
// 對於復雜的沒有什么規律的方式可以選用
void halfStep_controlSeq()
{
    static unsigned char seqIndex = 0; // 當前序列

    // 發出高電平后經 uln2003 反相成低電平給電機上電
    for (unsigned char i = 0; i < pinNum; ++i)
    {
        digitalWrite(pins[i], (controlSeq[seqIndex] & pinMask[i]) ? HIGH : LOW);
    }
    
    seqIndex = (seqIndex + dir + seqNum) % seqNum;
    delay(delayMs);
}

// 用算法來實現的半步驅動
// 半步驅動的操作其實也是有一定規律的,所以也可以用一定的算法來實現
void halfStep_algrothm()
{
    static unsigned char pulsePin1 = 0;
    static unsigned char pulsePin2 = 0;

    digitalWrite(pins[pulsePin1], HIGH);
    digitalWrite(pins[pulsePin2], HIGH);
    delay(delayMs);

    digitalWrite(pins[pulsePin1], LOW);
    digitalWrite(pins[pulsePin2], LOW);
    
    // 算法實現
    // 兩個引腳的索引按規律前進(這里的前進是以 dir 為標准,如果 dir 是負數,把后退方向當成前進):
    // - 當兩個引腳一樣的時候,pin1 前進
    // - 當兩個引腳不一樣的時候,pin2 前進
    if (pulsePin1 == pulsePin2)
        pulsePin1 = (pulsePin1 + dir + pinNum) % pinNum;
    else
        pulsePin2 = (pulsePin2 + dir + pinNum) % pinNum;
}

void setup()
{
  Serial.begin(9600);
    for (unsigned char i = 0; i < pinNum; ++i)
    {
        pinMode(pins[i], OUTPUT);
        digitalWrite(pins[i], LOW);
    }
}

void loop()
{
    halfStep_controlSeq();
    // halfStep_algrothm();
}

 

實驗照片


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM