Arduino 项目笔记 | 基于 Arduino 单片机的 A4988 和 L298N电机驱动模块实验记录


1. Arduino Nano 简介

Arduino Nano 是一款基于 ATmega328 (Arduino Nano 3.x) 的小型、完整且适合面包板的开发板。它或多或少具有与 Arduino Duemilanove 相同的功能,但采用不同的封装。它只缺少一个 DC 电源插孔,可以使用 Mini-B USB 电缆而不是标准的 USB 电缆。

2. 技术规格

微控制器ATmega328、工作电压5V、闪存32 KB 其中 2 KB 由引导加载程序使用、静态随机存取存储器2KB、时钟速度16MHZ、模拟输入引脚8个(A0~A7)、掉电可擦可编程只读存储器EEPROM1KB、每个 I/O 引脚的直流电流40mA、输入电压7V-12V、数字 I/O 引脚22个 (D0-D13A0-A7)、脉宽调制输出6个 (D3 D5 D6 D9 D10 D11)以及 功耗19mA

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3. 输入和输出

Nano 上的 14 个数字引脚中的每一个都可以用作输入或输出,使用 pinMode()digitalWrite()digitalRead() 函数。它们的工作电压为 5V。每个引脚最多可提供或接收 40 mA电流,并具有 20-50 kOhms 的内部上拉电阻(默认断开连接)。此外,有些引脚还具有专门的功能:

  • 串行:0 (RX) 和 1 (TX)。用于接收(RX)和发送(TX)TTL串行数据。这些引脚连接到 FTDI USB-to-TTL 串行芯片的相应引脚。
  • 外部中断:2 和 3。这些引脚可配置为在低值、上升沿或下降沿或值变化时触发中断。有关详细信息,请参阅 attachInterrupt() 函数。
  • PWM:3、5、6、9、10、11。通过analogWrite()函数提供8位PWM输出。
  • SPI:10 (SS)、11 (MOSI)、12 (MISO)、13 (SCK)。这些引脚支持 SPI 通信,虽然由底层硬件提供,但目前不包含在 Arduino 语言中。
  • LED:13。有一个内置LED连接到数字引脚13。当引脚为HIGH值时,LED点亮,当引脚为LOW时,它熄灭。

Nano 有 8 个模拟输入,每个输入提供 10 位分辨率(即 1024 个不同的值)。默认情况下,它们的测量范围是从地到 5 伏,但是否可以使用analogReference() 函数更改其范围的上限。模拟引脚 6 和 7 不能用作数字引脚。此外,一些引脚具有特殊功能:

  • I2C:A4 (SDA) 和 A5 (SCL)。使用 Wire 库(Wiring 网站上的文档)支持 I2C (TWI) 通信。
    板上还有几个其他引脚:

  • 模拟输入的参考电压。与analogReference() 一起使用。

  • 重启(也可以软件重置)。将此线置于低电平以重置微控制器。通常用于在屏蔽板上添加一个重置按钮来阻挡板上的那个。

1. A4988 简介

A4988是一款完整的 微步电机驱动器,内置转换器,它设计用于以全步、半步、四分之一步、八分之一步和十六分之一步模式操作双极步进电机,输出驱动能力高达35V和±2A电流。A4988包括一个固定的关闭时间电流调节器,能够在慢速或混合衰减模式下工作。

A4988 内置了 译码器,我们可以可以通过控制器的 2 个引脚来控制步进电机,一个控制旋转方向,另一个控制步数。

A4988 提供了五种不同的微步控制:

  • 全步(full-step)
  • 半步(haft-step)
  • 四分一步(quarter-step)
  • 八分之一步(eight-step)
  • 十六分之一步(sixteenth-step)

在这里插入图片描述

此外,它还配备了一个调节电流输出、过热保护和过流保护的 电位计。A4988 的逻辑电压范围是:3~5.5V,如果配备较好的散热条件每相最大电流可达 2A,在没有配备散热器的情况下,每相连续电流最好控制在 1A 范围内。

2. A4988 引脚定义图及功能说明

  • VMOTGND外部供电引脚,目的是能给电机提供足够的动力输出,供电范围:8-35V,此处使用一个47uf电解电容来保护驱动板免受瞬时电压的冲击。

  • VDDGND:连接到Arduino控制板5V电源GND引脚上。

  • 1A1B : 连接到步进电机的一相,2A2B引脚连接到步进电机的另一相。

  • STEPDIR : 连接至Arduino控制板P3P4引脚,这两个针脚主要用于控制电机的运动。Direction引脚控制转动方向,STEP针脚用于控制电机旋转的步数控制。

  • SLEEP低电平使能使模块处于休眠模式,当电机不工作时,它可以最大程度地降低功耗,默认为高电平

  • RESET : 如果这个针脚的输入是低电平,那么所有的微步设置都将被忽略掉。

