零基础入门学用Arduino 第四部分(三)

重要的内容写在前面:

  1. 该系列是以up主太极创客的零基础入门学用Arduino教程为基础制作的学习笔记。
  2. 个人把这个教程学完之后,整体感觉是很好的,如果有条件的可以先学习一些相关课程,学起来会更加轻松,相关课程有数字电路(强烈推荐先学数电,不然可能会有一些地方理解起来很困难)、模拟电路等,然后就是C++(注意C++是必学的)
  3. 文章中的代码都是跟着老师边学边敲的,不过比起老师的版本我还把注释写得详细了些,并且个人认为重要的地方都有详细的分析。
  4. 一些函数的介绍有参考太极创客官网给出的中文翻译,为了便于现查现用,把个人认为重要的部分粘贴了过来并做了一些修改。
  5. 如有错漏欢迎指正。

视频链接:4-1-1 电机基本结构与工作原理_哔哩哔哩_bilibili

太极创客官网:太极创客 – Arduino, ESP8266物联网的应用、开发和学习资料

四、Arduino AFMotor电机扩展板

1、Arduino AFMotor电机扩展板概述

(1)Arduino AFMotor电机扩展板专门与Arduino开发板配合使用,如下图所示,它是直接插在Arduino开发板上的。

(2)AFMOTOR电机扩展板主要功能特点:

①最多可驱动4个模型直流电机。

②最多可驱动2个28BYJ-48步进电机。

③最多可驱动2个舵机(伺服电机)。

④板载两块L293D芯片负责电机驱动的核心工作

⑤可配合Arduino Uno/Mega开发板使用(这里主要针对Uno开发板进行介绍)。

(3)Arduino AFMotor电机扩展板的各个端口如下所示。

①AFMotor电机扩展板上配有外接电源接口,该接口所连接的直流电源可以为电机和Arduino开发板供电。

[1]使用AFMotor电机扩展板驱动电机时,要考虑的问题就是电源的输出功率需要达到驱动电机的要求(对于工作电压低于4.5V的直流电机,不建议使用AFMotor驱动板来驱动),并且不宜过大。

[2]AFMotor扩展板中起关键作用的芯片是L293D,该芯片所允许的直流电源电压范围是4.5V ~25V,因此AFMotor扩展板外接电源接口允许连接的电源也是4.5V~25V。

[3]通常我们使用AFMotor电机扩展板所驱动的电机就是普通的模型电机,对于这一类型的电机,它们的工作电流大约是500mA左右,因此只要为扩展板配一个500 mA~1000 mA的外接电源就足够了;假如电机工作电流超过500mA,那么就要考虑为扩展板上的L293D加装芯片。

[4]外接电源极性千万不要接反,否则会对扩展板造成损坏。

②Arduino开发板的模拟输入输出引脚(A0~A5)没有被AFMotor扩展板所占用,模拟输入输出引脚被AFMotor扩展板延申至板上以便使用。模拟引脚旁的另外两排引脚分别是Arduino的+5V引脚和接地引脚。

③Arduino引脚2和引脚13都没有被AFMotor电机扩展板所占用。

2、AFMotor库

(1)使用AFMotor电机扩展板驱动电机以前,需要先将AFMotor库(属于第三方库)安装到Arduino IDE中。

(2)AFMotor库函数:

①AF_DCMotor.setSpeed(speed):将电机AF_DCMotor的运行速度设置为speed(取值范围为0-255)。

②AF_DCMotor.run(mode):mode的可选值为RELEASE、FORWARD、BACKWARD。

[1]RELEASE:让扩展板停止为电机AF_DCMotor提供运转动力,电机AF_DCMotor一旦失去动力就会自然的停止转动

[2]FORWARD:设置电机AF_DCMotor的运动方向为正向。

[3]BACKWARD:设置电机AF_DCMotor的运动方向为反向。

③AF_DCMotor.step(steps, mode1, mode2):该函数针对步进电机,其中steps为控制步进电机运动的步数,mode1的可选值为FORWARD、BACKWARD,即选择运动方向为正向或反向,mode2的可选值为SINGLE、DOUBLE、INTERLEAVE、NICROSTEP,其意义分别为全步进模式(单线圈)、全步进模式(双线圈)、半步进模式、微步进模式。

④AF_DCMotor.onestep(mode1, mode2):该函数针对步进电机,其中mode1的可选值为FORWARD、BACKWARD,即选择运动方向为正向或反向,mode2的可选值为SINGLE、DOUBLE、INTERLEAVE、NICROSTEP,即选择运动方式。

(3)借助AF_Stepper类,可以建立AccelStepper库能使用的步进电机对象。根据之前的经验,AccelStepper类的对象的构造函数参数可以是步进模式以及4个控制引脚编号,在这里可以将构造函数的参数替换为两个自定义函数的函数名,两个函数均封装一个AF_Stepper类的onestep函数,分别控制AF_Stepper对象的电机在正反方向上各走一步,根据这两个函数,Arduino可得到AF_Stepper对象的电机的相关信息,用于初始化AccelStepper类的对象。

3、Arduino驱动直流电机

(1)在AFMotor电机扩展板的两侧共有4个直流电机端口,每一个端口都有独立的编号,分别为M1、M2、M3、M4,每一个电机端口都是由两个接线端子所构成,如下图所示。如果只是单纯的想要让电机转起来,那么这两根引线连接到扩展板端口上是没有顺序的;但如果对电机的旋转方向有所要求,而电机旋转的方向与用户所期待的相反,那么可以将这两根电机引线从扩展板上断开,然后交换顺序再接到扩展板端子上,这时会看到电机旋转的方向就反过来了。

