4步进电机控制程序
From SZDOIT

4.18. 4步进电机控制程序#

4.18.1. 1 控制板#

wps1

这款板子的详细资料,请查阅:https://gitnova.com/#/zh/zhControlPanel/DOIT-ARM/DOIT-ARM

4.18.2. 2 接线#

wps2

4.18.3. 3 蓝牙WiFi控制软件#

注:仅支持安卓手机

下载地址:https://github.com/SmartArduino/SmartArduino.github.io/blob/master/docs/Robot/Controller/app/base.apk

4.18.4. 4 示例程序#

WiFi/蓝牙示例程序:

#define X_EN   38
#define X_STEP A0
#define X_DIR  A1
#define Y_EN   A2
#define Y_STEP A6
#define Y_DIR  A7
#define Z_EN   A8
#define Z_STEP 46
#define Z_DIR  48
#define E_EN   24
#define E_STEP 26
#define E_DIR  28
#define MAX_PACKETSIZE 32  //串口接收缓冲区
char buffUART[MAX_PACKETSIZE];
unsigned int buffUARTIndex = 0;
unsigned long preUARTTick = 0;
int i;
enum DN
{
  GO_FORWARD,
  GO_BACK,
  GO_RIGHT,
  GO_LEFT,
  STOP,
  DEF
}Drive_Num=DEF;

void forward()
{
  Serial.println("forward");
  digitalWrite(X_DIR,HIGH);
  digitalWrite(Y_DIR,LOW);
  digitalWrite(Z_DIR,HIGH);
  digitalWrite(E_DIR,LOW);
  for(i=0;i<=100;i++)
  {
    digitalWrite(X_STEP,HIGH);
    digitalWrite(Y_STEP,HIGH);
    digitalWrite(Z_STEP,HIGH);
    digitalWrite(E_STEP,HIGH);
    delayMicroseconds(100);
    digitalWrite(X_STEP,LOW);
    digitalWrite(Y_STEP,LOW);
    digitalWrite(Z_STEP,LOW);
    digitalWrite(E_STEP,LOW);
    delayMicroseconds(100);
  }
}
void turnleft()
{
  Serial.println("turnleft");
  digitalWrite(X_DIR,HIGH);
  digitalWrite(Y_DIR,HIGH);
  digitalWrite(Z_DIR,HIGH);
  digitalWrite(E_DIR,HIGH);
  for(i=0;i<=100;i++)
  {
    digitalWrite(X_STEP,HIGH);
    digitalWrite(Y_STEP,HIGH);
    digitalWrite(Z_STEP,HIGH);
    digitalWrite(E_STEP,HIGH);
    delayMicroseconds(100);
    digitalWrite(X_STEP,LOW);
    digitalWrite(Y_STEP,LOW);
    digitalWrite(Z_STEP,LOW);
    digitalWrite(E_STEP,LOW);
    delayMicroseconds(100);
  }
}
void turnright()
{
  Serial.println("turnright");
  digitalWrite(X_DIR,LOW);
  digitalWrite(Y_DIR,LOW);
  digitalWrite(Z_DIR,LOW);
  digitalWrite(E_DIR,LOW);
  for(i=0;i<=100;i++)
  {
    digitalWrite(X_STEP,HIGH);
    digitalWrite(Y_STEP,HIGH);
    digitalWrite(Z_STEP,HIGH);
    digitalWrite(E_STEP,HIGH);
    delayMicroseconds(100);
    digitalWrite(X_STEP,LOW);
    digitalWrite(Y_STEP,LOW);
    digitalWrite(Z_STEP,LOW);
    digitalWrite(E_STEP,LOW);
    delayMicroseconds(100);
  }
}
void back()
{
  Serial.println("back");
  digitalWrite(X_DIR,LOW);
  digitalWrite(Y_DIR,HIGH);
  digitalWrite(Z_DIR,LOW);
  digitalWrite(E_DIR,HIGH);
  for(i=0;i<=100;i++)
  {
    digitalWrite(X_STEP,HIGH);
    digitalWrite(Y_STEP,HIGH);
    digitalWrite(Z_STEP,HIGH);
    digitalWrite(E_STEP,HIGH);
    delayMicroseconds(100);
    digitalWrite(X_STEP,LOW);
    digitalWrite(Y_STEP,LOW);
    digitalWrite(Z_STEP,LOW);
    digitalWrite(E_STEP,LOW);
    delayMicroseconds(100);
  }
}
void Stop()
{
  Serial.println("stop");
  digitalWrite(X_DIR,LOW);
  digitalWrite(Y_DIR,LOW);
  digitalWrite(Z_DIR,LOW);
  digitalWrite(E_DIR,LOW);
  digitalWrite(X_STEP,LOW);
  digitalWrite(Y_STEP,LOW);
  digitalWrite(Z_STEP,LOW);
  digitalWrite(E_STEP,LOW);
}
void BT()
{
   char Uart_Date;
   int char_to_int;
   if(Serial.available())
   { 
      char Uart_Date = Serial.read();
      Serial.println(Uart_Date);
      char_to_int = (int)Uart_Date;
      Serial.println(char_to_int);
   }
   if(buffUARTIndex > 0 && (millis() - preUARTTick >= 100))//超过100ms没接到数据,则认为已经接收到完整指令
   { //data ready
      buffUART[buffUARTIndex] = 0x00;
      if((buffUART[0]=='C') && (buffUART[1]=='M') && (buffUART[2]=='D')) //若发送指令非法,则忽略
      {
        ;
      }
      else Uart_Date=buffUART[0];
        buffUARTIndex = 0;
    }
    switch(char_to_int)
    {
      case '2': Drive_Num = GO_FORWARD; break;
      case '8': Drive_Num = GO_BACK;    break;
      case '4': Drive_Num = GO_RIGHT;   break;
      case '6': Drive_Num = GO_LEFT;    break;
      case '5': Drive_Num = STOP;       break;
      default: break;
    }
}
void Car_control()
{
  switch(Drive_Num)
  {
    case GO_FORWARD: forward();    break;
    case GO_BACK:    back();       break;
    case GO_LEFT:    turnleft();   break;
    case GO_RIGHT:   turnright();  break;
    case STOP:       Stop();       break;
    default: break;
  }
}