注意: 将SLEEP和RESET针脚连接起来,目的是将RESET针脚设置为高电平,以便模块可控。

  • ENABLE:用于打开和关闭场效应管的输出,低电平打开高电平关闭
    在这里插入图片描述

  • MS1 , MS2MS3 针脚用于微步设置。

    • 全步(full-step)
    • 半步(haft-step)
    • 四分一步(quarter-step)
    • 八分之一步(eight-step)
    • 十六分之一步(sixteenth-step)

    如下图所示:

步进电机全步模式走 1 步是 1.8 度,一圈360° 就是 200 步;若使用 1/16 步进,1 步是 0.1125 度,一圈360° 则需要走 3200 步。

在这里插入图片描述

实际电路设计中,Arduino 引脚设置如下:

1、 电路中通过跳帽(连接器 J1)将 MS1 , MS2MS3 针脚拉高,微步设置为 1/16步进( HIGH HIGH HIGH)。

2、将SLEEPRESET针脚连接起来,目的是将RESET针脚设置为高电平,以便模块可控

3、200Ω 电阻将A1引脚拉低

在这里插入图片描述

(四相步进电机)

对于两相双极混合型步进电机它有四根引出线,通过用万用表测量会得出,其中红色线和蓝色线是阻值较小,它们是同一个绕组。

同样绿色线和黑色线阻值较小,它们俩也是同一绕组。接线时,只要把同一绕组的步进电机的驱动器上相应输出端子上,比如上图中的A+和A-接在同一个绕组上,B+和B-接在另一个绕组上即可。

接好后开机试车,如果转向与我们的要求不一样,只要把A+、A-和B+、B-对调就可以了。

在这里插入图片描述

在示意图上用A-B-C-D来标注。因此这种步进电机就叫“四相”步进电机。

假设先B相绕组闭合导通,这样就会在所对应的定子绕组齿上产生磁极,此时转子的“0”号和“3”号离它们最近,这样就会产生最强的吸引力。

如果按照B相-C相-D相-A相的顺序给步进电机的绕组通电的话,这样步进电机的转子就会按照逆时针的方向不停地运转。

通过分析可以知道,只要给步进电机的电子绕组输入一序列的电脉冲信号,那么步进电机的转子就会不停地转动一个角度,这就是步进电机名称的由来。

1B-1A-2A-2B
绿-红-黄-蓝

3. Arduino使用A4988控制电机代码

// Arduino使用A4988控制电机代码

#define Dir1pin   A0
#define Step1pin  A1
#define Enablepin 12
#define MSmodoule 3200

int x;   

void setup()  
{  
  pinMode(Enablepin,OUTPUT); // Enable  
  pinMode(Step1pin,OUTPUT); // Step  
  pinMode(Dir1pin,OUTPUT); // Dir  
  digitalWrite(Enablepin,LOW); // Set Enable low  
}  
void loop()  
{      
  digitalWrite(Dir1pin,HIGH); // Set Dir high  
   
  for(x = 0; x < MSmodoule; x++) // Loop 200 times  
  {  
      digitalWrite(Step1pin,HIGH); // Output high  
      delayMicroseconds(800); // Wait 1/2 a ms  
      digitalWrite(Step1pin,LOW); // Output low  
      delayMicroseconds(800); // Wait 1/2 a ms  
    }  
  delay(1000); // pause one second  
    
  digitalWrite(Dir1pin,LOW); // Set Dir low  
    
  for(x = 0; x < MSmodoule; x++) // Loop 2000 times  
  {  
      digitalWrite(Step1pin,HIGH); // Output high  
      delayMicroseconds(800); // Wait 1/2 a ms  
      digitalWrite(Step1pin,LOW); // Output low  
      delayMicroseconds(800); // Wait 1/2 a ms  
    }  
    delay(1000); // pause one second  
}  

总 结:

1、D12 (-en) 低电平启动电机(enable),貌似也可以不接,试过一样能运行(但如果要控制电机的启动关闭还是要用上);

2、A0(-dir) 用高低电平控制方向