(2)驱动直流电机电路的连接:

①项目开发时驱动直流电机电路的连接:(下图红色箭头指示的跳线一定要移除,该跳线的作用是控制Arduino开发板由外接电源供电,而项目开发时Arduino开发板由电脑供电)

②工作运行时驱动直流电机电路的连接:(下图红色箭头指示的跳线要安置好,工作运行时Arduino开发板由外接电源供电)

(3)示例程序:

#include <AFMotor.h>
AF_DCMotor motor1(1); //为1号电机建立对象,1号电机连接AFMotor扩展板的电机端口号码为1
AF_DCMotor motor2(2); //为2号电机建立对象,2号电机连接AFMotor扩展板的电机端口号码为2
AF_DCMotor motor3(3); //为3号电机建立对象,3号电机连接AFMotor扩展板的电机端口号码为3
AF_DCMotor motor4(4); //为4号电机建立对象,4号电机连接AFMotor扩展板的电机端口号码为4

void setup() 
{
  //4个电机的转速均设置为200
  motor1.setSpeed(200);motor2.setSpeed(200);
  motor3.setSpeed(200);motor4.setSpeed(200);
  //初始时电机全部不转动
  motor1.run(RELEASE);motor2.run(RELEASE);motor3.run(RELEASE);motor4.run(RELEASE);
}

void loop() 
{
  //将4个电机的旋转方向均设置为正向
  motor1.run(FORWARD);motor2.run(FORWARD);
  motor3.run(FORWARD);motor4.run(FORWARD);
  for (int i=0; i<=255; i++){   //从0开始,4个电机的转速每隔10ms增加1,直至增加到255
    motor1.setSpeed(i);motor2.setSpeed(i);motor3.setSpeed(i);motor4.setSpeed(i);
    delay(10);
  }                             
  for (int i=255; i>=0; i--){  //从255开始,4个电机的转速每隔10ms减小1,直至减小到0
    motor1.setSpeed(i);motor2.setSpeed(i);motor3.setSpeed(i);motor4.setSpeed(i); 
    delay(10);
  } //对于一些模型电机来说,当速度参数小于一定数值以后就不能转动了,这属于正常现象

  //将4个电机的旋转方向均设置为反向
  motor1.run(BACKWARD);motor2.run(BACKWARD);
  motor3.run(BACKWARD);motor4.run(BACKWARD);
  for (int i=0; i<=255; i++){   //从0开始,4个电机的转速每隔10ms增加1,直至增加到255 
    motor1.setSpeed(i);motor2.setSpeed(i);motor3.setSpeed(i);motor4.setSpeed(i); 
    delay(10);
  }
  for (int i=255; i>=0; i--){  //从255开始,4个电机的转速每隔10ms减小1,直至减小到0  
    motor1.setSpeed(i);motor2.setSpeed(i); motor3.setSpeed(i);motor4.setSpeed(i); 
    delay(10);
  } //对于一些模型电机来说,当速度参数小于一定数值以后就不能转动了,这属于正常现象
  
  //停止为4个电机提供运转动力
  motor1.run(RELEASE);motor2.run(RELEASE);motor3.run(RELEASE);motor4.run(RELEASE);
  delay(1000);  //让4个电机保持无旋转动力状态1秒钟
}

4、Arduino驱动28BYJ-48步进电机

(1)在AFMotor电机扩展板的两侧共有两个步进电机端口,每一个电机端口都是由五个接线端子所构成。

(2)驱动28BYJ-48步进电机电路的连接:

①项目开发时驱动28BYJ-48步进电机电路的连接:(下图红色箭头指示的跳线一定要移除,该跳线的作用是控制Arduino开发板由外接电源供电,而项目开发时Arduino开发板由电脑供电)

②工作运行时驱动28BYJ-48步进电机电路的连接:(下图红色箭头指示的跳线要安置好,工作运行时Arduino开发板由外接电源供电)

(3)示例程序:

①示例程序1:

#include <AFMotor.h>

AF_Stepper motor1(2048, 1);  //为步进电机1建立步进电机对象,它旋转一周的步数为2048,连接在扩展板上的端口号为1
AF_Stepper motor2(2048, 2);  //为步进电机2建立步进电机对象,它旋转一周的步数为2048,连接在扩展板上的端口号为2

void setup() 
{
  Serial.begin(9600);      //启动串口通讯
  
  motor1.setSpeed(10);     //设置电机1的运行速度参数为10
  motor2.setSpeed(10);     //设置电机2的运行速度参数为10
}

void loop() 
{
  Serial.println("Single Mode");
  motor1.step(2048, FORWARD, SINGLE); //步进电机1以全步进模式(单线圈)"正转"2048步
  motor1.step(2048, BACKWARD, SINGLE);//步进电机2以全步进模式(单线圈)"反转"2048步

  Serial.println("Double Mode");
  motor2.step(2048, FORWARD, DOUBLE); //步进电机1以全步进模式(双线圈)"正转"2048步
  motor2.step(2048, BACKWARD, DOUBLE);//步进电机2以全步进模式(双线圈)"反转"2048步

  Serial.println("Interleave Mode");
  motor1.step(2048, FORWARD, INTERLEAVE);    //步进电机1以半步进模式"正转"2048步
  motor1.step(2048, BACKWARD, INTERLEAVE);   //步进电机2以半步进模式"反转"2048步

  Serial.println("Micrsostep Mode");
  motor2.step(2048, FORWARD, MICROSTEP);      //步进电机1以微步进模式"正转"2048步
  motor2.step(2048, BACKWARD, MICROSTEP);     //步进电机2以微步进模式"反转"2048步
}

