arduino uno R3驱动直流减速电机(蓝牙控制)

2024-03-02 22:20

本文主要是介绍arduino uno R3驱动直流减速电机(蓝牙控制),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

此篇博客用于记录使用arduino驱动直流减速电机的过程,仅实现简单的功能:PID调速、蓝牙控制

    • 1、直流减速电机简介
    • 2、DRV8833电机驱动模块简介
    • 3、HC-05蓝牙模块简介
    • 电机转动测试
    • 4、PID控制
    • 5、蓝牙控制电机

1、直流减速电机简介

我在淘宝购买的电机,减速比是21.3,旋转一圈产生的脉冲数是11,这样实际通过编码区采集到的一圈脉冲数(使用一倍频计数)是11×21.3,如果采用N倍频的话就是:11×21.3×N。这里关于编码器的相关知识直接看此文档有详细介绍:http://www.autolabor.com.cn/book/ROSTutorials/di-8-zhang-gou-jian-lun-shi-cha-fen-ji-qi-ren/83-di-pan-kong-zhi-ji-chu-arduino-yu-dian-ji-qu-dong/833-dian-ji-ce-su.html

在这里插入图片描述
上面给出了接线方式,要注意的是直接使用arduino的io口是无法驱动电机的,所以还需要一块电机驱动板或者驱动芯片,这里使用的是DRV8833电机驱动模块,红色接DRV8833的AO1、白色接DRV8833的AO2、黑色接arduino的GND、蓝色接3V3、因为使用一倍频,只需要一个中断口就可以,这里换黄色接引脚2(外部中断),绿色接引脚9(可以使用其他的io口)。

2、DRV8833电机驱动模块简介

下面是芯片引脚图
在这里插入图片描述
在这里插入图片描述
由于这里VM需要较高的电压才能驱动电机转起来,所以还单独购买了一个电池,用于VM引脚供电,电池名称:18650锂电池,最好选可以充电的那种。
AIN1接arduino的引脚10(需要可以输出pwm波的引脚),AIN2接引脚11(可以任意指定引脚,这只是用于控制方向),STBY引脚直接接5V。
在这里插入图片描述

在这里插入图片描述

3、HC-05蓝牙模块简介

在这里插入图片描述
一共六个引脚,EN和STATE一般用不到,其余的有两个电源引脚、两个串口引脚。建议在使用单片机调试之前先用usb转ttl模块连接电脑进行测试:①将RX连接至usb转ttl模块的TX,TX连接RX,电源线对着连。②插进电脑之前先按住HC-05上的按键,然后将usb转ttl模块插入电脑,此时HC-05就会进入AT指令状态下,可以使用电脑的串口助手进行测试,蓝牙模块的波特率默认是38400,0个停止位,0个校验位。③进行测试,发送指令的顺序可以参考这个:1、AT,返回OK;2、AT+ROLE=0,默认就是零,保险起见再设置一下,设置完这个之后,下一次上电周围的设备就可以搜索到此蓝牙;3、AT+NAME=xxx,这里按自己喜好设置名字;4、AT+PSWD=“xxx”,设定密码;5、AT+UART=38400,0,0。设置波特率和停止位、校验位。
这样就设置完成了,下一次可以直接上电,然后手机搜索蓝牙使用密码连接。如果不想用串口助手测试,也可以再arduino中用以下代码测试(蓝牙模块的RX连接arduino引脚9,TX连引脚8):

