这是个很久之前的项目,没有保存照片,故使用文字+图片说明

先提前说明,想用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循迹小车相关推荐

  1. ARDUINO NANO 的 PID 循迹小车

    [Arduino项目]使用 ARDUINO NANO 的 PID 循迹小车 -------------------------------------------------------------- ...

  2. 【32最小系统板】pid循迹小车(铁丝循迹)

    文章目录 前言 一.任务.要求及评分标准 1.1 任务 1.2 要求及评分标准 1.3 说明 二.先上视频效果 三.小车循迹方法 1.第一次做循迹时 2.第二次做循迹时 状态机 调PID 四.铁丝与硬 ...

  3. 单片机原理及应用——Arduino四驱四路循迹小车

    摸摸鱼,把大二的课堂作业总结一下发出来,很基础的小白代码,希望能给入门的同学一点参考. 由于实物卖掉啦,只能尽量用文字配上接线图等,写详细一点. 一.元器件清单 Arduino UNO R3开发板(带 ...

  4. 基于arduino的循迹小车(含有PID算法)

           循迹小车一般分为两方面:一方面是简单的闭环赛道只有直道和弯道,另一方面是毕设类型的包括一些元素:90度弯道.十字道路.S形弯道等. 1.CSDN下载: 含有PID:https://dow ...

  5. Arduino循迹小车教程四----代码篇

    文章目录 一.完整的代码 二.循迹代码详解 1.循迹的原理 2.判断情况 3.调速代码 4.循迹代码 5.调试问题 总结 代码分享给同学们啦,在同学们运行小车的过程中,总会遇见各种奇怪的情况,比如小车 ...

  6. arduino黑线循迹小车程序_循迹小车:给我一条线,我能自己走完全程

    在老少通吃的智能小车到底是什么呢?科普来喽!一文中,我们介绍了智能小车的分类及组成,为什么循迹小车能够追踪黑线轨迹呢? 智能小车在画有黑线的白纸 "路面"上行驶,由于黑线和白纸对光 ...

  7. 基于arduino的5路循迹小车(1)

    基于arduino的5路循迹小车(1) 初步小车运动 1.硬件选用 1.开发板使用arduino 2560 2.电机驱动板使用 大功率电机驱动板(PWM由两个端子控制) 3.电源12V锂电池 4.降压 ...

  8. 基于arduino的5路循迹小车(2)

    基于arduino的5路循迹小车(2) 小车5路红外循线 接第一篇链接 https://blog.csdn.net/weixin_45984029/article/details/103437347 ...

  9. 基于arduino的5路循迹小车(4)与舵机控制板的通信控制

    基于arduino的5路循迹小车(4) arduino与舵机控制板的通信控制 以及语音播报模块 接第一篇链接 https://blog.csdn.net/weixin_45984029/article ...

最新文章

  1. 覆盖10亿设备,月活2亿,快应用要取代App?
  2. ICMP重定向(ICMP Redirect)
  3. PL/SQL学习笔记-过程
  4. 催收成本在单体经济中的分析
  5. emacs 跳转到指定行
  6. 事件查看器ID 1041
  7. 百分之六的谷歌云存储桶因配置错误而遭任意访问
  8. fedora 主题美化
  9. linux环境配置以及远程登录linux
  10. 【SVN】Win 10:SVN 下载、安装和汉化
  11. vs 2010 sp1 中文版 安装sliverlight 5 正式版
  12. mac下使用ipv6观看电视
  13. 勤学修身 放飞梦想4
  14. deepin网速慢 自己摸索 已解决
  15. 使用Aura.Router在PHP中进行Web路由
  16. 【C++基础】头文件定义问题导致的重定义问题
  17. gitbook 快速入门
  18. 灰度(金丝雀)发布、蓝绿部署、滚动发布
  19. 直流电路中升降压(Buck-Boost)变换电路的设计、参数选取及Matlab/Simulik仿真
  20. lambda表达式和方法引用

热门文章

  1. 锐捷云课堂服务器装什么系统,锐捷云课堂2.0系列产品详细介绍
  2. C语言验证四色定理并输出所有染色方案
  3. 腾讯绝不会开放客户端QQ
  4. 麦肯锡报告翻译:《超越狂欢:区块链的商业战略价值是什么?》
  5. 什么是神经元网络控制?,什么是神经网络控制?
  6. JAVA泛型及常用内库
  7. PHP设计模式之实体属性值模式(EAV 模式)代码实例大全(35)
  8. CATIA V5塑胶模具设计全套视频教程
  9. 企业网站的全能保镖——华为云网站安全解决方案
  10. 万年历系统c语言程序设计报告,万年历C程序设计报告