②示例程序2:

#include <AFMotor.h>
#include <AccelStepper.h>

AF_Stepper motor1(2048, 1);  //为步进电机1建立步进电机对象,它旋转一周的步数为2048,连接在扩展板上的端口号为1
AF_Stepper motor2(2048, 2);  //为步进电机2建立步进电机对象,它旋转一周的步数为2048,连接在扩展板上的端口号为2

void forwardstep1() {                
  motor1.onestep(FORWARD, SINGLE);    //电机1正向旋转1步
}                                     
void backwardstep1() {  
  motor1.onestep(BACKWARD, SINGLE);   //电机1反向旋转1步
}
void forwardstep2() {  
  motor2.onestep(FORWARD, SINGLE);    //电机2正向旋转1步
}
void backwardstep2() {  
  motor2.onestep(BACKWARD, SINGLE);   //电机2反向旋转1步
}

//借助AF_Stepper类,建立AccelStepper库能使用的步进电机对象
AccelStepper stepper1(forwardstep1, backwardstep1);  //根据让电机1在正反向各旋转1步的自定义函数,Arduino可得到电机1的相关信息,用于初始化stepper1
AccelStepper stepper2(forwardstep2, backwardstep2);  //根据让电机2在正反向各旋转1步的自定义函数,Arduino可得到电机2的相关信息,用于初始化stepper2

void setup()
{        
  stepper1.setMaxSpeed(500);  //设置电机1的最大运行速度为500
  stepper1.setSpeed(300);     //设置电机1在匀速模式下的运行速度为300
  stepper2.setMaxSpeed(500);  //设置电机2的最大运行速度为500
  stepper2.setSpeed(300);     //设置电机2在匀速模式下的运行速度为300
}

void loop()
{  
  stepper1.runSpeed();  //电机1匀速旋转
  stepper2.runSpeed();  //电机2匀速旋转
}

③示例程序3:

[1]全局变量、宏定义、包含头文件及初始化操作:

#include <AccelStepper.h>
#include <AFMotor.h>

#define stepperSpeed 300    //匀速模式下电机的运动速度
AF_Stepper motor1(2048, 1);  //为步进电机1建立步进电机对象,它旋转一周的步数为2048,连接在扩展板上的端口号为1
AF_Stepper motor2(2048, 2);  //为步进电机2建立步进电机对象,它旋转一周的步数为2048,连接在扩展板上的端口号为2
char cmd;        //存储电机指令字符
int data;        //存储电机指令参数
int stepperNum;  //存储当前控制电机的编号

void forwardstep1() {                
  motor1.onestep(FORWARD, SINGLE);    //电机1正向旋转1步
}                                     
void backwardstep1() {  
  motor1.onestep(BACKWARD, SINGLE);   //电机1反向旋转1步
}
void forwardstep2() {  
  motor2.onestep(FORWARD, SINGLE);    //电机2正向旋转1步
}
void backwardstep2() {  
  motor2.onestep(BACKWARD, SINGLE);   //电机2反向旋转1步
}
//借助AF_Stepper类,建立AccelStepper库能使用的步进电机对象
AccelStepper stepper1(forwardstep1, backwardstep1);  //根据让电机1在正反向各旋转1步的自定义函数,Arduino可得到电机1的相关信息,用于初始化stepper1
AccelStepper stepper2(forwardstep2, backwardstep2);  //根据让电机2在正反向各旋转1步的自定义函数,Arduino可得到电机2的相关信息,用于初始化stepper2

void setup()
{    
  stepper1.setMaxSpeed(stepperSpeed); //设置1号电机匀速模式下的运动速度为300
  stepper1.setAcceleration(100.0);    //设置1号电机的加速度为50.0
  stepper2.setMaxSpeed(stepperSpeed); //设置2号电机匀速模式下的运动速度为300
  stepper2.setAcceleration(100.0);    //设置2号电机的加速度为50.0 

  Serial.begin(9600);
  Serial.println(F("++++++++++++++++++++++++++++++++++"));     
  Serial.println(F("+Taichi-Maker AFMotor Shield Demo+"));   
  Serial.println(F("+     www.taichi-maker.com       +"));  
  Serial.println(F("++++++++++++++++++++++++++++++++++"));  
  Serial.println(F(""));Serial.println(F("Please input motor command:"));    
}

[2]主循环部分:

void loop()
{  
 if (Serial.available())  //检查串口缓存是否有数据等待传输 
 {     
    cmd = Serial.read();        //获取电机指令中指令信息    
    Serial.print(F("cmd = "));
    Serial.print(cmd);    
    Serial.print(F(" , ")); 
    
    data = Serial.parseInt();   //获取电机指令中参数信息  
    Serial.print(F("data = "));
    Serial.print(data);   
    Serial.println(F(""));    
    
    runUsrCmd();   //用户命令处理
  }
  stepper1.run();  //设置电机1为先加速后减速模式
  stepper2.run();  //设置电机2为先加速后减速模式
}

[3]用户命令处理部分:

