2020-09-26-舵机+两相4线步进电机

A4988 步进电机驱动模块测试-两相4线步进电机

在这里插入图片描述

使用中,把使能脚和细分脚全部接地,即不设置细分(步进值为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

stm32发脉冲的代码

//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.
在这里插入图片描述

windows下运行步骤

安装vscode和python,pyserial
vscode选择打开文件夹
在这里插入图片描述
选择协议2文件夹在这里插入图片描述
打开如图
在这里插入图片描述
选择文件后改动com口,点击菜单“运行”
在这里插入图片描述

sync_read_write

在这里插入图片描述
由上图协议可知,param前四个为地址和数据长度,后面是id编号
在这里插入图片描述
这里初始化了同步读取的四个参数,分别为端口 数据包 地址 数据长度。。协议第二条要求地址和数据长度不可变。
类初始化四个参数:

后面继续添加要读取的舵机id(添加了两个):
在这里插入图片描述
发送,并获得返回数据:
在这里插入图片描述
使用完后,(程序即将退出时):
在这里插入图片描述
写入类似,多了个写入的目标位置值
在这里插入图片描述

bulk_read_write

# 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

故障

length does not match

Succeeded to open the port
Succeeded to change the baudrate
[RxPacketError] The data length does not match as expected!

####已解决,舵机地址错误

调试过程中查的小知识

list

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

setup.py

Python 库打包分发(setup.py 编写)简易指南 | Huoty’s Blog
https://blog.konghy.cn/2018/04/29/setup-dot-py/#part-2bb23717ee7e9bfc

from . import XXX

我的理解是 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

Visual Studio Code快捷键

(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
在这里插入图片描述

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
好的,我可以帮你做一个基于Arduino UNO R3开发板的室内安全报警系统。下面是设备的接线流程和完整的编程代码。 设备接线流程: 1. MQ-2烟雾浓度传感器: - VCC引脚连接到Arduino的5V引脚 - GND引脚连接到Arduino的GND引脚 - DO引脚连接到Arduino的数字引脚2 2. 火焰传感器: - VCC引脚连接到Arduino的5V引脚 - GND引脚连接到Arduino的GND引脚 - DO引脚连接到Arduino的数字引脚3 3. 舵机: - VCC引脚连接到Arduino的5V引脚 - GND引脚连接到Arduino的GND引脚 - Signal引脚连接到Arduino的数字引脚9 4. 无源蜂鸣器: - 正极引脚连接到Arduino的数字引脚8 - 负极引脚连接到Arduino的GND引脚 5. 风扇: - 正极引脚连接到Arduino的数字引脚10 - 负极引脚连接到Arduino的GND引脚 6. 步进电机: - IN1、IN2、IN3、IN4引脚分别连接到Arduino的数字引脚4、5、6、7 7. RGB三色LED灯: - 红色引脚连接到Arduino的数字引脚11 - 绿色引脚连接到Arduino的数字引脚12 - 蓝色引脚连接到Arduino的数字引脚13 编程代码: ```cpp #include <Stepper.h> #define SMOKE_SENSOR_PIN 2 #define FLAME_SENSOR_PIN 3 #define SERVO_PIN 9 #define BUZZER_PIN 8 #define FAN_PIN 10 #define STEPPER_IN1_PIN 4 #define STEPPER_IN2_PIN 5 #define STEPPER_IN3_PIN 6 #define STEPPER_IN4_PIN 7 #define LED_RED_PIN 11 #define LED_GREEN_PIN 12 #define LED_BLUE_PIN 13 Stepper stepper(2048, STEPPER_IN1_PIN, STEPPER_IN3_PIN, STEPPER_IN2_PIN, STEPPER_IN4_PIN); void setup() { pinMode(SMOKE_SENSOR_PIN, INPUT); pinMode(FLAME_SENSOR_PIN, INPUT); pinMode(SERVO_PIN, OUTPUT); pinMode(BUZZER_PIN, OUTPUT); pinMode(FAN_PIN, OUTPUT); pinMode(LED_RED_PIN, OUTPUT); pinMode(LED_GREEN_PIN, OUTPUT); pinMode(LED_BLUE_PIN, OUTPUT); stepper.setSpeed(10); } void loop() { int smokeValue = digitalRead(SMOKE_SENSOR_PIN); int flameValue = digitalRead(FLAME_SENSOR_PIN); if (smokeValue == HIGH) { activateAlarm(); activateFan(); activateLED(255, 0, 0); // 红色 } else if (flameValue == HIGH) { activateAlarm(); activateServo(); activateLED(255, 165, 0); // 橙色 } else { deactivateAlarm(); deactivateServo(); deactivateFan(); activateLED(0, 255, 0); // 绿色 } rotateStepperMotor(); } void activateAlarm() { tone(BUZZER_PIN, 1000); } void deactivateAlarm() { noTone(BUZZER_PIN); } void activateServo() { for (int angle = 0; angle <= 180; angle += 10) { digitalWrite(SERVO_PIN, HIGH); delayMicroseconds(1000 + angle * 1000 / 180); digitalWrite(SERVO_PIN, LOW); delay(15); } } void deactivateServo() { digitalWrite(SERVO_PIN, LOW); } void activateFan() { digitalWrite(FAN_PIN, HIGH); } void deactivateFan() { digitalWrite(FAN_PIN, LOW); } void activateLED(int red, int green, int blue) { analogWrite(LED_RED_PIN, red); analogWrite(LED_GREEN_PIN, green); analogWrite(LED_BLUE_PIN, blue); } void rotateStepperMotor() { stepper.step(1); } ``` 这段代码使用了Stepper库(Stepper.h)。请确保将这个库正确安装到Arduino IDE中。 请在Arduino IDE中打开一个新的项目,将上述代码复制并粘贴到新项目中。然后,将代码上传到Arduino板上。 这个室内安全报警系统使用了MQ-2烟雾浓度传感器和火焰传感器来检测烟雾和火焰。当检测到烟雾或火焰时,报警器会发出声音警报,并且舵机会旋转,风扇会启动。此外,RGB三色LED灯会显示不同的颜色来表示当前状态。 请根据上述的接线流程进行硬件连接。希望这能帮助到你。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

开心超人dev

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值