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();
}

 

实验照片

posted @ 2015-06-28 17:18  听听海看看云  阅读(6477)  评论(0编辑  收藏  举报