void runUsrCmd()
{
  switch(cmd){ 
    case 'o':  //获取当前电机输出轴位置
      Serial.print(F("stepper1 Position: ")); 
      Serial.println(stepper1.currentPosition());  //获取当前电机1的输出轴位置  
      Serial.print(F("stepper2 Position: ")); 
      Serial.println(stepper2.currentPosition());  //获取当前电机2的输出轴位置
      Serial.print(F("Current Running Motor: "));  
      //输出当前受控制的电机编号
      if (stepperNum == 1 || stepperNum == 2){  //只有一个电机受控制
        Serial.print(F("Motor# "));Serial.println(stepperNum); 
      } 
      else if (stepperNum == 0 ){   //两个电机同时受控制
        Serial.println(F("Both Motors")); 
      }break;    
    case 'v':  //使电机运行到用户指定的坐标位置
      if (stepperNum == 1){
        Serial.print(F("Motor1 'moveTo' "));Serial.println(data); 
        stepper1.moveTo(data);  //控制电机1运行到data对应的绝对位置
      }
      else if (stepperNum == 2){
        Serial.print(F("Motor2 'moveTo' "));Serial.println(data); 
        stepper2.moveTo(data);  //控制电机2运行到data对应的绝对位置 
      }
      else if (stepperNum == 0){    //两个电机可以同时运行
        Serial.print(F("Both Motors 'moveTo' "));Serial.println(data); 
        stepper1.moveTo(data);  //控制电机1运行到data对应的绝对位置
        stepper2.moveTo(data);  //控制电机2运行到data对应的绝对位置 
      }break;
    case 'm':   //使电机运行相应步数(可顺时针也可逆时针)
      if (stepperNum == 1){
        Serial.print(F("Motor1 'move'  "));Serial.println(data); 
        stepper1.move(data);  //以当前位置为参照点,控制电机1运行到data对应的相对位置
      }
      else if (stepperNum == 2){
        Serial.print(F("Motor2 'move'  "));Serial.println(data);
        stepper2.move(data);  //以当前位置为参照点,控制电机2运行到data对应的相对位置
      }
      else if (stepperNum == 0){    //两个电机可以同时运行
        Serial.print(F("Both Motors 'move'  "));Serial.println(data);
        stepper1.move(data);  //以当前位置为参照点,控制电机1运行到data对应的相对位置
        stepper2.move(data);  //以当前位置为参照点,控制电机2运行到data对应的相对位置
      }break;
    case 'r':  //让电机运行到用户指定的位置 
      if (stepperNum == 1){
        Serial.print(F("Motor1 'runToNewPosition' "));Serial.println(data);
        stepper1.runToNewPosition(data);  //控制电机1运行到data对应的绝对位置
      }
      else if (stepperNum == 2){
        Serial.print(F("Motor2 'runToNewPosition' "));Serial.println(data);
        stepper2.runToNewPosition(data);  //控制电机2运行到data对应的绝对位置
      }
      else if (stepperNum == 0){         //电机1运行结束后,电机2才能开始运行
        Serial.print(F("Both Motors 'runToNewPosition' "));Serial.println(data);
        stepper1.runToNewPosition(data);  //控制电机1运行到data对应的绝对位置
        stepper2.runToNewPosition(data);  //控制电机2运行到data对应的绝对位置 
      }break;   
    case 's':   //设置当前位置为用户指定位置值
      if (stepperNum == 1){
        Serial.print(F("Set stepper1 Current Position to "));
        Serial.println(data);   //将电机1输出轴当前位置的数值设置为data
        stepper1.setCurrentPosition(data); 
      }
      else if (stepperNum == 2){
        Serial.print(F("Set stepper2 Current Position to "));
        Serial.println(data);   //将电机2输出轴当前位置的数值设置为data
        stepper2.setCurrentPosition(data);
      }
      else if (stepperNum == 0){
        Serial.print(F("Set both steppers' Current Position to "));Serial.println(data);
        stepper1.setCurrentPosition(data);  //将电机1输出轴当前位置的数值设置为data
        stepper2.setCurrentPosition(data);  //将电机2输出轴当前位置的数值设置为data
      }break;
    case 'a':   //设置电机在先加速后减速模式下运行的加速度 
      if (stepperNum == 1){
        Serial.print(F("Motor1 'setAcceleration' "));Serial.println(data);
        stepper1.setAcceleration(data);   //将电机1的加速度设置为data  
      }
      else if (stepperNum == 2){
        Serial.print(F("Motor2 'setAcceleration' "));Serial.println(data);
        stepper2.setAcceleration(data);   //将电机2的加速度设置为data   
      }
      else if (stepperNum == 0){
        Serial.print(F("Both Motors 'setAcceleration' "));Serial.println(data);
        stepper1.setAcceleration(data);   //将电机1的加速度设置为data  
        stepper2.setAcceleration(data);   //将电机2的加速度设置为data
      }break;   
    case 'x':  //设置电机在先加速后减速模式下运行的最大速度   
      if (stepperNum == 1){
        Serial.print(F("Motor1 'setMaxSpeed' "));Serial.println(data);
        stepper1.setMaxSpeed(data);   //将电机1的最大速度设置为data 
      }
      else if (stepperNum == 2){
        Serial.print(F("Motor2 'setMaxSpeed' "));Serial.println(data);
        stepper2.setMaxSpeed(data);   //将电机2的最大速度设置为data  
      }
      else if (stepperNum == 0){
        Serial.print(F("Both Motors 'setMaxSpeed' "));Serial.println(data);
        stepper1.setMaxSpeed(data);   //将电机1的最大速度设置为data  
        stepper2.setMaxSpeed(data);   //将电机2的最大速度设置为data  
      }break;  
    case 'd':  //用户通过此指令可指定哪一个电机进行工作  
      if (data == 1 || data == 2){   //指定仅控制电机1或电机2
        stepperNum = data;
        Serial.print(F("Running Motor "));Serial.println(stepperNum); 
      }
      else if (data == 0 ){   //同时控制两个电机工作
        stepperNum = data;
        Serial.println(F("Running Both Motors "));  
      }
      else {   //参数有误
        Serial.print(F("Motor Number Wrong.")); 
      }break;         
    default:  //未知指令
      Serial.println(F("Unknown Command"));
  }
}