void setup() 
{
  Serial.begin(115200);
  pinMode(X_EN,  OUTPUT);
  pinMode(X_STEP,OUTPUT);
  pinMode(X_DIR, OUTPUT);
  pinMode(Y_EN,  OUTPUT);
  pinMode(Y_STEP,OUTPUT);
  pinMode(Y_DIR, OUTPUT);
  pinMode(Z_EN,  OUTPUT);
  pinMode(Z_STEP,OUTPUT);
  pinMode(Z_DIR, OUTPUT);
  pinMode(E_EN,  OUTPUT);
  pinMode(E_STEP,OUTPUT);
  pinMode(E_DIR, OUTPUT);
  digitalWrite(X_EN, LOW);
  digitalWrite(Y_EN, LOW);
  digitalWrite(Z_EN, LOW);
  digitalWrite(E_EN, LOW);
}
void loop() 
{
  BT();
  Car_control();
}

PS2手柄示例程序:

程序里面使用到的第三方库,请自行下载:https://github.com/SmartArduino/Arduino-Third-party-Libraries

#include <PS2X_lib.h>  //for v1.6

//PS2手柄引脚;
#define PS2_DAT        13      
#define PS2_CMD        22
#define PS2_SEL        49  
#define PS2_CLK        12  

// 电机控制引脚;
#define X_EN   38
#define X_STEP A0
#define X_DIR  A1
#define Y_EN   A2
#define Y_STEP A6
#define Y_DIR  A7
#define Z_EN   A8
#define Z_STEP 46
#define Z_DIR  48
#define E_EN   24
#define E_STEP 26
#define E_DIR  28

enum DN
{
  GO_FORWARD,
  GO_BACK,
  GO_LEFT,
  GO_RIGHT,
  STOP,
  DEF
}Drive_Num=DEF;

/******************************************************************
 * select modes of PS2 controller:
 *   - pressures = analog reading of push-butttons 
 *   - rumble    = motor rumbling
 * uncomment 1 of the lines for each mode selection
 ******************************************************************/
#define pressures   true
//#define pressures   false
#define rumble      true
//#define rumble      false