3、A1(-step) 用高低电平 驱动电机转动,注意中间间隔等待的微秒值,如果太快会导致电机有声响不转动。


1. L298N 简介

L298N 是专用驱动集成电路,属于H桥集成电路,与 L293D 的差别是起输出电流增大,功率增强。

其输出电流为 2A ,最高电流 4A,最高工作电压50V,可以驱动感性负载,如大功率直流电机,步进电机,电磁阀等等,特别是其输入端可以与单片机直接相连,从而很方便地受单片机控制。

当驱动直流电机时,可以直接控制步进电机,并可以实现电机的正转和反转,实现此功能只需要改变输入端的逻辑电平。为了避免电机对单片机的干扰,本模块加入光耦,进行光电隔离 (光耦合器以光为媒介传输电信号,它对输入、输出电信号有良好的隔离作用)、整流二极管电机保护、从而使系统能够稳定可靠的工作。

4 通道控制、钽(tǎn)电容稳压、光耦隔离、整流二极管电机保护、过流保护、合金散热片、数模电路线路分离、电机电流反馈和PWM调速,电机双闭环控制。

在这里插入图片描述

2. L298N 外观尺寸和针脚定义

在这里插入图片描述

  • Output A:接DC 电机 1 或步进电机的 A+和 A-;

  • Output B:接DC 电机 2 或步进电机的 B+和 B-;

  • 5V Enable:输入电源小于12V时短接可以提供5V电源输出,如果使用输入电源大于12V的电源,请将跳线帽移除;

  • +5V Power:当输入电源小于12V时且5V Enable处于短接状态,可以提供+5V电源输出(实际位置请参考驱动板上的标注);

  • Power Gnd:电源

  • +12V Power:连接电机电源,最大35V。输入电压大于12V时,为确保安全,请去除 5V Enble 针脚上的跳线帽(实际位置请参考驱动板上的标注);

  • A/B Enble:可用于输入PWM脉宽调制信号对电机进行调速控制。(如果无须调速可将两引脚接5V,使电机工作在最高速状态,既将短接帽短接)

实现电机正反转功能:

电机M1正转,输入信号端IN1接高电平输入端IN2接低电平。(如果信号端IN1接低电平, IN2接高电平,电机M1反转。)

电机M2正转,输入信号端IN3接高电平,输入端IN4接低电平。(反之则反转)

PWM信号端A控制M1调速,PWM信号端B控制M2调速。可参考下图表:
在这里插入图片描述

实际电路设计中,Arduino 引脚设置如下:

在这里插入图片描述
在这里插入图片描述

3. Arduino使用L298N 控制电机代码

#define In1pin 7
#define In2pin 8
#define Speedpin  9
#define asingle A6
#define Step  A1
#define Dir   A0
#define Enable  12
#define setstep  400            // 1/2步模式 一圈 步长400
#define nw_step  setstep * 1.7  // 400 x 1.7 = 680步
#define delayM   600            // 延时微秒
int x;
void setup()
{
  pinMode(Enable,OUTPUT); 
  pinMode(Step,OUTPUT); 
  pinMode(Dir,OUTPUT); 
  digitalWrite(Enable,LOW); 
  Serial.begin(9600);
  pinMode(In1pin, OUTPUT);
  pinMode(In2pin, OUTPUT);
  pinMode(Speedpin, OUTPUT);
  pinMode(asingle, INPUT);
  digitalWrite(In1pin,HIGH); 
  digitalWrite(In2pin,LOW); 
  analogWrite(Speedpin,200);
}
void(* resetFunc) (void) = 0; //制造重启命令

void DCMOTOR_RUN(){
  digitalWrite(In1pin,HIGH); 
  digitalWrite(In2pin,LOW); 
  analogWrite(Speedpin,200);
  }
void DCMOTOR_STOP(){ 
  digitalWrite(In1pin,LOW); 
  digitalWrite(In2pin,LOW); 
  analogWrite(Speedpin,0);
  }
void STEP_F(){        
  digitalWrite(Dir,HIGH); 
  for(x = 0; x < setstep; x++) 
  {
      digitalWrite(Step,HIGH); 
      delayMicroseconds(delayM); 
      digitalWrite(Step,LOW); 
      delayMicroseconds(delayM);
      if(!(10000<=millis() && millis()<=20000)){break;}
    }}