#include <SoftwareSerial.h>          //库文件SoftwareSerial BT(8, 9);           //设置蓝牙与板子的连接端口。  pin 8  接蓝牙的 TXD    pin 9 接蓝牙的 RXD
char X;                              //定义一个变量存数据。void setup() 
{Serial.begin(38400);              //串口监视器通信速率,38400Serial.println("蓝牙连接正常");     //串口监视器显示蓝牙正常状态BT.begin(38400);                  //蓝牙通信速率,默认一般为 38400
}void loop()                         //大循环,执行。
{if (Serial.available())          {X = Serial.read();              //把写入的数据给到自定义变量  XBT.print(X);                    //由arduino向手机发数据}if (BT.available())             {X = BT.read();                  //把检测到的数据给到自定义变量 XSerial.print(X);                //由手机向arduino发数据}
}

编译运行之后打开自带的串口监视器,设置模式BOTH NL &CR,波特率选择38400,就可以输入前面的指令进行设置了,后面与手机进行通信的时候发现数据都是乱码,将 BT.begin(38400); 改为 BT.begin(9600);即可。

电机转动测试

按照上面的方式连接好线路之后可以先测试看是否能正常驱动电机转起来:

/** 电机转动控制* 1.定义接线中电机对应的引脚* 2.setup 中设置引脚为输出模式* 3.loop中控制电机转动* */int DIRA = 11;
int PWMA = 10;void setup() {//两个引脚都设置为 OUTPUTpinMode(DIRA,OUTPUT);pinMode(PWMA,OUTPUT);
}void loop() {//先正向转动3秒digitalWrite(DIRA,LOW);analogWrite(PWMA,100);delay(3000);//停止3秒digitalWrite(DIRA,LOW);analogWrite(PWMA,0);delay(3000);//再反向转动3秒digitalWrite(DIRA,HIGH);analogWrite(PWMA,100);delay(3000);//停止3秒digitalWrite(DIRA,LOW);analogWrite(PWMA,0);delay(3000);/** 注意: * 1.可以通过将DIRA设置为HIGH或LOW来控制电机转向,但是哪个标志位正转或反转需要根据需求判断,转向是相对的。* 2.PWM的取值为 [0,255],该值可自己设置。* */
}

如果电机转动起来说明前面的步骤就没问题。
转速测试也直接参考前面的那个链接里做就行。

4、PID控制

理论部分参考链接文档,下面给出具体实现流程:
也就是直接调用PID库里的函数就可以实现,具体代码如下:


#include <PID_v1.h> int motor_A = 2;//中端口是2
int motor_B = 9;//中断口是3
int DIRA = 11;
int PWMA = 10;
volatile int count = 0;//如果是正转,那么每计数一次自增1,如果是反转,那么每计数一次自减1 float reducation = 21;//减速比,根据电机参数设置,比如 15 | 30 | 60
int pulse = 11; //编码器旋转一圈产生的脉冲数该值需要参考商家电机参数
int per_round = pulse * reducation;//车轮旋转一圈产生的脉冲数 
long start_time = millis();//一个计算周期的开始时刻,初始值为 millis();
long interval_time = 50;//一个计算周期 50ms
double current_vel;void count_A(){//单频计数实现//手动旋转电机一圈,输出结果为 一圈脉冲数 * 减速比if(digitalRead(motor_A) == HIGH){if(digitalRead(motor_B) == HIGH){//A 高 B 高count++;  } else {//A 高 B 低count--;  }}
}//获取当前转速的函数
void get_current_vel(){long right_now = millis();  long past_time = right_now - start_time;//计算逝去的时间if(past_time >= interval_time){//如果逝去时间大于等于一个计算周期//1.禁止中断noInterrupts();//2.计算转速 转速单位可以是秒,也可以是分钟... 自定义即可current_vel = (double)(count) / per_round / past_time * 1000 * 60;//3.重置计数器count = 0;//4.重置开始时间start_time = right_now;//5.重启中断interrupts();Serial.println(current_vel);}
}//-------------------------------------PID-------------------------------------------
//创建 PID 对象
//1.当前转速 2.计算输出的pwm 3.目标转速 4.kp 5.ki 6.kd 7.当输入与目标值出现偏差时,向哪个方向控制
double pwm;//电机驱动的PWM值
double target = 20;
double kp=1.5, ki=3.0, kd=0.1;
PID pid(&current_vel,&pwm,&target,kp,ki,kd,DIRECT);//速度更新函数
void update_vel(){//获取当前速度get_current_vel();pid.Compute();//计算需要输出的PWMdigitalWrite(DIRA,HIGH);analogWrite(PWMA,pwm);}void setup() {Serial.begin(57600);//设置波特率  pinMode(9,INPUT);pinMode(2,INPUT);pinMode(10,OUTPUT);pinMode(11,OUTPUT);attachInterrupt(0,count_A,CHANGE);//当电平发生改变时触发中断函数pid.SetMode(AUTOMATIC);
}void loop() {delay(10);update_vel();
}

PID控制的最终预期结果,是要快速、精准、稳定的达成预期结果,P主要用于控制响应速度,I主要用于控制精度,D主要用于减小震荡增强系统稳定性,三者的取值是需要反复调试的,调试过程中需要查看系统的响应曲线,根据响应曲线以确定合适的PID值。

在 Arduino 中响应曲线的查看可以借助于 Serial.println() 将结果输出,然后再选择菜单栏的工具下串口绘图器以图形化的方式显示响应结果

5、蓝牙控制电机

这里只提供简单实现,可以用安卓手机市场里的蓝牙调试器进行调试,如果找不到也可以私信我。实现控制电机正反转。

#include <SoftwareSerial.h>         
#include <PID_v1.h> SoftwareSerial BT(8, 9);           //设置蓝牙与板子的连接端口。  pin 8  接蓝牙的 TXD    pin 9 接蓝牙的 RXD
char X;                              //定义一个变量存数据。
String temp = "";int motor_A = 2;//中端口是2
int motor_B = 9;//中断口是3
int DIRA = 11;
int PWMA = 10;
volatile int count = 0;//如果是正转,那么每计数一次自增1,如果是反转,那么每计数一次自减1 float reducation = 21.3;//减速比,根据电机参数设置,比如 15 | 30 | 60
int pulse = 11; //编码器旋转一圈产生的脉冲数该值需要参考商家电机参数
int per_round = pulse * reducation;//车轮旋转一圈产生的脉冲数 
long start_time = millis();//一个计算周期的开始时刻,初始值为 millis();
long interval_time = 50;//一个计算周期 50ms
double current_vel;void count_A(){//单频计数实现//手动旋转电机一圈,输出结果为 一圈脉冲数 * 减速比if(digitalRead(motor_A) == HIGH){if(digitalRead(motor_B) == HIGH){//A 高 B 高count++;  } else {//A 高 B 低count--;  }}
}//获取当前转速的函数
void get_current_vel(){long right_now = millis();  long past_time = right_now - start_time;//计算逝去的时间if(past_time >= interval_time){//如果逝去时间大于等于一个计算周期//1.禁止中断noInterrupts();//2.计算转速 转速单位可以是秒,也可以是分钟... 自定义即可current_vel = (double)(count) / per_round / past_time * 1000 * 60;//3.重置计数器count = 0;//4.重置开始时间start_time = right_now;//5.重启中断interrupts();Serial.println(current_vel);}
}//-------------------------------------PID-------------------------------------------
//创建 PID 对象
//1.当前转速 2.计算输出的pwm 3.目标转速 4.kp 5.ki 6.kd 7.当输入与目标值出现偏差时,向哪个方向控制
double pwm;//电机驱动的PWM值
double target = 0;
double kp=1.5, ki=3.0, kd=0.1;
PID pid(&current_vel,&pwm,&target,kp,ki,kd,DIRECT);//速度更新函数
void update_vel(){//获取当前速度get_current_vel();pid.Compute();//计算需要输出的PWMif(target > 0){digitalWrite(DIRA,LOW); //正转}else if(target < 0){digitalWrite(DIRA,HIGH);//反转}else{}analogWrite(PWMA,pwm);}void setup() {Serial.begin(38400);//设置波特率  pinMode(9,INPUT);pinMode(2,INPUT);pinMode(10,OUTPUT);pinMode(11,OUTPUT);attachInterrupt(0,count_A,CHANGE);//当电平发生改变时触发中断函数pid.SetMode(AUTOMATIC);BT.begin(9600); 
}void loop() {if (BT.available())               //检测:【蓝牙】如果数据写入,则执行。{X = BT.read();                  //把检测到的数据给到自定义变量 XSerial.println(X);                //把从蓝牙得到的数据显示到串口监视器temp = X;}if(temp == "2"){target = 80;Serial.println(temp);}else if(temp == "3"){target = -80;Serial.println(temp);}else if(temp == "0"){target = 0;Serial.println(temp);}delay(10);update_vel();
}

蓝牙调试器发送2控制电机正转,发送3反转,发送0停止。

这篇关于arduino uno R3驱动直流减速电机(蓝牙控制)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/767604

相关文章

Spring Security 基于表达式的权限控制

前言 spring security 3.0已经可以使用spring el表达式来控制授权,允许在表达式中使用复杂的布尔逻辑来控制访问的权限。 常见的表达式 Spring Security可用表达式对象的基类是SecurityExpressionRoot。 表达式描述hasRole([role])用户拥有制定的角色时返回true (Spring security默认会带有ROLE_前缀),去

Linux_kernel驱动开发11

一、改回nfs方式挂载根文件系统         在产品将要上线之前,需要制作不同类型格式的根文件系统         在产品研发阶段,我们还是需要使用nfs的方式挂载根文件系统         优点:可以直接在上位机中修改文件系统内容,延长EMMC的寿命         【1】重启上位机nfs服务         sudo service nfs-kernel-server resta

arduino ide安装详细步骤

​ 大家好,我是程序员小羊! 前言: Arduino IDE 是一个专为编程 Arduino 微控制器设计的集成开发环境,使用起来非常方便。下面将介绍如何在不同平台上安装 Arduino IDE 的详细步骤,包括 Windows、Mac 和 Linux 系统。 一、在 Windows 上安装 Arduino IDE 1. 下载 Arduino IDE 打开 Arduino 官网

三相直流无刷电机(BLDC)控制算法实现:BLDC有感启动算法思路分析

一枚从事路径规划算法、运动控制算法、BLDC/FOC电机控制算法、工控、物联网工程师,爱吃土豆。如有需要技术交流或者需要方案帮助、需求:以下为联系方式—V 方案1:通过霍尔传感器IO中断触发换相 1.1 整体执行思路 霍尔传感器U、V、W三相通过IO+EXIT中断的方式进行霍尔传感器数据的读取。将IO口配置为上升沿+下降沿中断触发的方式。当霍尔传感器信号发生发生信号的变化就会触发中断在中断

控制反转 的种类

之前对控制反转的定义和解释都不是很清晰。最近翻书发现在《Pro Spring 5》(免费电子版在文章最后)有一段非常不错的解释。记录一下,有道翻译贴出来方便查看。如有请直接跳过中文,看后面的原文。 控制反转的类型 控制反转的类型您可能想知道为什么有两种类型的IoC,以及为什么这些类型被进一步划分为不同的实现。这个问题似乎没有明确的答案;当然,不同的类型提供了一定程度的灵活性,但

深入解析秒杀业务中的核心问题 —— 从并发控制到事务管理

深入解析秒杀业务中的核心问题 —— 从并发控制到事务管理 秒杀系统是应对高并发、高压力下的典型业务场景,涉及到并发控制、库存管理、事务管理等多个关键技术点。本文将深入剖析秒杀商品业务中常见的几个核心问题,包括 AOP 事务管理、同步锁机制、乐观锁、CAS 操作,以及用户限购策略。通过这些技术的结合,确保秒杀系统在高并发场景下的稳定性和一致性。 1. AOP 代理对象与事务管理 在秒杀商品

PostgreSQL中的多版本并发控制(MVCC)深入解析

引言 PostgreSQL作为一款强大的开源关系数据库管理系统,以其高性能、高可靠性和丰富的功能特性而广受欢迎。在并发控制方面,PostgreSQL采用了多版本并发控制(MVCC)机制,该机制为数据库提供了高效的数据访问和更新能力,同时保证了数据的一致性和隔离性。本文将深入解析PostgreSQL中的MVCC功能,探讨其工作原理、使用场景,并通过具体SQL示例来展示其在实际应用中的表现。 一、

开放式耳机好用?平价开放式耳机推荐?四款开放式的蓝牙耳机推荐

开放式耳机好用吗?有平价些的开放式耳机推荐吗?那这两个问题的回答当然是肯定的。 首先开放式耳机好不好用取决于对耳机的需求,因为开放式耳机其实是比较适用于需要注意周围环境、需要‌长时间佩戴舒适以及需要频繁与人交流的场景中,在这些场景下使用开放式耳机的话就会比较有优势。就例如跑步骑行健身等运动的时候,能够兼得佩戴舒适度的同时,增加一定的安全性;还有在办公学习的时候,会很适合长时间佩戴,能够方便和

vue2实践:el-table实现由用户自己控制行数的动态表格

需求 项目中需要提供一个动态表单,如图: 当我点击添加时,便添加一行;点击右边的删除时,便删除这一行。 至少要有一行数据,但是没有上限。 思路 这种每一行的数据固定,但是不定行数的,很容易想到使用el-table来实现,它可以循环读取:data所绑定的数组,来生成行数据,不同的是: 1、table里面的每一个cell,需要放置一个input来支持用户编辑。 2、最后一列放置两个b

【电机控制】数字滤波算法(持续更新)

文章目录 前言1. 数字低通滤波 前言 各种数字滤波原理,离散化公式及代码。 1. 数字低通滤波 滤波器公式 一阶低通滤波器的输出 y [ n ] y[n] y[n] 可以通过以下公式计算得到: y [ n ] = α x [ n ] + ( 1 − α ) y [ n − 1 ] y[n] = \alpha x[n] + (1 - \alpha) y[n-1]