5、Arduino驱动伺服电机

(1)AFMotor扩展板驱动舵机实际上就是通过Arduino的9号和10号引脚来驱动舵机,10号引脚对应的是扩展板上的servo1端口,9号引脚对应的是servo2端口,如下图所示(直流电源的连接这里不再赘述)。

(2)驱动舵机(伺服电机)示例程序:

#include <Servo.h>

Servo servo1;   //建立舵机对象servo1
Servo servo2;   //建立舵机对象servo2
int pos = 0;    //记录舵机轴的当前角度  

void setup() 
{
  servo1.attach(10);  //舵机1接在扩展板servo1端口,servo1端口是由Arduino的10号引脚来控制的
  servo2.attach(9);   //舵机2接在扩展板servo2端口,servo2端口是由Arduino的9号引脚来控制的
}

void loop() 
{
  for (pos = 0; pos <= 180; pos += 1){   //舵机1从0°旋转至180° 
    servo1.write(pos);delay(15);                       
  }
  for (pos = 180; pos >= 0; pos -= 1){   //舵机1从180°旋转至0° 
    servo1.write(pos);delay(15);       
  }
  
  for (pos = 0; pos <= 180; pos += 1){   //舵机2从0°旋转至180°
    servo2.write(pos);delay(15);                       
  }
  for (pos = 180; pos >= 0; pos -= 1){   //舵机2从180°旋转至0° 
    servo2.write(pos);delay(15);       
  }  
}

五、Arduino CNC电机扩展板

1、Arduino CNC电机扩展板概述

(1)Arduino CNC电机扩展板专门与Arduino开发板配合使用,如下图所示,它是直接插在Arduino开发板上的。

(2)CNC扩展板可以支持A4988、DRV8825等步进电机驱动板,这里主要介绍如何使用A4988驱动板来配合CNC扩展板使用。下图中CNC电机扩展板装配有3个A4988驱动板,实际上最多可以装配4个,具体安装多少个A4988是根据需要驱动步进电机数量来决定的,一台步进电机需要一个A4988。(安装A4988驱动板的时候注意驱动板安装方向不要搞反)

(3)每一个A4988接口上都有三组步进设置插针,这三组插针旁的电路板上印刷有M0/M1/M2,可以(且仅可以)通过在上面安置跳线帽设置电机的步进模式,如下图所示。

(4)Arduino CNC电机扩展板上配有外接直流电源接口,该接口允许接入的电压范围是12V~36V,具体应该连接多大的电源电压是根据被驱动的电机工作电压所决定的,如果使用的电机是NEMA17步进电机(42步进电机),通常该电机的工作电压是12伏特,那么可以为扩展板配一个12伏特的外接电源。

(5)用于控制电机的Arduino引脚与CNC扩展板上印刷的标识的对应关系如下所示,需要注意的是A端口比较特殊。

①Arduino引脚8 —– CNC扩展板EN(所有电机驱动板的使能引脚,低电平有效)。

②Arduino引脚5 —– CNC扩展板X.DIR(X端口方向控制引脚)。

③Arduino引脚2 —– CNC扩展板X.STEP(X端口步进控制引脚)。

④Arduino引脚6 —– CNC扩展板Y.DIR(Y端口方向控制引脚)。

⑤Arduino引脚3 —– CNC扩展板Y.STEP(Y端口步进控制引脚)。

⑥Arduino引脚7 —– CNC扩展板Z.DIR(Z端口方向控制引脚)。

⑦Arduino引脚4 —– CNC扩展板Z.STEP(Z端口步进控制引脚)。

⑧Arduino引脚13—– CNC扩展板A.DIR(A端口方向控制引脚)。

⑨Arduino引脚12—– CNC扩展板A.STEP(A端口步进控制引脚)。

(6)CNC扩展板的端口A比其它三个端口的功能要更丰富一些,它有两种工作模式。

①第一种模式是复制X、Y、Z中任意一个端口上的电机运行情况(以下简称复制模式),所谓复制模式就是端口A所接的电机完全复制其它端口上的电机运行状态,比如将端口A设置为复制端口X,那么端口A电机的运行状况将是完全复制端口X上的电机运行状况,在复制模式下,端口A电机不受Arduino开发板的程序控制而只是单纯地复制端口X电机运行。

②第二种是独立模式来控制电机,这时端口A上的电机会根据Arduino的程序控制运行,在独立模式下,端口A上安装的A4988驱动板的step引脚受Arduino的12号引脚控制,dir引脚受Arduino的13号引脚控制。

③以上两种模式的设置是通过扩展板上专门用于设置端口A工作模式的一系列插针来完成的,如下图所示。

(7)CNC扩展板的其它引脚功能介绍:

①步进电机控制插针共有两排,在插针旁印有各个引脚的名称标识,每行插针标识都使用“/”作为分割,“/”左侧的文字是图中蓝色插针的引脚标识,“/”右侧的文字是图中黄色插针的引脚标识,这些引脚的作用是便于使用Arduino开发板以外的开发板来控制CNC扩展板。

②CNC扩展板右下部分还配有两排很长的引脚插针,其中黑色的引脚全都是GND引脚,白色引脚插针旁的文字标识是这些引脚的名称,它们与Arduino的引脚是联通的,具体如下:

[1]CNC扩展板Z+引脚——Arduino引脚11。

[2]CNC扩展板Z-引脚——Arduino引脚11。

[3]CNC扩展板Y+引脚——Arduino引脚10。

[4]CNC扩展板Y-引脚——Arduino引脚10。

[5]CNC扩展板X+引脚——Arduino引脚9。

