文章目录
日常·唠嗑
3月份在做智能剥壳机的时候,就遇到了丝杠问题。想着通过挤压的方式把坚果的外壳压碎,但那时候对丝杠原理还不是很理解,最后不了了之。现在省电,需要给车子做一个升降台,再一次回到了曾经没有攻克的难题……
一、双线轨丝杆式升降
双线轨丝杆式升降一般由步进电机,T8丝杆,联轴器,上下轴承片,导轨及轴承座组成。这种组合,一般承重能力强,精度高。多用于3D打印机或者高精度机床等等。(汽修厂升降的升降机与这个结构也有异曲同工之妙)双线轨丝杆式升降台如下图所示:
某宝的上的配套升降台(有效行程1米)价格一般在400左右,较为昂贵,但是性能稳定,无需经过多次调试就可以直接用。我做的项目,升降距离不需要太长,且要求整个机构体积较小,所以我利用零件自己组装。
T8丝杆:
42步进电机(6线):
A4988驱动模块:
联轴器:
成果图: 有点丑,不过还好经过多次测试能用。
二、42步进电机
1、常见问题
初次接触步进电机肯定会有很多疑问,比如4线步进电机与6线步进电机的差别,该如何接线,步进电机的电压该怎么解决,12V可以吗(第一次接触,我朋友跟我说,电机功率很大,90W,并且电压要30V,比赛要带上电源器,我当场人就傻),像我第一次接触就一直在纠结用什么驱动模块(当时我了解的就只有TB6600,可是这东西太大了啊),后来了解到了拇指大的A4988一样可以实现驱动。
2.型号参数
(42BYGH) 两相四线步进电机,步距角为 1.8 °, 200 个脉冲转动一圈。(这个参数很重要!!!下面写程序需要用到)下图为电机与模块接线(这个图是与Arduino接线,但是与别的板卡接线是一样的):
三、A4988驱动模块
A4988 是一款带转换器和过流保护的 DMOS 微步驱动器,该产品可在全、半、1/4、1/8 及 1/16 步进模式时操作双极步进电动机,输出驱动性能可达 35 V 及 ±2 ,A4988 包括一个固定关断时间电流稳压器,该稳压器可在慢或混合衰减模式下工作。转换器是 A4988 易于实施的关键。只要在“步进”输入中输入一个脉冲,即可驱动电动机产生微步。无须进行相位顺序表、高频率控制行或复杂的界面编程。A4988 界面非常适合复杂的微处理器不可用或过载的应用。
麻雀虽小五脏俱全,虽然模块只有拇指大,我对引脚做了笔记,下面看看每个引脚的名称及作用。
1、STEP 、 DIR 分别连接单片机的两个控制端口; EN 可以使用单片机端口控制,也可以直接连接 GND 使能;
2、 MS1 、 MS2 、MS3 按照上一节“步进模式设置”,接高低电平,设置步进模式,来选择不同的步距角。 设置脉冲的频率,来控制旋转速度。步进电机走一步是1.8度,一圈就是200步。例如使用1/16步进,则需要走3200步才等于一圈。
3、 2B 、2A 、 1A 、 1B 分别接步进电机红、蓝、黑、绿线。 VMOT 、 GND 接 12V
4、左右直流电源(电压大小更具步进电机不同,选择合适电压)。VDD 、 GND 接 3.3V 或 5V 。
5、 sleep,reset:通常短接;
长篇大论讲了一堆,主要是想让大家看懂这个模块的具体功能。但是实际运用中,如果,不是特别精细的控制,可以直接选择全步进的工作方式(MS1,MS2,MS3,三个引脚全部悬空,即为全步进模式,那样的话就只要控制STEP,DIR两个引脚即可)
四、程序设计
1、C语言(51单片机)
#include"reg52.h"
#include <intrins.h>
sbit dir=P1^0;
sbit step=P1^1;
#define uint unsigned int
void Delay_xms(uint x);
void Delay1000us() //@11.0592MHz
{
unsigned char i, j;
_nop_();
i = 2;
j = 199;
do
{
while (--j);
} while (--i);
}
void Delay_xms(uint x)
{
uint i,j;
for(i=0;i<x;i++)
for(j=0;j<112;j++);
}
void main()
{
uint x,y;
dir=1;//电机正转
for( y = 0; y<6; y++) { //修改y值可以改变电机转的圈数
for( x = 0; x <=200; x++) { //一个圈200个脉冲
step=1;
Delay1000us();
step=0;
Delay1000us();
}
}
Delay_xms(1500);
dir=0;//电机反转
for( y = 0; y<6; y++) {
for( x = 0; x <=200; x++) {
step=1;
Delay1000us();//时间长短会影响电机运动
step=0;
Delay1000us();
}
}
Delay_xms(1500);
2、Python(STM32)
from pyb import Pin, delay
p_dir = Pin('Y1', Pin.OUT_PP)
p_step = Pin('Y2', Pin.OUT_PP)
while True:
p_dir.high
for y in range(0, 6):
for x in range(0, 201):
p_step.high()
pyb.udelay(1000)
p_step.low()
pyb.udelay(1000)
pyb.delay(1500)
p_dir.low
for y in range(0, 6):
for x in range(0, 201):
p_step.high()
pyb.udelay(1000)
p_step.low()
pyb.udelay(1000)
pyb.delay(1500)
3、Verilog(FPGA)
module step1 (clk0,reset,out,der,x);//状态机module
input clk0,reset,der,x;
output[3:0] out;
reg[3:0] out;
reg[2:0] current;
reg[2:0] current1;
parameter s0=3'b000,s1=3'b001,s2=3'b010,
s3=3'b011,s4=3'b100,s5=3'b101,
s6=3'b110,s7=3'b111;
always@(posedge clk0 or negedge reset )
begin
if(!reset)
begin
current<=s0;
end
else
case(current)
s0:
begin
if(!der)
begin
current<=s7;
current1<=s7;
end
else
begin
current<=s1;
current1<=s1;
end
end
s1:
begin
if(!der)
begin
current<=s0;
current1<=s0;
end
else
begin
current<=s2;
current1<=s2;
end
end
s2:
begin
if(!der)
begin
current<=s1;
current1<=s1;
end
else
begin
current<=s3;
current1<=s3;
end
end
s3:
begin
if(!der)
begin
current<=s2;
current1<=s2;
end
else
begin
current<=s4;
current1<=s4;
end
end
s4:
begin
if(!der)
begin
current<=s3;
current1<=s3;
end
else
begin
current<=s5;
current1<=s5;
end
end
s5:
begin
if(!der)
begin
current<=s4;
current1<=s4;
end
else
begin
current<=s6;
current1<=s6;
end
end
s6:
begin
if(!der)
begin
current<=s5;
current1<=s5;
end
else
begin
current<=s7;
current1<=s7;
end
end
s7:
begin
if(!der)
begin
current<=s6;
current1<=s6;
end
else
begin
current<=s0;
current1<=s0;
end
end
endcase
end
always@(current1 )//or clk0
begin
case(current1)
s0:
begin
out<=4'b1001;
end
s1:
begin
out<=4'b0001;
end
s2:
begin
out<=4'b0011;
end
s3:
begin
out<=4'b0010;
end
s4:
begin
out<=4'b0110;
end
s5:
begin
out<=4'b0100;
end
s6:
begin
out<=4'b1100;
end
s7:
begin
out<=4'b1000;
end
endcase
end
endmodule
module step2 (clk1,a,adj);//分频module
input clk1;
input[5:0] adj;
output a;
reg a;
reg[25:0] cnt;
reg[15:0] counter;
wire[5:0] adj;
reg[2:0] temp;
always @(posedge clk1)
begin
temp=adj[5]+adj[4]+adj[3]+adj[2]+adj[1]+adj[0];
if(temp==3'd6)
begin
if(cnt <= 32000) cnt <= cnt+1'b1;//0.5MS 1MS 2MS 4MS 8MS 4000 8000 16000 32000 64000
else
begin
cnt <=26'b0;
a=~a;
end
end
else if(temp==3'd5)
begin
if(cnt <= 16000) cnt <= cnt+1'b1;//0.5MS 1MS 2MS 4MS 8MS 4000 8000 16000 32000 64000
else
begin
cnt <=26'b0;
a=~a;
end
end
else if(temp==3'd4)
begin
if(cnt <= 12000) cnt <= cnt+1'b1;//0.5MS 1MS 2MS 4MS 8MS 4000 8000 16000 32000 64000
else
begin
cnt <=26'b0;
a=~a;
end
end
else if(temp==3'd3)
begin
if(cnt <= 10000) cnt <= cnt+1'b1;//0.5MS 1MS 2MS 4MS 8MS 4000 8000 16000 32000 64000
else
begin
cnt <=26'b0;
a=~a;
end
end
else if(temp==3'd2)
begin
if(cnt <= 8000) cnt <= cnt+1'b1;//0.5MS 1MS 2MS 4MS 8MS 4000 8000 16000 32000 64000
else
begin
cnt <=26'b0;
a=~a;
end
end
else if(temp==3'd1)
begin
if(cnt <= 6000) cnt <= cnt+1'b1;//0.5MS 1MS 2MS 4MS 8MS 4000 8000 16000 32000 64000
else
begin
cnt <=26'b0;
a=~a;
end
end
else if(temp==3'd0)
begin
if(cnt <= 4000) cnt <= cnt+1'b1;//0.5MS 1MS 2MS 4MS 8MS 4000 8000 16000 32000 64000
else
begin
cnt <=26'b0;
a=~a;
end
end
end
endmodule
module step (clk,reset,out,der,d);//总体模块d[5:0]调速控制端口 用6个拨码开关表示 全1速度最慢 全0时速度最快 其中1(0)的个数能表示电机速度的快慢
input clk ,reset,der,d;
output [3:0]out;
wire p;
wire[5:0] d;
step2 l1 (clk,p,d);//clk系统时钟
step1 l2 (p,reset ,out,der);//reset停止转动 out[3:0]电机控制输出端口 der正反方向控制端
endmodule
endmodule
注: 3点56分,实在太困了,Verilog的程序留着下次再更新(就当留个彩蛋,哈哈哈)。还有一些需要注意地方,可能一时没想到,也留着下次一起更新。