< >
Home » 树莓派3物联网 » 树莓派物联网-WiringPi GPIO接口控制步进电机

树莓派物联网-WiringPi GPIO接口控制步进电机

WiringPi GPIO接口控制步进电机

说明

  • 在树莓派上编写一个C程序,通过其GPIO口控制步进电机的转动方向以及速度

准备

  • 树莓派
  • 电机驱动板
  • 步进电机

步骤

  1. 步进电机和驱动板图
    请输入图片描述

  2. 步进电机和驱动板的接线
    请输入图片描述

  3. 驱动板配有一个原理图,根据它我们可以知道如何把整个系统连接起来
    请输入图片描述

  4. 驱动板上有4个输入口:IN1~IN4,这4个口用来接树莓派的4个GPIO口。同时,我们需要为驱动板提供5V的供电,这从哪里来?当然是从树莓派引出来。从下面的GPIO口分布图可以得知,“2”口就是+5V,正好就利用它。
    请输入图片描述

  1. 将树莓派上的GPIO 17、18、21、22口(用树莓派的命名方式就是0、1、2、3口)分别接到步进电机驱动板上的IN1、IN2、IN3、IN4口,最后接好线的效果如下:
    请输入图片描述

  2. 编写代码

  • 依次把驱动板的IN1~IN4置为高电平,就可以驱动步进电机,也就是说,要把树莓派的4个GPIO输出口依次置为高电平。例如,假设用0代表低电平,1代表高电平的话,GPIO 17、18、21、22口的电平第一次被置为1、0、0、0,第二次被置为0、1、0、0,第三次被置为0、0、1、0,第四次被置为0、0、0、1。
/* moto.c
* A program to control a stepper motor through the GPIO on Raspberry Pi. 
* 
* Author: Darran Zhang (http://www.codelast.com) 
*/
 
#include <wiringPi.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
 
#define CLOCKWISE 1
#define COUNTER_CLOCKWISE 2
 
void delayMS(int x);
void rotate(int* pins, int direction);
 
int main(int argc,char* argv[]) {
  if (argc < 4) {
    printf("Usage example: ./motor 0 1 2 3 \n");
    return 1;
  }
 
  /* number of the pins which connected to the stepper motor driver board */
  int pinA = atoi(argv[1]);
  int pinB = atoi(argv[2]);
  int pinC = atoi(argv[3]);
  int pinD = atoi(argv[4]);
 
  int pins[4] = {pinA, pinB, pinC, pinD};
 
  if (-1 == wiringPiSetup()) {
    printf("Setup wiringPi failed!");
    return 1;
  }
 
  /* set mode to output */
  pinMode(pinA, OUTPUT);
  pinMode(pinB, OUTPUT);
  pinMode(pinC, OUTPUT);
  pinMode(pinD, OUTPUT);
 
  delayMS(50);    // wait for a stable status 
  for (int i = 0; i < 500; i++) {
    rotate(pins, CLOCKWISE);
  }
 
  return 0;
}
 
/* Suspend execution for x milliseconds intervals.
 *  @param ms Milliseconds to sleep.
 */
void delayMS(int x) {
  usleep(x * 1000);
}
 
/* Rotate the motor.
 *  @param pins     A pointer which points to the pins number array.
 *  @param direction  CLOCKWISE for clockwise rotation, COUNTER_CLOCKWISE for counter clockwise rotation.
 */
void rotate(int* pins, int direction) {
  for (int i = 0; i < 4; i++) {
    if (CLOCKWISE == direction) {
      for (int j = 0; j < 4; j++) {
        if (j == i) {
          digitalWrite(pins[3 - j], 1); // output a high level 
        } else {
          digitalWrite(pins[3 - j], 0); // output a low level 
        }
      }
    } else if (COUNTER_CLOCKWISE == direction) {
      for (int j = 0; j < 4; j++) {
        if (j == i) {
          digitalWrite(pins[j], 1); // output a high level 
        } else {
          digitalWrite(pins[j], 0); // output a low level 
        }
      }
    }
    delayMS(4);
  }
}
  • 编译代码