[6]CNC扩展板X-引脚——Arduino引脚9。

[7]CNC扩展板SpnEN引脚——Arduino引脚12。

[8]CNC扩展板SpnDir引脚——Arduino引脚13。

[9]CNC扩展板CoolEn引脚——Arduino引脚A3。

[10]CNC扩展板Abort引脚——Arduino引脚A0。

[11]CNC扩展板Hold引脚——Arduino引脚A1。

[12]CNC扩展板Resume引脚——Arduino引脚A2。

[13]CNC扩展板E-STOP引脚——Arduino引脚Reset。

2、Arduino CNC扩展板驱动NEMA步进电机

(1)Arduino CNC扩展板驱动1个NEMA步进电机:

①电路连接:

②示例程序:

#include <AccelStepper.h> 
 
const int xdirPin = 5;     //X端口方向控制引脚连接Arduino的引脚号为5
const int xstepPin = 2;    //X端口步进控制引脚连接Arduino的引脚号为2
const int xenablePin = 8;  //使能控制引脚连接Arduino的引脚号为8
 
const int moveSteps = 200;    //对于NEMA 17来说,全步进模式下200步转子旋转一周
 
AccelStepper stepper1(1,xstepPin,xdirPin);  //建立步进电机对象
//“1”表示该电机使用A4988电机驱动板驱动
 
void setup() 
{
  pinMode(xstepPin,OUTPUT);     //Arduino控制A4988步进引脚为输出模式
  pinMode(xdirPin,OUTPUT);      //Arduino控制A4988方向引脚为输出模式
  pinMode(xenablePin,OUTPUT);   //Arduino控制A4988使能引脚为输出模式
  digitalWrite(xenablePin,LOW); //将使能控制引脚设置为低电平,从而让电机驱动板进入工作状态
 
  stepper1.setMaxSpeed(300.0);     //设置电机运行的最大速度300 
  stepper1.setAcceleration(20.0);  //设置电机的加速度20.0  
}
 
void loop() 
{
  if (stepper1.currentPosition() == 0)
  { 
    stepper1.moveTo(moveStep);  //stepper1控制电机正向旋转1周(针对全步进模式)  
  } 
  else if (stepper1.currentPosition() == moveSteps)
  {
    stepper1.moveTo(0);          //stepper1控制电机反向旋转1周(针对全步进模式)
  }         
  
  stepper1.run();   //1号电机以先加速后减速的模式运行
}

(2)Arduino CNC扩展板驱动3个NEMA步进电机:

①电路连接:

②示例程序:

#include <AccelStepper.h>

const int xenablePin = 8;  //使能控制引脚连接Arduino的引脚号为8
const int xdirPin = 5;     //X端口方向控制引脚连接Arduino的引脚号为5
const int xstepPin = 2;    //X端口步进控制引脚连接Arduino的引脚号为2
const int ydirPin = 6;     //Y端口方向控制引脚连接Arduino的引脚号为6
const int ystepPin = 3;    //Y端口步进控制引脚连接Arduino的引脚号为3
const int zdirPin = 7;     //Z端口方向控制引脚连接Arduino的引脚号为7
const int zstepPin = 4;    //Z端口步进控制引脚连接Arduino的引脚号为4
const int moveSteps = 200;    //测试电机运行使用的运行步数
 
AccelStepper stepper1(1,xstepPin,xdirPin);  //建立步进电机对象1
AccelStepper stepper2(1,ystepPin,ydirPin);  //建立步进电机对象2
AccelStepper stepper3(1,zstepPin,zdirPin);  //建立步进电机对象3
 
void setup() 
{
  pinMode(xstepPin,OUTPUT);pinMode(xdirPin,OUTPUT);pinMode(ystepPin,OUTPUT);
  pinMode(ydirPin,OUTPUT);pinMode(zstepPin,OUTPUT);pinMode(zdirPin,OUTPUT);
  
  pinMode(enablePin,OUTPUT);
  digitalWrite(enablePin,LOW);  //将使能控制引脚设置为低电平,从而让电机驱动板进入工作状态
                                
  stepper1.setMaxSpeed(300.0);stepper1.setAcceleration(20.0);
  stepper2.setMaxSpeed(300.0);stepper2.setAcceleration(20.0);
  stepper3.setMaxSpeed(300.0);stepper3.setAcceleration(20.0);
}
 
void loop() 
{
  if (stepper1.currentPosition() == 0) 
    stepper1.moveTo(moveSteps);    //电机1正向旋转1周(针对全步进模式)        
  else if (stepper1.currentPosition() == moveSteps)
    stepper1.moveTo(0);            //电机1反向旋转1周(针对全步进模式)        
  if (stepper2.currentPosition() == 0)
    stepper2.moveTo(moveSteps/2);  //电机2正向旋转半周(针对全步进模式)      
  else if (stepper2.currentPosition() == moveSteps/2)
    stepper2.moveTo(0);            //电机2反向旋转半周(针对全步进模式)       
  if (stepper3.currentPosition() == 0)
    stepper3.moveTo(moveSteps/4); //电机3正向旋转0.25周(针对全步进模式)      
  else if (stepper3.currentPosition() == moveSteps/4)
    stepper3.moveTo(0);           //电机3反向旋转0.25周(针对全步进模式)  
  stepper1.run();stepper2.run();stepper3.run();
}

(3)Arduino CNC扩展板驱动4个NEMA步进电机:

①电路连接:

②示例程序:

#include <AccelStepper.h>

