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停止。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/679594.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

24个已知403绕过方法的利用脚本

介绍 一个简单的脚本&#xff0c;仅供自用&#xff0c;用于绕过 403 在curl的帮助下使用24个已知的403绕过方法 它还可用于比较各种条件下的响应&#xff0c;如下图所示 用法 ./bypass-403.sh https://example.com admin ./bypass-403.sh website-here path-here 安装 git …

交叉熵损失函数基本概念及公式

Cross-Entropy Loss 1.二分类2. 对于多类别分类问题&#xff0c;其公式可以表示为&#xff1a;3. 公式深度挖掘解释——交叉熵损失函数公式中&#xff08;log&#xff09;的解释总结 交叉熵损失函数&#xff08;Cross-Entropy Loss&#xff09;是在机器学习和深度学习中常用的一…

陪护系统|陪护小程序提升长者护理服务质量的关键

在如今逐渐老龄化的社会中&#xff0c;老年人对更好的护理服务需求不断增加。科技的进步使得陪护小程序系统源码成为提供优质服务的重要途径之一。本文将从运营角度探讨如何优化陪护小程序系统源码&#xff0c;提升长者护理服务的质量。 首先&#xff0c;我们需要对软件的设计和…

2024年世界听力日活动的主题是什么?

改变思维模式&#xff1a;让所有人的耳和听力保健成为现实&#xff01; Let’s make ear and hearing care a reality for all! 据 世界卫生组织 报道&#xff1a;在全球范围内&#xff0c;超过 80% 的耳和听力保健需求仍未得到满足 &#xff1b; 未得到解决的听力损失每…

CrossOver虚拟机软件功能相似的软件

与 CrossOver 功能相似的软件有&#xff1a; Wine&#xff1a;Wine 是一款在 Unix 和 Unix-like 系统&#xff08;如 Linux、macOS&#xff09;上运行 Windows 应用程序的兼容层。与 CrossOver 类似&#xff0c;Wine 通过模拟 Windows 的 API 来实现应用程序的兼容性。它支持大…

FPGA_简单工程_VGA显示驱动器

一 理论 使用640*48060显示模式&#xff0c;将数字信号转换位模拟信号&#xff0c;经由VGA进行显示。 使用3GM723&#xff0c;3路高清视频编码芯片。 3GM7123编码芯片&#xff1a; 该芯片的主要功能是将RGB888的颜色数据转换成模拟的电压信号&#xff0c;然后进入到VGA接口的…

免费文字转语音工具,一款优秀且永久免费的文字转语音工具,同时拥有多种类型男声女声,支持多国语言转换,支持语速调节和下载!

一、软件简介 该工具只有一个功能&#xff0c;就是将输入框内的纯文本内容转换为指定语言的音频&#xff0c;并且可以自由调节语速及音色&#xff08;男声/女声&#xff09;&#xff0c;其内置了多种语音包&#xff0c;包含男声、女声、普通话、粤语以及方言&#xff0c;并且支…

vue3-内置组件-Suspense

Suspense (实验性功能) <Suspense> 是一项实验性功能。它不一定会最终成为稳定功能&#xff0c;并且在稳定之前相关 API 也可能会发生变化。 <Suspense> 是一个内置组件&#xff0c;用来在组件树中协调对异步依赖的处理。它让我们可以在组件树上层等待下层的多个嵌…

Ainx-V0.2-简单的连接封装与业务绑定

&#x1f4d5;作者简介&#xff1a; 过去日记&#xff0c;致力于Java、GoLang,Rust等多种编程语言&#xff0c;热爱技术&#xff0c;喜欢游戏的博主。 &#x1f4d7;本文收录于Ainx系列&#xff0c;大家有兴趣的可以看一看 &#x1f4d8;相关专栏Rust初阶教程、go语言基础系列…

leetcode链表相关题目

文章目录 1.移除链表元素方法1&#xff1a;方法2 2.合并两个有序链表3.链表的中间节点方法1方法2 4.反转单链表方法1方法2 5.分割链表6.链表中的倒数第k个节点方法1&#xff1a;方法2: 7.环形链表的约瑟夫问题8.链表的回文结构9.相交链表方法1方法2&#xff1a; 10.环形链表11.…

