使用中,把使能脚和细分脚全部接地,即不设置细分(步进值为1),复位脚和睡眠脚用跳线帽短接。
A4988功能实验测试:
DIR=1,STEP为3.3V占空比50%,频率为500Hz的方波,电机电压Vmot=12V。
接线参考下图对应关系
A+和A-为一相
B+和B-为一相
同相之间电阻较小,非同相之间电阻无穷大,接完线可以用万用表测量是否接错
A4988的引脚图及运用 – 八色木
https://www.basemu.com/a4988_pinout_and_how_to_use.html
//PB15 enable 低电平有效
//PB14 dir
//PB13 pulse
void loop()
{
int i,j,k,x=7;
int num=1000;
PBout(15)=0;
PBout(14)=1;
for(i=0;i<num;i++)
{
PBout(13)=1;
Delay_ms(x);
PBout(13)=0;
Delay_ms(x);
}
GPIOBE_REV;
Delay_ms(1000);
PBout(14)=0;
for(i=0;i<num;i++)
{
PBout(13)=1;
Delay_ms(x);
PBout(13)=0;
Delay_ms(x);
}
GPIOBE_REV;
Delay_ms(1000);
PBout(15)=1;
// GPIOBE_REV;
}
主函数:
int main(void)
{
u8 i,j,k=0;
RCC_Configuration();
GPIO_Configuration();//LED+用到的GPIO
while(1)
{
loop();
}
}
脉冲越快电机转动速度越快
脉冲不能发的太快,否则电机跟不上就会吱吱响但是不转动
1、4988驱动板可以驱动57电机吗?
4988可以驱动的电机跟尺寸关系不大,主要与工作电流有关,理论上电流小于2A的步进电机都是可以驱动的,不论是42还是57电机。
2、可以驱动多大的电流?
如果4988芯片上没有加散热片,电流最好在1.2A以下。如果加散热片,电流可以达到2A。
3、步进电机的连接方式是什么?
正如4988板子背面所标识的,连接方式是依次连接步进电机的1B-1A-2A-2B,或者反向为2B-2A-1A-1B,或者1A-1B-2B-2A,其它的方式一次类推。如果你的电机线是标准的红蓝绿黑的颜色,可以按照颜色连接为:红-蓝-绿-黑,或相反:黑-绿-蓝-红。
4、如何调节相电流?
相电流的大小跟步进电机的扭力有直接关系,如果感觉你的步进电机扭力不足,可以加大4988板子的电流配置。驱动板是通过一个小的电位器来实现对输出电流的配置的。可以通过用万用表测量电位器中间管脚的电位。电位和电流的关系满足下面的公式:Vref = A*0.8.也就是如果你想配置电机工作电流为1A,则电位应该配置在0.8V。默认的元件配置可以将电流调节到1.5A,如果需要更大电流需要修改电路中的R1,将30K的阻值改为20K(左右),就可以将电流调节到2A左右。
5、4988板子的细分如何配置?
4988板子细分配置需要ramps或其它相似板子的短路块来配置。ramps上对应每个4988驱动都有ms1,ms2,ms3三个短路块来调节细分(需要取下4988板子才可以看到),
ms1 | ms2 | ms3
no | no | no |全细分
yes | no | no |1/2(2细分)
no | yes | no | 1/4 (4细分)
yes | yes | no |1/8(8细分)
yes | yes | yes | 1/16(16细分)
6、接上电机后,电机不能正常运行,在左右抖动,是什么原因?
电机出现抖动一般有两个原因,
一是缺相:可能是4988板子没有焊接好或因为外力导致4988的输出端某一相断开,造成电机缺相从而抖动。也有可能是步进电机接线只用一相没有连接好;
而是两相接错:如果步进电机没有按照正确的顺序进行连接,电机也会出现抖动的情况,请按照问题3进行正确的连接。
7、4988可以驱动两相六线或两相无线的电机吗?
可以,两相连线按照问题3连接,将中间抽头悬空即可。
8、电机停止转动时会有滋滋的电流声。
首先说明的是这是正常现象。步进电机的特点是走特定的角度而不是一直转,所以步进电机都有一个参数,步距角。如果通过细分,可以最小走 步距角/细分数的角度,比如步距角为1.8度的步进电机,采用16细分,最小可以走的角度是1.8/16=0.1125度。但由于这个角度非常小,并且不一定在电机物理所在的位置(1.8度为一个物理位置),所以步进电机停止时也需要通电,从而保证电机不会自动跳到物理步距角上。因为这个特性使得步进电机在静止时会有电流声,这属于正常现象,不用担心。
链接:https://www.jianshu.com/p/a168c20b0f65
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
a4988芯片烧毁的现象:24V和GND短路,AB两相也短路
步进电机驱动芯片a4988上电烧毁-OpenEdv-开源电子网
http://openedv.com/thread-100510-1-1.html
好几根线都要接的时候
代码 A4988 步进电机驱动模块测试 - 简书
https://www.jianshu.com/p/a168c20b0f65
(8条消息) A4988步进驱动_Nc2016的博客-CSDN博客
https://blog.csdn.net/PoJiaA123/article/details/85107927
(8条消息) 使用Arduino与A4988 驱动步进电机_凌顺实验室-CSDN博客
https://blog.csdn.net/ling3ye/article/details/47001251
A4988 步进电机驱动模块测试 - 简书
https://www.jianshu.com/p/a168c20b0f65
(8条消息) A4988步进驱动_Nc2016的博客-CSDN博客
https://blog.csdn.net/PoJiaA123/article/details/85107927
(8条消息) 【arduino】arduino uno + A4988控制42步进电机_g1fdgfgdf2_的博客-CSDN博客
https://blog.csdn.net/g1fdgfgdf2_/article/details/78692759
Instruction Packet
Instruction Packet is the command data sent to the Device.
安装vscode和python,pyserial
vscode选择打开文件夹
选择协议2文件夹
打开如图
选择文件后改动com口,点击菜单“运行”
由上图协议可知,param前四个为地址和数据长度,后面是id编号
这里初始化了同步读取的四个参数,分别为端口 数据包 地址 数据长度。。协议第二条要求地址和数据长度不可变。
类初始化四个参数:
后面继续添加要读取的舵机id(添加了两个):
发送,并获得返回数据:
使用完后,(程序即将退出时):
写入类似,多了个写入的目标位置值
# Enable Dynamixel#1 Torque
dxl_comm_result, dxl_error = packetHandler.write1ByteTxRx(portHandler, DXL1_ID, ADDR_PRO_TORQUE_ENABLE, TORQUE_ENABLE)
if dxl_comm_result != COMM_SUCCESS:
print("%s" % packetHandler.getTxRxResult(dxl_comm_result))
elif dxl_error != 0:
print("%s" % packetHandler.getRxPacketError(dxl_error))
else:
print("Dynamixel#%d has been successfully connected" % DXL1_ID)
# Add parameter storage for Dynamixel#1 present position
dxl_addparam_result = groupBulkRead.addParam(DXL1_ID, ADDR_PRO_PRESENT_POSITION, LEN_PRO_PRESENT_POSITION)
if dxl_addparam_result != True:
print("[ID:%03d] groupBulkRead addparam failed" % DXL1_ID)
quit()
while1循环
while 1:
print("Press any key to continue! (or press ESC to quit!)")
if getch() == chr(0x1b):
break
# Allocate goal position value into byte array
param_goal_position = [DXL_LOBYTE(DXL_LOWORD(dxl_goal_position[index])), DXL_HIBYTE(DXL_LOWORD(dxl_goal_position[index])), DXL_LOBYTE(DXL_HIWORD(dxl_goal_position[index])), DXL_HIBYTE(DXL_HIWORD(dxl_goal_position[index]))]
# Add Dynamixel#1 goal position value to the Bulkwrite parameter storage
dxl_addparam_result = groupBulkWrite.addParam(DXL1_ID, ADDR_PRO_GOAL_POSITION, LEN_PRO_GOAL_POSITION, param_goal_position)
if dxl_addparam_result != True:
print("[ID:%03d] groupBulkWrite addparam failed" % DXL1_ID)
quit()
# Bulkwrite goal position and LED value
dxl_comm_result = groupBulkWrite.txPacket()
if dxl_comm_result != COMM_SUCCESS:
print("%s" % packetHandler.getTxRxResult(dxl_comm_result))
groupBulkWrite.clearParam()
# Add Dynamixel#2 LED value to the Bulkwrite parameter storage
dxl_addparam_result = groupBulkWrite.addParam(DXL1_ID, ADDR_PRO_LED_RED, LEN_PRO_LED_RED, [dxl_led_value[index]])
if dxl_addparam_result != True:
print("[ID:%03d] groupBulkWrite addparam failed" % DXL1_ID)
quit()
# Bulkwrite goal position and LED value
dxl_comm_result = groupBulkWrite.txPacket()
if dxl_comm_result != COMM_SUCCESS:
print("%s" % packetHandler.getTxRxResult(dxl_comm_result))
# Clear bulkwrite parameter storage
groupBulkWrite.clearParam()
while 1:
# # Bulkread present position and LED status
dxl_comm_result = groupBulkRead.txRxPacket()
if dxl_comm_result != COMM_SUCCESS:
print("%s" % packetHandler.getTxRxResult(dxl_comm_result))
# Check if groupbulkread data of Dynamixel#1 is available
dxl_getdata_result = groupBulkRead.isAvailable(DXL1_ID, ADDR_PRO_PRESENT_POSITION, LEN_PRO_PRESENT_POSITION)
if dxl_getdata_result != True:
print("[ID:%03d] groupBulkRead getdata failed" % DXL1_ID)
quit()
# # Check if groupbulkread data of Dynamixel#2 is available
# dxl_getdata_result = groupBulkRead.isAvailable(DXL2_ID, ADDR_PRO_LED_RED, LEN_PRO_LED_RED)
# if dxl_getdata_result != True:
# print("[ID:%03d] groupBulkRead getdata failed" % DXL2_ID)
# quit()
# Get present position value
dxl1_present_position = groupBulkRead.getData(DXL1_ID, ADDR_PRO_PRESENT_POSITION, LEN_PRO_PRESENT_POSITION)
# # Get LED value
# dxl2_led_value_read = groupBulkRead.getData(DXL2_ID, ADDR_PRO_LED_RED, LEN_PRO_LED_RED)
# print("[ID:%03d] Present Position : %d \t [ID:%03d] LED Value: %d" % (DXL1_ID, dxl1_present_position, DXL2_ID, dxl2_led_value_read))
if not (abs(dxl_goal_position[index] - dxl1_present_position) > DXL_MOVING_STATUS_THRESHOLD):
break
# Change goal position
if index == 0:
index = 1
else:
index = 0
Succeeded to open the port
Succeeded to change the baudrate
[RxPacketError] The data length does not match as expected!
####已解决,舵机地址错误
txpacket = [0] * (length + 7)
在python中, 如果用一个列表list1乘一个数字n 会得到一个新的列表list2, 这个列表的元素是list1的元素重复n次, 例如:
list1 = [0]
list2 = list1 * 5 # list2 = [0, 0, 0, 0, 0]
(3条消息) python 列表乘一个数字_hq_cjj的博客-CSDN博客
https://blog.csdn.net/hq_cjj/article/details/86659589
Python 库打包分发(setup.py 编写)简易指南 | Huoty’s Blog
https://blog.konghy.cn/2018/04/29/setup-dot-py/#part-2bb23717ee7e9bfc
我的理解是 from . import XXX默认的就是在当前程序所在文件夹里__init__.py程序中导入XXX,如果当前程序所在文件夹里没有__init__.py文件的话,就不能这样写,而应该写成from .A import XXX,A是指当前文件夹下你想导入的函数(或者其他的)的python程序名,如果你想导入的函数不在当前文件夹,那么就有可能用到 from … import XXX(即上一个文件夹中的__init__.py),或者from …A import XXX(即上一个文件夹中的文件A)
链接:https://www.zhihu.com/question/28688151/answer/66982373
(3条消息) 【Visual Studio Code】VS Code在Linux/Mac/Windows中向前、向后定位的快捷键及修改方法_H_O_W_E的专栏-CSDN博客
https://blog.csdn.net/H_O_W_E/article/details/104944130