const int xenablePin = 8;  //使能控制引脚连接Arduino的引脚号为8
const int xdirPin = 5;     //X端口方向控制引脚连接Arduino的引脚号为5
const int xstepPin = 2;    //X端口步进控制引脚连接Arduino的引脚号为2
const int ydirPin = 6;     //Y端口方向控制引脚连接Arduino的引脚号为6
const int ystepPin = 3;    //Y端口步进控制引脚连接Arduino的引脚号为3
const int zdirPin = 7;     //Z端口方向控制引脚连接Arduino的引脚号为7
const int zstepPin = 4;    //Z端口步进控制引脚连接Arduino的引脚号为4
const int adirPin = 13;    //A端口方向控制引脚连接Arduino的引脚号为13
const int astepPin = 12;   //A端口步进控制引脚连接Arduino的引脚号为12
const int moveSteps = 200;
 
AccelStepper stepper1(1,xstepPin,xdirPin); //建立步进电机对象1
AccelStepper stepper2(1,ystepPin,ydirPin); //建立步进电机对象2
AccelStepper stepper3(1,zstepPin,zdirPin); //建立步进电机对象3
AccelStepper stepper4(1,astepPin,adirPin); //建立步进电机对象4

void setup() 
{
  pinMode(xstepPin,OUTPUT);pinMode(xdirPin,OUTPUT);
  pinMode(ystepPin,OUTPUT);pinMode(ydirPin,OUTPUT);
  pinMode(zstepPin,OUTPUT);pinMode(zdirPin,OUTPUT);
  pinMode(astepPin,OUTPUT);pinMode(adirPin,OUTPUT);
  
  pinMode(enablePin,OUTPUT);digitalWrite(enablePin,LOW);

  stepper1.setMaxSpeed(300.0);stepper1.setAcceleration(20.0);
  stepper2.setMaxSpeed(300.0);stepper2.setAcceleration(20.0);
  stepper3.setMaxSpeed(300.0);stepper3.setAcceleration(20.0);
  stepper4.setMaxSpeed(300.0);stepper4.setAcceleration(20.0); 
}
 