PS2X ps2x; // create PS2 Controller Class

//right now, the library does NOT support hot pluggable controllers, meaning 
//you must always either restart your Arduino after you connect the controller, 
//or call config_gamepad(pins) again after connecting the controller.

int error = 0;
byte type = 0;
byte vibrate = 0;
int R;

void (* resetFunc) (void) = 0;

/******初始化******/
 void setup()
 {
  pinMode(X_EN,  OUTPUT);
  pinMode(X_STEP,OUTPUT);
  pinMode(X_DIR, OUTPUT);
  pinMode(Y_EN,  OUTPUT);
  pinMode(Y_STEP,OUTPUT);
  pinMode(Y_DIR, OUTPUT);
  pinMode(Z_EN,  OUTPUT);
  pinMode(Z_STEP,OUTPUT);
  pinMode(Z_DIR, OUTPUT);
  pinMode(E_EN,  OUTPUT);
  pinMode(E_STEP,OUTPUT);
  pinMode(E_DIR, OUTPUT);
  digitalWrite(X_EN, LOW);
  digitalWrite(Y_EN, LOW);
  digitalWrite(Z_EN, LOW);
  digitalWrite(E_EN, LOW);
   Serial.begin(115200);
   delay(300) ; //added delay to give wireless ps2 module some time to startup, before configuring it
   //CHANGES for v1.6 HERE!!! **************PAY ATTENTION*************

  //setup pins and settings: GamePad(clock, command, attention, data, Pressures?, Rumble?) check for error
  error = ps2x.config_gamepad(PS2_CLK, PS2_CMD, PS2_SEL, PS2_DAT, pressures, rumble);

  if(error == 0){
    Serial.print("Found Controller, configured successful ");
    Serial.print("pressures = ");
  if (pressures)
    Serial.println("true ");
  else
    Serial.println("false");
  Serial.print("rumble = ");
  if (rumble)
    Serial.println("true)");
  else
    Serial.println("false");
    Serial.println("Try out all the buttons, X will vibrate the controller, faster as you press harder;");
    Serial.println("holding L1 or R1 will print out the analog stick values.");
    Serial.println("Note: Go to www.billporter.info for updates and to report bugs.");
  }  
  else if(error == 1){
    Serial.println("No controller found, check wiring, see readme.txt to enable debug. visit www.billporter.info for troubleshooting tips");
    resetFunc();
  }
  else if(error == 2){
    Serial.println("Controller found but not accepting commands. see readme.txt to enable debug. Visit www.billporter.info for troubleshooting tips");
  }

  else if(error == 3){
    Serial.println("Controller refusing to enter Pressures mode, may not support it. ");
  }

 //  Serial.print(ps2x.Analog(1), HEX);

  type = ps2x.readType(); 
  switch(type) {
    case 0:
      Serial.print("Unknown Controller type found ");
      break;
    case 1:
      Serial.print("DualShock Controller found ");
      break;
    case 2:
      Serial.print("GuitarHero Controller found ");
      break;
  case 3:
      Serial.print("Wireless Sony DualShock Controller found ");
      break;
   }
}

//定义小车运动方式

 void turnLeft()//左转
{
  digitalWrite(X_DIR,HIGH);
  digitalWrite(Y_DIR,HIGH);
  digitalWrite(Z_DIR,HIGH);
  digitalWrite(E_DIR,HIGH);
  for(R=0;R<=100;R++)
  {
    digitalWrite(X_STEP,HIGH);
    digitalWrite(Y_STEP,HIGH);
    digitalWrite(Z_STEP,HIGH);
    digitalWrite(E_STEP,HIGH);
    delayMicroseconds(100);
    digitalWrite(X_STEP,LOW);
    digitalWrite(Y_STEP,LOW);
    digitalWrite(Z_STEP,LOW);
    digitalWrite(E_STEP,LOW);
    delayMicroseconds(100);
  }
}

 void turnRight()//右转
{
  digitalWrite(X_DIR,LOW);
  digitalWrite(Y_DIR,LOW);
  digitalWrite(Z_DIR,LOW);
  digitalWrite(E_DIR,LOW);
  for(R=0;R<=100;R++)
  {
    digitalWrite(X_STEP,HIGH);
    digitalWrite(Y_STEP,HIGH);
    digitalWrite(Z_STEP,HIGH);
    digitalWrite(E_STEP,HIGH);
    delayMicroseconds(100);
    digitalWrite(X_STEP,LOW);
    digitalWrite(Y_STEP,LOW);
    digitalWrite(Z_STEP,LOW);
    digitalWrite(E_STEP,LOW);
    delayMicroseconds(100);
  }
}

