文章目录[隐藏]
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-D13
、A0-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 引脚定义图及功能说明
-
VMOT
、GND
:外部供电引脚,目的是能给电机提供足够的动力输出,供电范围:8-35V,此处使用一个47uf
的电解电容来保护驱动板免受瞬时电压的冲击。 -
VDD
和GND
:连接到Arduino控制板的5V电源
和GND
引脚上。 -
1A
和1B
: 连接到步进电机的一相,2A
和2B
引脚连接到步进电机的另一相。 -
STEP
和DIR
: 连接至Arduino控制板的P3
和P4
引脚,这两个针脚主要用于控制电机的运动。Direction引脚控制转动方向,STEP针脚用于控制电机旋转的步数控制。 -
SLEEP
: 低电平使能使模块处于休眠模式,当电机不工作时,它可以最大程度地降低功耗,默认为高电平。 -
RESET
: 如果这个针脚的输入是低电平,那么所有的微步设置都将被忽略掉。
注意: 将SLEEP和RESET针脚连接起来,目的是将RESET针脚设置为高电平,以便模块可控。
-
ENABLE
:用于打开和关闭场效应管的输出,低电平打开,高电平关闭。
-
MS1
,MS2
和MS3
针脚用于微步设置。- 全步(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
, MS2
和 MS3
针脚拉高,微步设置为 1/16步进( HIGH HIGH HIGH)。
2、将SLEEP
和RESET
针脚连接起来,目的是将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 机械回零 限位开关、传感器等硬件原点识别器。
参考资料
- [1] 三端稳压集成电路 LM7805/LM7809 (LM78xx正电压LM79xx负电压系列)
- [2] L298N 电机驱动 (电机驱动板L298N的针脚定义)
- [3] FR207 损耗二极管
- [4] A4988 步进电机驱动模块 (A4988的引脚图及运用)(Arduino+A4988+步进电机)
- [5] 模型三维图、框架图、电路原理图、PCB图和代码
代码
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
暂无评论