void loop() 
{
  if (stepper1.currentPosition() == 0) stepper1.moveTo(moveSteps);              
  else if (stepper1.currentPosition() == moveSteps) stepper1.moveTo(0);       
  if (stepper2.currentPosition() == 0) stepper2.moveTo(moveSteps/2);              
  else if (stepper2.currentPosition() == moveSteps/2) stepper2.moveTo(0);  
  if (stepper3.currentPosition() == 0) stepper3.moveTo(moveSteps/4);              
  else if (stepper3.currentPosition() == moveSteps/4) stepper3.moveTo(0);  
  if (stepper4.currentPosition() == 0) stepper4.moveTo(moveSteps/8);              
  else if (stepper4.currentPosition() == moveSteps/8) stepper4.moveTo(0); 
  stepper1.run();stepper2.run();stepper3.run();stepper4.run();
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/723528.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

《EDA技术》同步十三进制计数器实验报告

摘要&#xff1a; 本实验通过Multsim和Quartus软件完成对同步十三进制计数器的仿真&#xff0c;运用Quartus软件编VHDL程序&#xff0c;实现波形图的生成&#xff0c;并且运用Multsim软件进行电路图仿真。同时&#xff0c;加深 对数字电路和VHDL语言的理解&#xff0c;提高实验…

2024 年 Python 基于 Kimi 智能助手 Moonshot Ai 模型搭建微信机器人(更新中)

注册 Kimi 开放平台 Kimi&#xff1a;https://www.moonshot.cn/ Kimi智能助手是北京月之暗面科技有限公司&#xff08;Moonshot AI&#xff09;于2023年10月9日推出的一款人工智能助手&#xff0c;主要为用户提供高效、便捷的信息服务。它具备多项强大功能&#xff0c;包括多…

04 Pytorch tensor

一&#xff1a;老版本的 variable 二&#xff1a;新版 tensor 曾经&#xff1a;求导相关 如今&#xff1a;数据相关 –dtype: 张量的数据类型&#xff0c;三大类&#xff0c;共9种。torch.FloatTensor, torch.cuda.FloatTensor –shape: 张量的形状。如&#xff1a;&#x…

k8s学习--Kruise Rollouts 基本使用

文章目录 Kruise Rollouts简介什么是 Kruise Rollouts&#xff1f;核心功能 应用环境一、OpenKruise部署1.安装helm客户端工具2. 通过 helm 安装 二、Kruise Rollouts 安装2. kubectl plugin安装 三、Kruise Rollouts 基本使用(多批次发布)1. 使用Deployment部署应用2.准备Roll…

[Cloud Networking] SPDY 协议

文章目录 1. 背景2. SPDY 之前3. SPDY 项目目标4. SPDY 功能特点4.1 SPDY基本功能4.2 SPDY高级功能 1. 背景 TCP是通用的、可靠的传输协议&#xff0c;提供保证交付、重复抑制、按顺序交付、流量控制、拥塞避免和其他传输特性。 HTTP是提供基本请求/响应语义的应用层协议。 不…

网格布局之重复轨道

网格布局之重复轨道 欢迎关注&#xff1a;xssy5431 小拾岁月 参考链接&#xff1a;https://mp.weixin.qq.com/s/FQboZRMhdOFWqVDZ5JScDg 点击查看 使用场景 在网页开发中&#xff0c;我们尝尝会遇到宫格布局&#xff0c;比如&#xff1a;3 * 3&#xff0c;4 * 4布局等等。 …

6月19日(周三)A股行情总结:A股震荡收跌,恒生科技指数大涨3%,10年期国债期货转涨续创新高

内容提要 车路云概念延续昨日涨势&#xff0c;华铭智能20CM 3连板。贵金属及PEEK材料概念全日走强&#xff1b;港股有色金属及能源股走强&#xff0c;紫金矿业涨超3%&#xff0c;中石油涨超3%。国债期货午后全线转涨&#xff0c;10年期主力合约涨0.05%报104.925元&#xff0c;…

7zip安装后压缩包图标显示空白解决办法

记录安装7zip软件后&#xff0c;出现了如下的图标是空白的问题: &#xff08;虽然我最终解决了但是我不确定是哪一步起的作用&#xff0c;但是我也懒得再情景复现了。&#xff09; 我的解决过程是&#xff1a; 在开始菜单栏搜索“7zip ”然后点击“打开。 然后点击 &#xf…

HTTP!!!

HTTP 一 : 请求报文1.2 : 首行1.3 :请求头(header)1.4 : 空行1.5 : 正文 body 二: 响应报文2.2 : 首行 三 : URL 一 : 请求报文 一个HTTP 请求报文, 分成四个部分 首行 GET https://cn.bing.com/?FORMZ9FD1 HTTP/1.1请求头(header)空行正文(body) 1.2 : 首行 首行又分为三个…

CobaltStrike后渗透进阶篇

0x01 网络钓鱼攻击 钓鱼攻击简介 钓鱼攻击主要通过生成的木马诱使受害者运行后上线&#xff0c;其中木马一般都伪装成正常的程序。与此同时配合钓鱼网站可帮助攻击者模拟真实网站诱骗受害者访问&#xff0c;达到获取账号密码、上线木马等目的。接下来主要介绍后门程序的生成及…

自动化测试接口测试前的【准备及思路】

1、什么是接口测试 客户端&#xff08;前端&#xff09;与服务端&#xff08;后端&#xff09;的关系&#xff0c;一般小编会理解为“服务端负责赚钱养家&#xff0c;客户端负责貌美如花”。客户端更注重的是功能呈现及用户体验&#xff0c;怎么将强大的功能精彩的界面呈现给不…

云上战场:ToDesk云电脑、青椒云、顺网云全面对决

前言 记得端午放假期间&#xff0c;我已经在旅游的路上了&#xff0c;老板突然发短信&#xff0c;让我给他画个图&#xff0c;我手上的战斗机已经是十年前的老古董了(平常一直用的公司电脑&#xff0c;也没想过要换)&#xff0c;压根满足不了老板的任务要求&#xff0c;不得已&…

系统之家教你安装最新Win10 22H2版本!一看就会!

当前很多用户办公或学习都喜欢使用Win10系统&#xff0c;但很多新手用户不知道怎么操作才能安装上最新的Win10 22H2版本&#xff1f;接下来系统之家小编就给大家带来最简单的安装方法&#xff0c;帮助大家轻松快速给电脑安装上Win10系统最新版本22H2&#xff0c;体验22H2版本带…

Footer组件在home 、search 显示,在登录、注册隐藏

footer组件显示与隐藏 我们可以根据组件身上的$route获取当前路由的信息&#xff0c;通过路由路径判断Footer显示与隐藏。配置的路由的时候&#xff0c;可以给路由添加路由元信息【meta】&#xff0c;路由需要配置对象&#xff0c;它的key不能瞎写、胡写、乱写 <template&…

Python网络爬虫4-实战爬取pdf

1.需求背景 爬取松产品中心网站下的家电说明书。这里以冰箱为例&#xff1a;松下电器-冰箱网址 网站分析&#xff1a; 第一步&#xff1a; 点击一个具体的冰箱型号&#xff0c;点击了解更多&#xff0c;会打开此型号电器的详情页面。 第二步&#xff1a;在新打开的详情页面中…

N7745A Keysight 是德 多端口光功率计 简述

N7745A光功率计专为表征多端口光器件而设计&#xff0c;适用于多路复用器、PON分路器、波长选择开关&#xff08;WSS&#xff09;和ROADM等多端口器件的测试。它可以节省通道空间&#xff0c;通过LAN或USB连接进行并行编程&#xff0c;集成多种设备到单一设置&#xff0c;提高了…

用Vue3和ApexCharts打造交互式3D折线图

本文由ScriptEcho平台提供技术支持 项目地址&#xff1a;传送门 Vue.js 中使用 ApexCharts 构建交互式折线图 应用场景 ApexCharts 是一个功能强大的 JavaScript 库&#xff0c;用于创建交互式、可定制的图表。在 Vue.js 中&#xff0c;它可以通过 vue3-apexcharts 插件轻松…

JavaFX HTMLEditor

HTMLEditor控件是一个富文本编辑器&#xff0c;具有以下功能。 粗体斜体下划线删除线字体系列字体大小前景色背景颜色缩进项目符号列表编号列表对齐水平线复制文本片段粘贴文本片段 HTMLEditor类返回HTML字符串中的编辑内容。 创建HTML编辑器 import javafx.application.App…

docker安装使用

文章目录 docker产生的原因传统虚拟机容器化技术 docker组成安装docker镜像加速docker安装过程中遇到的问题以及解决办法Errors during downloading metadata for repository root_:Failed to set locale, defaulting to C.UTF-8 docker产生的原因 传统虚拟机 在不使用docker…

《Linux运维总结:基于ARM64架构CPU使用docker-compose一键离线部署alertmanager v0.27.0高可用集群》

总结&#xff1a;整理不易&#xff0c;如果对你有帮助&#xff0c;可否点赞关注一下&#xff1f; 更多详细内容请参考&#xff1a;《Linux运维篇&#xff1a;Linux系统运维指南》 一、部署背景 由于业务系统的特殊性&#xff0c;我们需要面对不同的客户部署业务系统&#xff0…