void forward()//前进
{ 
  digitalWrite(X_DIR,HIGH);
  digitalWrite(Y_DIR,LOW);
  digitalWrite(Z_DIR,HIGH);
  digitalWrite(E_DIR,LOW);
  for(R=0;R<=100;R++)
  {
    digitalWrite(X_STEP,HIGH);
    digitalWrite(Y_STEP,HIGH);
    digitalWrite(Z_STEP,HIGH);
    digitalWrite(E_STEP,HIGH);
    delayMicroseconds(100);
    digitalWrite(X_STEP,LOW);
    digitalWrite(Y_STEP,LOW);
    digitalWrite(Z_STEP,LOW);
    digitalWrite(E_STEP,LOW);
    delayMicroseconds(100);
  }
}

void back()//后退
{
  digitalWrite(X_DIR,LOW);
  digitalWrite(Y_DIR,HIGH);
  digitalWrite(Z_DIR,LOW);
  digitalWrite(E_DIR,HIGH);
  for(R=0;R<=100;R++)
  {
    digitalWrite(X_STEP,HIGH);
    digitalWrite(Y_STEP,HIGH);
    digitalWrite(Z_STEP,HIGH);
    digitalWrite(E_STEP,HIGH);
    delayMicroseconds(100);
    digitalWrite(X_STEP,LOW);
    digitalWrite(Y_STEP,LOW);
    digitalWrite(Z_STEP,LOW);
    digitalWrite(E_STEP,LOW);
    delayMicroseconds(100);
  }
}
void Stop() // 停止;
{
  digitalWrite(X_DIR,LOW);
  digitalWrite(Y_DIR,LOW);
  digitalWrite(Z_DIR,LOW);
  digitalWrite(E_DIR,LOW);
  digitalWrite(X_STEP,LOW);
  digitalWrite(Y_STEP,LOW);
  digitalWrite(Z_STEP,LOW);
  digitalWrite(E_STEP,LOW);
}
void ps2()
{
  /* You must Read Gamepad to get new values and set vibration values
     ps2x.read_gamepad(small motor on/off, larger motor strenght from 0-255)
     if you don't enable the rumble, use ps2x.read_gamepad(); with no values
     You should call this at least once a second
   */  
  if(error == 1) //skip loop if no controller found
    return; 

  if(type == 2) {//Guitar Hero Controller
  return;
  }
  else  { //DualShock Controller
    ps2x.read_gamepad(false, vibrate); //read controller and set large motor to spin at 'vibrate' speed


//start 开始运行,电机初PWM为100;
// 电机正转;
    if(ps2x.Button(PSB_PAD_UP)){
      Serial.println("Up held this hard: ");
      Drive_Num = GO_FORWARD;
    }

// 电机反转;
    else if(ps2x.Button(PSB_PAD_DOWN)){
      Serial.println("Down held this hard: ");
      Drive_Num = GO_BACK;
    }

 //左转;   
    else if(ps2x.Button(PSB_PAD_LEFT)){
       Serial.println("turn left ");
       Drive_Num = GO_LEFT;       
    }

//右转;
   else if(ps2x.Button(PSB_PAD_RIGHT))
   {
    Serial.println("turn right");
    Drive_Num = GO_RIGHT;
   }
   else
   {
      Drive_Num = STOP;
   }
  }
}
void Car_Control()
{
  switch(Drive_Num)
  {
    case GO_FORWARD: forward();   break;
    case GO_BACK:    back();      break;
    case GO_LEFT:    turnLeft();  break;
    case GO_RIGHT:   turnRight(); break;
    case STOP:       Stop();      break;
  }
}
void loop()
{
   ps2();
   Car_Control();
}

4.18.5. 更多资源,请关注公众号!#

wps101010