void STEP_B(){         
   digitalWrite(Dir,LOW); 
   for(x = 0; x < setstep; x++) 
   {   digitalWrite(Step,HIGH); 
       delayMicroseconds(delayM); 
       digitalWrite(Step,LOW);
       delayMicroseconds(delayM); 
       if(!(25000<=millis() && millis()<=35000)){break;}
     }}
void STEP_CONTROL(){


}
 
void loop()
{ 
  DCMOTOR_RUN();                        // 直流电机转动
  int val = analogRead(asingle);
  val = map(val,0,1023,0,255);
  Serial.print("A6类比信号为:");Serial.println(val);
  Serial.print("millis()为:");Serial.println(millis()); // 内部计数器
  while(1){
    if(10000<=millis() && millis()<=20000)
    {      DCMOTOR_STOP(); STEP_F();      }
    else if(25000<=millis() && millis()<=35000)
     {     DCMOTOR_STOP(); STEP_B();     }
    else if(10000<=millis()&& millis()<=35000)
    {      DCMOTOR_STOP();      } // 直流电机停止
     else{break;}
}
  if (millis() >= 40000)
  { // 复位函数 重置程序
    resetFunc();
  }
  //STEP_CONTROL();
}

总 结

1、步进电机接线问题。

通过用万用表测量会得出,其中红色线和绿色线是阻值较小,它们是同一个绕组。同样黄色线和蓝色线阻值较小,它们俩也是同一绕组。
在这里插入图片描述

A4988模块脚位 步进电机线颜色
1B-1A-2A-2B 绿-红-黄-蓝

2、为什么步进电机老是振动?

步进电机振动

原因1:线接错了

原因2:高速振动,低速振动

解决办法:减小步距角
在这里插入图片描述
3、为什么当while不满足语句条件的时候依然循环?

不要使用

while (条件)

更不要使用

while (组合条件)

要使用


while (1) {
if (条件1) break;
//...
if (条件2) continue;
//...
if (条件3) return;
//...
}

原因:因为前两种写法在语言表达意思的层面上有二义性,只有第三种才忠实地反映了程序流的实际情况

4、if (条件) 中的运算符问题

  if(10<=count && count<=20){} // C语言判断条件的语法格式与Python区分开
  if(10<=count<=20){} // Python

5、Arduino定时计数器 (计数器)0、1、2的灵活使用
(参考文章:Arduino定时计数器 0、1、2的灵活使用)

6、如何在不用Arduino板上的复位按钮 Reset的情况下 让程序重启?使 millis()函数 重新计数?

Arduino有一个名为resetFunc()的内置函数,声明函数地址为0,当我们执行此功能时,Arduino将自动重启。

void(* resetFunc) (void) = 0; //制造重启命令
  if (millis() >= 40000)
  { // 复位函数 重置程序
    resetFunc();
  }

7、步进电机如何断电开机时复位到原点?

方法一:

记录驱动脉冲数,存储在EEPROM中,步进电机开机读取数值判断是否复位到原点。

缺点:有累加误差

方法二:

endstop 机械回零 限位开关、传感器等硬件原点识别器。

在这里插入图片描述


参考资料

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述


代码

2021.12.10

#define In1pin 7
#define In2pin 8
#define In3pin 10
#define In4pin 11
#define Speedpin  9
#define asingle A6
#define Step  A1
#define Dir   A0
#define Enable  12
#define setstep  1600            // 全步模式 一圈 步长200
#define nw_step  setstep * 1.7  // 400 x 1.7 = 680步
#define delayM   800            // 延时微秒
int endstoppin = 4;            // 机械限位 回零

int x;
void setup()
{
  pinMode(endstoppin,INPUT);
  pinMode(Enable,OUTPUT); 
  pinMode(Step,OUTPUT); 
  pinMode(Dir,OUTPUT); 
  digitalWrite(Enable,LOW); 
  Serial.begin(9600);
  pinMode(In1pin, OUTPUT);
  pinMode(In2pin, OUTPUT);
  pinMode(In3pin, OUTPUT);
  pinMode(In4pin, OUTPUT);
  pinMode(Speedpin, OUTPUT);
  pinMode(asingle, INPUT);
//  digitalWrite(In1pin,HIGH); 
//  digitalWrite(In2pin,LOW); 
  analogWrite(Speedpin,255);
  while(1){
   digitalWrite(Dir,LOW); 
   for(x = 0; x < setstep; x++) 
   {   digitalWrite(Step,HIGH); 
       delayMicroseconds(delayM); 
       digitalWrite(Step,LOW);
       delayMicroseconds(delayM); 
       //Serial.print("digitalRead(D4)为:");
       //Serial.println(digitalRead(endstoppin)); 
       if(digitalRead(endstoppin) == 0){break;}
     }
    //STEP_B(); // 电机原点复位
    if (digitalRead(endstoppin) == 0){break;}
  }
}
void(* resetFunc) (void) = 0; //制造重启命令