专业课145+总分410+华南理工大学811信号与系统考研经验华工电子信息与通信,真题,大纲,参考书。

大家好&#xff0c;今年考研顺利上岸华南理工大学&#xff0c;专业课811信号与系统145&#xff08;只差一点满分&#xff0c;有点遗憾&#xff0c;专业我跟着Jenny老师复习投入时间和精力和数学差不多&#xff0c;华工专业课难度中等&#xff0c;是一个总分提高很好的突破口&am…

【JavaScript 漫游】【014】正则表达式通关

文章简介 JS 语言中的 RegExp 对象提供正则表达式的功能。本篇文章旨在对该对象的相关知识点进行总结。内容包括&#xff1a; 正则表达式概述RegExp 对象的实例属性RegExp 对象的实例方法字符串与正则表达式相关的实例方法正则表达式匹配规则 概述 正则表达式的概念 正则表…

第三节课[LangChain]作业

文章目录 前言实践搭建向量知识库 前言 本次作业虽然是第三节课作业&#xff0c;但是在第四次作业之后才完成&#xff0c;所以用的是经过自我认知微调的小助手权重。 使用**诡秘之主和宿命之环小说&#xff08;仅用于学习和研究&#xff09;**以及设定集、百度百科&#xff0c…

【开源】JAVA+Vue.js实现天然气工程业务管理系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块三、使用角色3.1 施工人员3.2 管理员 四、数据库设计4.1 用户表4.2 分公司表4.3 角色表4.4 数据字典表4.5 工程项目表4.6 使用材料表4.7 使用材料领用表4.8 整体E-R图 五、系统展示六、核心代码6.1 查询工程项目6.2 工程物资…

414. Third Maximum Number(第三大的数)

题目描述 给你一个非空数组&#xff0c;返回此数组中第三大的数 。如果不存在&#xff0c;则返回数组中最大的数。 问题分析 注意要查找的数是数组中第三大的数&#xff0c;相同大小的数算一个&#xff0c;对于此问题可以采用先将数组排序然后查找第三大的数采用排序的方式最…

如何解决利用cron定时任务自动更新SSL证书后Nginx重启问题

利用cron定时任务自动更新SSL证书后&#xff0c;用浏览器访问网站&#xff0c;获取到的证书仍然是之前的。原因在于没有对Nginx进行重启。 据说certbot更新完成证书后会自动重启Nginx,但显然经我检测不是这回事儿。 所以我们需要创建一bash脚本&#xff0c;然后定时调用这个脚…

Vue核心基础5:数据监测、收集表单数据、过滤器

1 数据监测 【代码】 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>总结</title><scrip…

ChatGPT高效提问—prompt实践

ChatGPT高效提问—prompt实践 ​ 探索prompt在实际生活中的各种应用&#xff0c;旨在帮助理解和掌握如何将之前学到的prompt基础和技巧应用到具体实践中&#xff0c;从而在各个领域实现人工智能的价值。 ​ 通过生动的案例&#xff0c;发现并挖掘ChatGPT和prompt的无穷潜力。…

一个小而实用的 Python 包 pangu,实现在中文和半宽字符(字母、数字和符号)之间自动插入空格

&#x1f349; CSDN 叶庭云&#xff1a;https://yetingyun.blog.csdn.net/ 一个小巧的库&#xff0c;可以避免自己重新开发功能。利用 Python 包 pangu&#xff0c;可以轻松实现在 CJK&#xff08;中文、日文、韩文&#xff09;和半宽字符&#xff08;字母、数字和符号&#xf…

电路设计(15)——篮球赛24秒违例倒计时报警器的proteus仿真

1.设计要求 设计、制作一个篮球赛24秒违例倒计时报警器。要求&#xff1a; &#xff08;1&#xff09;具有倒计时功能。可完整实现从“24”秒开始依序倒计时并显示倒计时过程&#xff0c;显示时间间隔为1秒。 &#xff08;2&#xff09;具有消隐功能。当“24”秒倒计时…