【arduino】三路pid循迹小车
这是个很久之前的项目,没有保存照片,故使用文字+图片说明
先提前说明,想用pid就需要足够的精度,数字信号很难满足,故选用模拟信号,51系列建议放弃,没有自带模拟接口,只能外接转换器,非常麻烦
pid的好处就是跑的非常稳
以下是正文
首先是传感器部分,使用三个带模拟信号的红外传感器(大部分都是带的,d引脚输出数字,a引脚输出模拟),并排放置,如图差不多就行了,传感器之间可以留有一定间隙,根据个人调整。
每个传感器都是模拟量,也就是越黑值就越大,
然后我们把最左边的值减去最右边的值,就能得到另一个函数图像,大概这样,画的有点丑
再融入中间的传感器,把左右偏转,得出这样一个图像,可能传感器本身误差比较大,跟图像有所区别
直接贴代码,这部分是难点,主要是对数据的处理,实际环境变化传感器出现的误差会很难受,可以选择较好的红外传感器或者灰度传感器
int GetTraceDate()
{int Data_Out;//定义数据输出变量int Left_AD,Right_AD,Mid_AD;//定义左右中传感器AD值变量Left_AD=analogRead(A0);Mid_AD=analogRead(A1);Right_AD=analogRead(A2);
//左值减去右值Data_Out=(Left_AD-Right_AD+D_AD_VALUE);//D_AD_VALUE表示居中时误差,把车放在最中间显示的值
//底下这段是对图像进行处理,使得更接近理论以及运行过程的bug,自行调整即可if(Left_AD > _H && Mid_AD > _H && Right_AD > _H) stop = 1;else stop = 0;if(Mid_AD>200){flag = 0;}if((Mid_AD <= LEFT_THERSH) && (Data_Out < -20)){ //leftData_Out= (2*LEFT_MAX-Data_Out);flag--;} else if((Mid_AD <= RIGHT_THERSH) && (Data_Out > -10)){ //rightData_Out= (2*RIGHT_MAX-Data_Out);flag++;}if(Left_AD < _L && Mid_AD < _L && Right_AD < _L){Serial.print("---");if(flag<0){//leftData_Out = LEFT_MAX*2;}else{//rightData_Out = RIGHT_MAX*2;}}
// Data_Out是最重要的返回值,表示车子位于线的方向以及距离,不然无法使用pid公式return Data_Out;
}
车身就没什么好讲的了,使用了一个l298n带电机,好处是可以一次带两个,图片为网图(侵权联系删除),接线方法大概就这样,使用差速转向成本低,快捷,缺点是车身容易摆动
这里贴上完整代码
#define LEFT_MAX -680
#define RIGHT_MAX 330
#define LEFT_THERSH 35
#define RIGHT_THERSH 37
#define D_AD_VALUE -8
#define _L 45
#define _H 500#define leftA_PIN 3
#define leftB_PIN 5
#define righA_PIN 6
#define righB_PIN 9float Kp = 0.05, Ki = 0, Kd = 0; //pid弯道参数参数
float error = 0, P = 0, I = 0, D = 0, PID_value = 0;//pid直道参数
float previous_error = 0, previous_I = 0; //误差值
int initial_motor_speed = 100; //初始速度
//unsigned int PWM_L, PWM_R, T = 0;
int flag = 0;
int stop = 0;
void motor_pinint( )
{pinMode (leftA_PIN, OUTPUT); //设置引脚为输出引脚pinMode (leftB_PIN, OUTPUT); //设置引脚为输出引脚pinMode (righA_PIN, OUTPUT); //设置引脚为输出引脚pinMode (righB_PIN, OUTPUT); //设置引脚为输出引脚
}
//获取循迹传感器输出函数
int GetTraceDate()
{int Data_Out;//定义数据输出变量int Left_AD,Right_AD,Mid_AD;//定义左右中传感器AD值变量Left_AD=analogRead(A0);Mid_AD=analogRead(A1);Right_AD=analogRead(A2);Data_Out=(Left_AD-Right_AD+D_AD_VALUE);Serial.print(Data_Out);Serial.print(" ");if(Left_AD > _H && Mid_AD > _H && Right_AD > _H) stop = 1;else stop = 0;if(Mid_AD>200){flag = 0;}if((Mid_AD <= LEFT_THERSH) && (Data_Out < -20)){ //leftData_Out= (2*LEFT_MAX-Data_Out);flag--;} else if((Mid_AD <= RIGHT_THERSH) && (Data_Out > -10)){ //rightData_Out= (2*RIGHT_MAX-Data_Out);flag++;}if(Left_AD < _L && Mid_AD < _L && Right_AD < _L){Serial.print("---");if(flag<0){//leftData_Out = LEFT_MAX*2;}else{//rightData_Out = RIGHT_MAX*2;}}return Data_Out;
}void calc_pid()
{P = error;I = I + error;D = error - previous_error;PID_value = (Kp * P) + (Ki * I) + (Kd * D);previous_error = error;
}void motor_control()
{int left_motor_speed = initial_motor_speed - PID_value;int right_motor_speed = initial_motor_speed + PID_value;if(left_motor_speed < 1)left_motor_speed = 1;if(right_motor_speed < 1)left_motor_speed = 1;analogWrite(leftA_PIN, left_motor_speed);analogWrite(leftB_PIN, 0);analogWrite(righA_PIN, right_motor_speed);analogWrite(righB_PIN, 0);Serial.print("move_A: ");Serial.print(left_motor_speed, OCT);Serial.print(" move_B: ");Serial.print(right_motor_speed, OCT);Serial.print(" error: ");Serial.print(error, OCT);Serial.print(" PID_value: ");Serial.print(PID_value);Serial.println();
}
void _stop()
{analogWrite(leftA_PIN, 0);analogWrite(leftB_PIN, 0);analogWrite(righA_PIN, 0);analogWrite(righB_PIN, 0);
}
void setup() {Serial.begin(9600);motor_pinint();
}void loop() {error = GetTraceDate();if(!stop) {calc_pid();motor_control();}else {Serial.println("stop");_stop();}
// Serial.print(GetTraceDate());
// Serial.print(" ");
// Serial.print(analogRead(A0));
// Serial.print(" ");
// Serial.print(analogRead(A1));
// Serial.print(" ");
// Serial.print(analogRead(A2));
// Serial.print(" ");
// Serial.print(flag);
// Serial.println();}
代码照搬大概率是用不了的,因为需要根据车子进行实际修改,赛道也有影响
【arduino】三路pid循迹小车相关推荐
- ARDUINO NANO 的 PID 循迹小车
[Arduino项目]使用 ARDUINO NANO 的 PID 循迹小车 -------------------------------------------------------------- ...
- 【32最小系统板】pid循迹小车(铁丝循迹)
文章目录 前言 一.任务.要求及评分标准 1.1 任务 1.2 要求及评分标准 1.3 说明 二.先上视频效果 三.小车循迹方法 1.第一次做循迹时 2.第二次做循迹时 状态机 调PID 四.铁丝与硬 ...
- 单片机原理及应用——Arduino四驱四路循迹小车
摸摸鱼,把大二的课堂作业总结一下发出来,很基础的小白代码,希望能给入门的同学一点参考. 由于实物卖掉啦,只能尽量用文字配上接线图等,写详细一点. 一.元器件清单 Arduino UNO R3开发板(带 ...
- 基于arduino的循迹小车(含有PID算法)
循迹小车一般分为两方面:一方面是简单的闭环赛道只有直道和弯道,另一方面是毕设类型的包括一些元素:90度弯道.十字道路.S形弯道等. 1.CSDN下载: 含有PID:https://dow ...
- Arduino循迹小车教程四----代码篇
文章目录 一.完整的代码 二.循迹代码详解 1.循迹的原理 2.判断情况 3.调速代码 4.循迹代码 5.调试问题 总结 代码分享给同学们啦,在同学们运行小车的过程中,总会遇见各种奇怪的情况,比如小车 ...
- arduino黑线循迹小车程序_循迹小车:给我一条线,我能自己走完全程
在老少通吃的智能小车到底是什么呢?科普来喽!一文中,我们介绍了智能小车的分类及组成,为什么循迹小车能够追踪黑线轨迹呢? 智能小车在画有黑线的白纸 "路面"上行驶,由于黑线和白纸对光 ...
- 基于arduino的5路循迹小车(1)
基于arduino的5路循迹小车(1) 初步小车运动 1.硬件选用 1.开发板使用arduino 2560 2.电机驱动板使用 大功率电机驱动板(PWM由两个端子控制) 3.电源12V锂电池 4.降压 ...
- 基于arduino的5路循迹小车(2)
基于arduino的5路循迹小车(2) 小车5路红外循线 接第一篇链接 https://blog.csdn.net/weixin_45984029/article/details/103437347 ...
- 基于arduino的5路循迹小车(4)与舵机控制板的通信控制
基于arduino的5路循迹小车(4) arduino与舵机控制板的通信控制 以及语音播报模块 接第一篇链接 https://blog.csdn.net/weixin_45984029/article ...
最新文章
- 覆盖10亿设备,月活2亿,快应用要取代App?
- ICMP重定向(ICMP Redirect)
- PL/SQL学习笔记-过程
- 催收成本在单体经济中的分析
- emacs 跳转到指定行
- 事件查看器ID 1041
- 百分之六的谷歌云存储桶因配置错误而遭任意访问
- fedora 主题美化
- linux环境配置以及远程登录linux
- 【SVN】Win 10:SVN 下载、安装和汉化
- vs 2010 sp1 中文版 安装sliverlight 5 正式版
- mac下使用ipv6观看电视
- 勤学修身 放飞梦想4
- deepin网速慢 自己摸索 已解决
- 使用Aura.Router在PHP中进行Web路由
- 【C++基础】头文件定义问题导致的重定义问题
- gitbook 快速入门
- 灰度(金丝雀)发布、蓝绿部署、滚动发布
- 直流电路中升降压(Buck-Boost)变换电路的设计、参数选取及Matlab/Simulik仿真
- lambda表达式和方法引用