g++ motor.c -o motor -lwiringPi
  • 运行代码
./motor 0 1 2 3

这里向程序传入了4个参数,它们分别代表要控制的树莓派的GPIO口。切记,由于使用了WiringPi库,所以要参考上面的GPIO分布图的左边那部分来确定这些数字。

可以看到步进电机已经转动了。如果你发现转动方向(顺/逆时针)反了,你可以把传入的参数顺序调整一下,就可以让它转对方向。

  1. 控制转速

如果要改变步进电机的转速,只需要改变rotate()函数中每次delay的时间即可。因此,如果我们把delay的时间逐渐由大变小,就会导致步进电机呈加速状态。让步进电机周期性加速的完整代码如下:

/* motor_speed_up.c
* A program to control a stepper motor(speed up) through the GPIO on Raspberry Pi.
*
* Author: Darran Zhang (http://www.codelast.com)
*/

#include <wiringPi.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>

#define CLOCKWISE 1
#define COUNTER_CLOCKWISE 2

void delayMS(int x);
void rotate(int* pins, int direction, int delay);
void stop(int* pins);

int main(int argc,char* argv[]) {
  if (argc < 4) {
    printf("Usage example: ./motor 0 1 2 3 \n");
    return 1;
  }

  /* number of the pins which connected to the stepper motor driver board */
  int pinA = atoi(argv[1]);
  int pinB = atoi(argv[2]);
  int pinC = atoi(argv[3]);
  int pinD = atoi(argv[4]);

  int pins[4] = {pinA, pinB, pinC, pinD};

  if (-1 == wiringPiSetup()) {
    printf("Setup wiringPi failed!");
    return 1;
  }

  /* set mode to output */
  pinMode(pinA, OUTPUT);
  pinMode(pinB, OUTPUT);
  pinMode(pinC, OUTPUT);
  pinMode(pinD, OUTPUT);

  delayMS(50);    // wait for a stable status
  int delay = 25;
  while (true) {
    for (int i = 0; i < 10; i++) {
      rotate(pins, CLOCKWISE, delay);
    }
    delay--;
    if (delay < 4) {
      delay = 25;
      stop(pins);
      delayMS(500);
    }
  }

  return 0;
}

/* Suspend execution for x milliseconds intervals.
*  @param ms Milliseconds to sleep.
*/
void delayMS(int x) {
  usleep(x * 1000);
}

/* Rotate the motor.
*  @param pins     A pointer which points to the pins number array.
*  @param direction  CLOCKWISE for clockwise rotation, COUNTER_CLOCKWISE for counter clockwise rotation.
*  @param delay    The time intervals(in ms) to delay, and if the value is smaller, the motor rotates faster.
*/
void rotate(int* pins, int direction, int delay) {
  for (int i = 0; i < 4; i++) {
    if (CLOCKWISE == direction) {
      for (int j = 0; j < 4; j++) {
        if (j == i) {
          digitalWrite(pins[3 - j], 1); // output a high level
        } else {
          digitalWrite(pins[3 - j], 0); // output a low level
        }
      }
    } else if (COUNTER_CLOCKWISE == direction) {
      for (int j = 0; j < 4; j++) {
        if (j == i) {
          digitalWrite(pins[j], 1); // output a high level
        } else {
          digitalWrite(pins[j], 0); // output a low level
        }
      }
    }
    delayMS(delay);
  }
}

/* Stop the motor.
*  @param pins     A pointer which points to the pins number array.
*/
void stop(int* pins) {
  for (int i = 0; i < 4; i++) {
    digitalWrite(pins[i], 0); // output a low level
  }
}

参考:

  • http://bbs.elecfans.com/jishu_439995_1_1.html

纠错,疑问,交流: 请进入讨论区点击加入Q群

获取最新文章: 扫一扫右上角的二维码加入“创客智造”公众号


标签: 树莓派3gpio, 树莓派3步进电机