void DCMOTOR_RUN(){
  digitalWrite(In1pin,HIGH); 
  digitalWrite(In2pin,LOW); 
//  analogWrite(Speedpin,200);
  }
void DCMOTOR_STOP(){ 
  digitalWrite(In1pin,LOW); 
  digitalWrite(In2pin,LOW); 
//  analogWrite(Speedpin,0);
  }
void DCMOTOR2_DOWN(){
  digitalWrite(In3pin,HIGH); 
  digitalWrite(In4pin,LOW); 
//  delay(1000);
//  digitalWrite(In3pin,LOW); 
//  digitalWrite(In4pin,LOW); 
  }

void DCMOTOR2_UP(){
//  digitalWrite(In3pin,LOW); 
//  digitalWrite(In4pin,HIGH); 
//  delay(1000);
  digitalWrite(In3pin,LOW); 
  digitalWrite(In4pin,LOW); 
  delay(1000);
  }
void STEP_F(){        
  digitalWrite(Dir,HIGH); 
  for(x = 0; x < setstep; x++) 
  {
      digitalWrite(Step,HIGH); 
      delayMicroseconds(delayM); 
      digitalWrite(Step,LOW); 
      delayMicroseconds(delayM);
//      if(!(10000<=millis() && millis()<=20000)){break;}
    }}
void STEP_B(){         
   digitalWrite(Dir,LOW); 
   for(x = 0; x < setstep; x++) 
   {   digitalWrite(Step,HIGH); 
       delayMicroseconds(delayM); 
       digitalWrite(Step,LOW);
       delayMicroseconds(delayM); 
//       if(!(25000<=millis() && millis()<=35000)){break;}
     }}
void STEP_CONTROL(){


}
 
void loop()
{ 
//  DCMOTOR_RUN();                        // 直流电机转动
//  int val = analogRead(asingle);
//  val = map(val,0,1023,0,255);
//  Serial.print("A6类比信号为:");Serial.println(val);
//  Serial.print("millis()为:");Serial.println(millis()); // 内部计数器
  while(1){
    if(10000<=millis() && millis()<=15000)
    {      DCMOTOR_STOP(); 
           STEP_F();  
    }
    else if(16000<=millis() && millis()<=17000){
           DCMOTOR_STOP(); 
           DCMOTOR2_UP(); 
           }
    else if(19000<=millis() && millis()<=23000)
     {      STEP_B();     }
    else if(10000<=millis()&& millis()<=23000)
    {      DCMOTOR_STOP();      } // 直流电机停止
     else{    
      DCMOTOR_RUN();     // 直流电机转动
      DCMOTOR2_DOWN();   //电磁铁通电吸附
      break;}
}
  if (millis() >= 30000)
  { // 复位函数 重置程序
    resetFunc();
  }
  //STEP_CONTROL();
  //delay(1000);
}

版权声明:本文为CSDN博主「Naiva」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/Naiva/article/details/121376364

生成海报
点赞 0

Naiva

我还没有学会写个人说明!

暂无评论

发表评论

相关推荐

七、Arduino 串口的使用

Arduino与计算机通信最常用的方式就是串口通信 我们使用USB线连接Arduino Uno与计算机时,Arduino Uno会在计算机上虚拟出一个串口设备,此时两者之间便建立了串口连接。通过此连接,

Arduino与Proteus仿真实例-DHT11温度湿度传感器驱动仿真

DHT11温度湿度传感器驱动仿真 DHT11 是一款基本的超低成本数字温度和湿度传感器。 它使用电容式湿度传感器和热敏电阻来测量周围的空气,并在数据引脚上吐出数字信号(不需要模拟输入引脚)。 它使用起来相当简单,但需要仔细定时来抓取数据。

Arduino使用Esp32-cam开发版

首先你需要先准备一些硬件 1、Esp32-Cam开发版 2、TY-OV2640-v2.0摄像头 3、烧录底座,可以用USB-TTL,我用的是Esp8266的烧录底座 4、杜邦线母线x5,颜色不做要求 开始填坑 贴个大