循迹小车程序(三路循迹)
- 格式:docx
- 大小:12.89 KB
- 文档页数:8
智能循迹避障小车完整程序(亲测好使)/*******************************************//利用51定时器产生PWM波来调节电机速度//速度变化范围从0-100可调//使用三路做寻迹使用,哪一路检测在黑线哪一路为//高电平//没检测到黑线表示有反射对应输出低电平信号*********************************************/#include<>#define uint unsigned int#define uchar unsigned char/*电机四个接口定义*/sbit in1=P0^0;sbit in2=P0^1;sbit in3=P0^2;sbit in4=P0^3;/*计时器*/uchar j,k,i,a,A1,A2,second,minge,minshi;sbit dula=P2^6;sbit wela=P2^7;uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};uchar code table2[]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef,0xf7,0xfc,0xb9,0xde,0xf9,0xf1};void delay(uchar i){for(j=i;j>0;j--)for(k=110;k>0;k--);}void display(uchar sh_c,uchar g_c,uchar min_ge,uchar min_shi) {dula=1;P0=table[sh_c];dula=0;P0=0xff;wela=1;P0=0xfb;wela=0;delay(5);dula=1;P0=table[g_c];dula=0;P0=0xff;wela=1;P0=0xf7;wela=0;delay(5);dula=1;P0=table[min_shi];dula=0;P0=0xff;wela=1;P0=0xfe;wela=0;delay(5);dula=1;P0=table2[min_ge];dula=0;P0=0xff;wela=1;P0=0xfd;wela=0;delay(5);}/*左、中、右三路循迹传感器接口定义*/ sbit zuo=P1^0; sbit zhong=P1^1;sbit you=P1^2;/*避障接口定义*/sbit bz_zuo=P1^3;sbit bz_zhong=P1^4;sbit bz_you=P1^5;uchar count = 0;/*利用定时器0定时中断,产生PWM波*/ void Init_timer() {TH0 = (65535-10)/256;TL0 = (65535-10)%256;TMOD = 0x01;TR0 = 1;ET0 = 1;EA = 1;}/*左轮速度调节程序*/void zuolun(uchar speed){if(count <= speed) //count计数变量{in1 = 1;in2 = 0;}else{in1 = 0;in2 = 1;}}void youlun(uchar speed) //同上{if(count<= speed){in3 = 1;in4 = 0;}else{in3 = 0;in4 = 1;}}void Inline() //检测黑线信号{uchar temp;temp =P1;switch(temp){case 0x01:zuolun(0); youlun(90);break; //左侧循迹传感器压线,小车向左前修正case 0x02:zuolun(100);youlun(100);break; //中间循迹传感器压线,保持直走此处两值使电机速度保持相同case 0x04:zuolun(90); youlun(0);break; //右侧循迹传感器压线,小车向右前修正case 0x08:zuolun(90); youlun(0);break; //左侧避障传感器有信号小车右转case 0x10:zuolun(90); youlun(0);break; //中间避障传感器有信号小车左转case 0x20:zuolun(90); youlun(0);break; //右侧避障传感器有信号小车左转}/*if(zuo==1){zuolun(10);youlun(50);}else if(zhong==1){zuolun(99);youlun(99);}else if(you==1){zuolun(50);youlun(10);} */}void main() //主函数{Init_timer(); //调用函数while(1){Inline();minge=0;minshi=0;second++;if(second==60)second=0,minge++;A1=second/10;A2=second%10;if(minge==10)minge=0,minshi++;for(a=200;a>0;a--){display(A1,A2,minge,minshi);};}}void Timer0_int()interrupt 1 //定时器中断计数{TH0 = (65535-10)/256;TL0 = (65535-10)%256;count ++;if(count >= 100){count = 0;}}。
河北联合大学
电气工程学院
生产实习报告
专业自动化
姓名张桂平
学号************ 指导教师沈小伟
2013年7月1日
单片机最小系统
2. 电源模块:
模型车通过自身系统,采集赛道信息,获取自身速度信息,加以处理,由芯片给出指令控制其前进转向等动作,各部分都需要由电路支持,电源管理尤为重要。
在本设计中,51单片机使用5V电源,电机及舵机使用6V电源。
考虑到电源为充电电池组,额定电压为7.2V,实际充满电后电压则为6.5-6.8V,所以单片机及传感器模块采用7805稳压后的5V电源供电,电机直接由电池供电。
3.路面检测电路:
路面检测电路由5对光电发送与接收管组成。
由于路面存在黑色引导线,落在黑线区域内的光电接收管接收到反射的光线的强度与白色的路面不同,进而在光电接收管两端产生不同的电压值,由此判断路线的走向。
传感器模块将当前采集到的一组电压值传递给单片机,进而根据一定的算法对电机进行控制,使小车自动寻线行走。
下图是路面检测电路图:。
2012循迹小车规则
1,比赛分三轮,按我们安排的顺序,每一队参赛小车有三次比赛机会。
2,小车赛跑场地,由比赛当天公布。
必须按照路线跑。
跑出线外3次,立刻结束这一轮比赛。
3,如果没有成功跑完全程,成绩按照所跑长度记录;如果成功跑完,按照跑完的时间记录成绩。
如图,若小车在第7区跑到线外则成绩记录为7。
4,最终成绩有三部分组成。
1)电路板元件布局合理,线条美观;占权重10%(评分总分为10)
2)车体设计美观;占权重20%(评分总分为20)
3)赛跑成绩;占权重70%,按照全部排名,总分71;若第一名,则该部分得分为71-1=70;
三部分分数加起来,然后进行总排名。
5,不使用协会提供的原理图,只要实现相同功能的车可以参赛。
但必须无人操作,杜绝遥控等场外控制小车。
6,
奖项设置:
一等奖(1名):奖状+高端单片机开发板一套(自选C51或STM32系列)
二等奖(2名):奖状+中端单片机开发板一套(自选C51或STM32系列)
三等奖(3名):奖状+单片机最小系统板(自选C51或STM32系列)
优胜奖(成功参赛):奖状+精美礼品
附图:黑实线为实际跑道,细实线区为积分区。
前点
终点
5
1
2
3 4。
小车循迹的pid算法小车循迹的PID算法引言:小车循迹是指通过感知地面上的黑线或者白线,使小车能够沿着线路行驶。
为了实现精确的循迹,PID算法被广泛应用于小车循迹控制中。
本文将介绍PID算法的原理和应用于小车循迹的具体实现。
一、PID算法原理PID算法是一种基于反馈控制的算法,其全称为比例-积分-微分控制算法。
其基本原理是通过不断调整输出信号,使系统的输出值尽量接近给定的目标值。
1. 比例控制(Proportional Control):比例控制是根据当前误差的大小来调整输出信号。
当误差较大时,输出信号也会相应增大;当误差较小时,输出信号也会相应减小。
这样可以实现系统的快速响应。
2. 积分控制(Integral Control):积分控制是根据误差的累积值来调整输出信号。
当误差持续存在时,积分项会逐渐增大,从而加大输出信号,以消除积累误差。
积分控制可以解决系统静差的问题。
3. 微分控制(Derivative Control):微分控制是根据误差的变化率来调整输出信号。
当误差的变化率较大时,输出信号也会相应增大;当误差的变化率较小时,输出信号也会相应减小。
微分控制可以提高系统的稳定性和抑制振荡。
二、PID算法在小车循迹中的应用小车循迹是指通过感知地面上的黑线或者白线,使小车能够沿着线路行驶。
PID算法可以根据当前的线路位置误差来调整小车的转向角度,从而实现循迹控制。
1. 感知线路:小车循迹需要通过感知地面上的黑线或者白线来判断当前的位置误差。
通常使用光敏电阻或红外传感器来感知地面的亮度,并将其转换为电信号。
2. 计算误差:根据感知到的线路信息,可以计算出当前的位置误差。
位置误差可以定义为小车当前位置与目标位置之间的距离差。
3. 调整转向角度:根据计算得到的位置误差,可以使用PID算法来调整小车的转向角度。
比例控制项可以根据位置误差的大小来调整转向角度;积分控制项可以消除积累误差,使小车能够更好地沿着线路行驶;微分控制项可以提高系统的稳定性,防止小车出现过大的震荡。
三路红外循迹模块介绍红外循迹技术是一种常见的机器人导航和自动驾驶技术,它通过利用红外线传感器来检测地面上的红外线信号,实现对机器人运动方向的控制。
三路红外循迹模块是一种基于红外循迹技术的控制模块,它通常由红外线传感器、控制电路和连接接口等组成。
下面将对三路红外循迹模块的工作原理、应用领域以及使用注意事项进行详细介绍。
一、工作原理三路红外循迹模块通过红外线传感器探测地面上的红外线反射信号,从而确定机器人当前位置和运动方向。
模块通常配备了三个红外线传感器,分别位于机器人的左、中、右三个方向。
当机器人在循迹路径上行驶时,红外线传感器会检测到地面上的红外线反射信号并产生相应的电信号。
根据三路传感器的信号强度,可以确定机器人相对于循迹路径的位置以及需要调整的运动方向。
通过对传感器信号的处理和控制电路的反馈,三路红外循迹模块可以实现对机器人的精确控制和导航。
二、应用领域三路红外循迹模块广泛应用于机器人导航、智能小车、无人机等领域。
在机器人导航中,三路红外循迹模块可以帮助机器人实现自主避障和自动寻路功能,提高机器人的导航能力和智能化水平。
在智能小车领域,三路红外循迹模块可以用于控制小车沿着指定路径行驶,实现自动驾驶和遥控驾驶功能。
在无人机领域,三路红外循迹模块可以用于控制无人机在空中精确飞行,实现自主导航和巡航功能。
三、使用注意事项1. 红外线传感器的灵敏度和角度范围需要根据具体应用场景进行调整和配置,以确保传感器能够准确检测到地面上的红外线信号。
2. 红外线传感器需要与控制电路进行连接,通常通过数字引脚或模拟引脚进行数据传输和控制信号的交互。
3. 三路红外循迹模块的控制电路需要根据具体需求进行编程和调试,以确保模块能够正确识别红外线信号并实现准确的导航控制。
4. 在使用过程中,应注意避免模块与其他电子元件的干扰,以免影响红外线传感器的探测效果和模块的正常工作。
5. 在安装和使用过程中,应注意保护红外线传感器,避免受到外界光线、灰尘或其他物体的干扰,以确保传感器的准确性和稳定性。
arduino智能循迹⼩车代码(三个循迹模块)#include <Servo.h>int leftMotor1 = 3;int leftMotor2 = 5;int rightMotor1 = 6;int rightMotor2 = 11;int sum=0;void setup() {Serial.begin(9600);pinMode(leftMotor1, OUTPUT);pinMode(leftMotor2, OUTPUT);pinMode(rightMotor1, OUTPUT);pinMode(rightMotor2, OUTPUT);pinMode(A0, INPUT);pinMode(A1, INPUT);pinMode(A2, INPUT);}void loop() {tracing();}void tracing(){int data[4];data[0]=analogRead(A0);data[1]=analogRead(A1);data[2]=analogRead(A2);if(data[0]<210&&data[1]>500&&data[2]<210)//向前⾛{analogWrite(3,100);analogWrite(5,0);analogWrite(6,100);analogWrite(11,0);}if(data[0]>500 &&data[1]<210 && data[2]<210) // ⼩车偏左{analogWrite(3,0);analogWrite(5,0);analogWrite(6,120);analogWrite(11,0);}if(data[0]>500&&data[1]>500&&data[2]<210) //⼩车偏⼤左{analogWrite(3,0);analogWrite(5,120);analogWrite(6,120);analogWrite(11,0);}if(data[0]<210&&(data[1]-30)<210&&data[2]>500) //⼩车偏右{analogWrite(3,120);analogWrite(5,0);analogWrite(6,0);analogWrite(11,0);}if(data[0]<210&&data[1]>500&&data[2]>500) //⼩车偏⼤右{analogWrite(3,120);analogWrite(5,0);analogWrite(6,0);analogWrite(11,120);}if(data[0]>500&&data[1]>500&&data[2]>500) //左右都检测到⿊线是停⽌{analogWrite(3,0);analogWrite(5,0);analogWrite(6,0); analogWrite(11,0);}Serial.print(data[0]); Serial.print("---"); Serial.print(data[1]-30); Serial.print("---"); Serial.print(data[2]); Serial.print("---"); Serial.println(data[3]); }。
附录程序目录一、前言------------------------------------------------------------二、小车功能------------------------------------------------------三、元器件选择--------------------------------------------------四、 I/O分配及硬件连接简图---------------------------------五、相关模块、算法---------------------------------------------六、系统框图------------------------------------------------------七、调试过程------------------------------------------------------八、小车图片资料---------------------------------------------------九、讲座所感------------------------------------------------------十、实习总结------------------------------------------------------一、前言感生产实习能给我们这次实现自己想法的机会,虽然实验条件异常简陋、资金投入非常有限,总体感觉我的队友们灰常灰常给力啊,我感觉我是抱到大腿了--王威,夏青、峰哥,团队气氛非常好,大家一起讨论,一起分工研究模块,最后一起解决问题调试程序,而且是不同的组合在不同阶段解决了不同的问题,大家合作,各显身手,在奋战中给大三学年画上了圆满的句号。
之前我们本来商量是不是可以拿往年电子设计大赛的题目过来做,如果难度太大就算只实现一部分功能也算是成功完成了,结果研究一天后发现电子设计大赛的题目需要很长时间的知识积累啊,基本上都是准备一个月以上然后开工的,后来王威提议要不我们做个小车吧,超声波测距实现自动物体追踪,控制核心采用单片机,传感器采用广泛用于避障和测距的超声波传感器,前进和后退用普通伺服电机和电机驱动模块实现。
/************************************************************************** **简单寻迹程序:P1_0 P1_1 接IN1 IN2 当P1_0=1,P1_1=0; 时左上电机正转左上电机接驱动板子输出端(蓝色端子OUT1 OUT2)P1_0 P1_1 接IN1 IN2 当P1_0=0,P1_1=1; 时左上电机反转P1_0 P1_1 接IN1 IN2 当P1_0=0,P1_1=0; 时左上电机停转P1_2 P1_3 接IN3 IN4 当P1_2=1,P1_3=0; 时左下电机正转左下电机接驱动板子输出端(蓝色端子OUT3 OUT4)P1_2 P1_3 接IN3 IN4 当P1_2=0,P1_3=1; 时左下电机反转P1_2 P1_3 接IN3 IN4 当P1_2=0,P1_3=0; 时左下电机停转P1_4 P1_5 接IN5 IN6 当P1_4=1,P1_5=0; 时右上电机正转右上电机接驱动板子输出端(蓝色端子OUT5 OUT6)P1_4 P1_5 接IN5 IN6 当P1_4=0,P1_5=1; 时右上电机反转P1_4 P1_5 接IN5 IN6 当P1_4=0,P1_5=0; 时右上电机停转P1_6 P1_7 接IN7 IN8 当P1_6=1,P1_7=0; 时右下电机正转右下电机接驱动板子输出端(蓝色端子OUT7 OUT8)P1_6 P1_7 接IN7 IN8 当P1_6=0,P1_7=1; 时右下电机反转P1_6 P1_7 接IN7 IN8 当P1_6=0,P1_7=0; 时右下电机停转P3_2接三路寻迹模块接口第一路输出信号即中控板上面标记为OUT1P3_3接三路寻迹模块接口第二路输出信号即中控板上面标记为OUT2P3_4接三路寻迹模块接口第三路输出信号即中控板上面标记为OUT3三路寻迹传感器有信号(白线)为0 没有信号(黑线)为1三路寻迹传感器电源+5V GND 取自于单片机板靠近液晶调节对比度的电源输出接口*************************************************************************** */#include<AT89x52.H>#define Left_led P3_2 //P3_4接四路寻迹模块接口第一路输出信号即中控板上面标记为OUT1#define Among_led P3_3 //P3_5接四路寻迹模块接口第二路输出信号即中控板上面标记为OUT2#define Right_led P3_4 //P3_6接四路寻迹模块接口第三路输出信号即中控板上面标记为OUT3#define Back_Left_led P3_5 //P3_7接四路寻迹模块接口第四路输出信号即中控板上面标记为OUT4#define Back_Among_led P3_6 //P3_6接四路寻迹模块接口第五路输出信号即中控板上面标记为OUT5#define Back_Right_led P3_7 //P3_7接四路寻迹模块接口第六路输出信号即中控板上面标记为OUT6#define Left_moto_go {P1_0=1,P1_1=0,P1_2=1,P1_3=0;} //左边两个电机向前走#define Left_moto_back {P1_0=0,P1_1=1,P1_2=0,P1_3=1;} //左边两个电机向后转#define Left_moto_Stop {P1_0=0,P1_1=0,P1_2=0,P1_3=0;} //左边两个电机停转#define Right_moto_go {P1_4=1,P1_5=0,P1_6=1,P1_7=0;} //右边两个电机向前走#define Right_moto_back {P1_4=0,P1_5=1,P1_6=0,P1_7=1;} //右边两个电机向前走#define Right_moto_Stop {P1_4=0,P1_5=0,P1_6=0,P1_7=0;} //右边两个电机停转/************************************************************************///延时函数void delay(unsigned int k){unsigned int x,y;for(x=0;x<k;x++)for(y=0;y<2000;y++);}/************************************************************************///前速前进void run(void)Left_moto_go ; //左电机往前走Right_moto_go ; //右电机往前走}//前速后退void backrun(void){Left_moto_back ; //左电机往前走Right_moto_back ; //右电机往前走}//左转void leftrun(void){Left_moto_back ; //左电机往前走Right_moto_go ; //右电机往前走}//右转void rightrun(void){Left_moto_go ; //左电机往前走Right_moto_back ; //右电机往前走}void stop(void){Left_moto_Stop ; //左电机往前走Right_moto_Stop; //右电机往前走}/*********************************************************************//*********************************************************************/ /*--主函数--*/void main(void)unsigned char flag1=0,flag2=0;delay(100);while(1){if(flag1==1&&flag2==1) //后传感碰到起始黑线,前传感碰到终点黑线{if(Back_Left_led==0&&Back_Among_led==0&&Back_Right_led==0)//三个传感器没检测到黑线backrun();else if(Back_Left_led==0&&Back_Among_led==0&&Back_Right_led==1) //右边检测到黑线{rightrun();}else if(Back_Left_led==0&&Back_Among_led==1&&Back_Right_led==0) //中间检测到黑线{run();}else if(Back_Left_led==0&&Back_Among_led==1&&Back_Right_led==1) //右边检测到黑线{rightrun();}else if(Back_Left_led==1&&Back_Among_led==0&&Back_Right_led==0) //左边检测到黑线{leftrun();}else if(Back_Left_led==1&&Back_Among_led==0&&Back_Right_led==1) //两边检测到黑线,中间检测不到信号{stop();}else if(Back_Left_led==1&&Back_Among_led==1&&Back_Right_led==0) //左边检测到黑线{leftrun();}else //三个传感器检测到黑线{stop();}}else //后传感碰到起始黑线,前传感没有碰到终点黑线{flag2=1;if(Left_led==0&&Among_led==0&&Right_led==0)//三个传感器没有检测到黑线run();else if(Left_led==0&&Among_led==0&&Right_led==1)//右边检测到黑线{rightrun();}else if(Left_led==0&&Among_led==1&&Right_led==0)//中间检测到黑线{run();}else if(Left_led==0&&Among_led==1&&Right_led==1)//右边检测到黑线{rightrun();}else if(Left_led==1&&Among_led==0&&Right_led==0)//左边检测到黑线{leftrun();}else if(Left_led==1&&Among_led==0&&Right_led==1)//两边检测到黑线,中间检测不到信号{stop();}else if(Left_led==1&&Among_led==1&&Right_led==0)//左边检测到黑线{leftrun();}else if(Left_led==1&&Among_led==1&&Right_led==1) //三个传感器检测到黑线{stop(); delay(500);flag1=1;}}}}。
arduino三路循迹原理
Arduino三路循迹原理主要是基于红外传感器的工作原理。
这种循迹模块通常具有多个引脚,包括VCC、GND和多个信号输出引脚,每个引脚对应不同的红外传感器。
在循迹模块中,红外发射管发出红外线,当遇到白色地面或其他可以反射红外光的物体时,红外线会被反射回来,被红外接收管接收;如果遇到黑色地面或其他可以吸收红外光的物体,红外线则会被吸收,红外接收管接收不到信号。
三路循迹模块具有三个红外传感器,每个传感器可以检测其下方的地面颜色。
通常情况下,我们将这三个传感器分别接在Arduino的三个数字引脚上,通过读取这三个引脚的电平状态,就可以判断小车当前的位置以及应该行驶的方向。
具体来说,如果中间传感器的引脚读到高电平(表示检测到黑色轨迹),那么说明小车正在轨迹上行驶,应保持当前方向不变;如果左边或右边传感器的引脚读到高电平(表示检测到黑色轨迹),则说明小车偏离了轨迹,需要向相应方向调整,以使小车重新回到轨迹上。
通过编写相应的代码,我们就可以实现小车的自动循迹功能。
这种循迹方式简单易行,成本低廉,因此在智能小车、机器人等领域得到了广泛的应用。
#include "reg51.h"
typedef unsigned int uint;
typedef unsigned char uchar;
sbit p2_0 = P2^0; //开关
sbit p2_1 = P2^1; //红外检测
sbit p2_2 = P2^2;
sbit p2_3 = P2^3;
sbit p1_0 = P1^0; //电机驱动
sbit p1_1 = P1^1;
sbit p1_2 = P1^2;
sbit p1_3 = P1^3;
sbit pwm1 = P1^4; //pwm调速
sbit pwm2 = P1^5;
unsigned char timer1;
/******************************************************************** ***********
* 函数名 : Time1Config
* 函数功能 : 设置定时器
* 输入 : 无
* 输出 : 无
********************************************************************* **********/
void Time1Config()
{
TMOD|= 0x10; //设置定时计数器工作方式1为定时器
//--定时器赋初始值,12MHZ下定时0.5ms--//
TH1 = 0xFE;
TL1 = 0x0C;
ET1 = 1; //开启定时器1中断
EA = 1;
TR1 = 1; //开启定时器
}
/************************************************ 延时函数
总共延时
1ms
乘以
count
************************************************/ void DelayX1ms(uint count)
{
uint j;
while(count--!=0)
{
for(j=0;j<72;j++);
}
}
/************************************************ 电机转动函数定义
************************************************/ void ZhiXing( )
{
p1_0=0;
p1_1=0;
p1_2=0;
p1_3=0;
DelayX1ms(10);
p1_0=0;
p1_1=1;
p1_2=0;
p1_3=1;
DelayX1ms(15);
}
void ZuoZhuan( )
{
pwm1=0;
pwm2=0;
DelayX1ms(10); p1_0=0;
p1_1=1;
p1_2=1;
p1_3=0;
DelayX1ms(20); }
void YouZhuan( )
{
pwm1=0;
pwm2=0;
DelayX1ms(10);
p1_0=1;
p1_1=0;
p1_2=0;
p1_3=1;
DelayX1ms(20); }
void HouTui( )
{
p1_0=0;
p1_1=0;
p1_2=0;
p1_3=0;
DelayX1ms(6); p1_0=1;
p1_1=0;
p1_2=1;
p1_3=0;
DelayX1ms(20);
}
/************************************************ 主函数
************************************************/ void main( )
{
Time1Config();
while(1)
{
if( p2_1==0 && p2_2==0 && p2_3==1)
{
YouZhuan( );
}
else if(p2_1==1 && p2_2==0 && p2_3==0)
{
ZuoZhuan( );
}
else
{
ZhiXing( );
}
}
}
/******************************************************************** ***********
* 函数名 : Time1
* 函数功能 : 定时器1的中断函数
* 输入 : 无
* 输出 : 无
********************************************************************* **********/
void Time1(void) interrupt 3 //3 为定时器1的中断号 1 定时器0的中断号 0 外部中断1 2 外部中断2 4 串口中断
{
timer1++;
if(timer1>100) //PWM周期为100*0.5ms
{
timer1=0;
}
if(timer1 < 85) //改变30这个值可以改变直流电机的速度
{
pwm1=1;
pwm2=1;
}
else
{
pwm1=0;
pwm2=0;
}
TH1 = 0xFE; //重新赋初值
TL1 = 0x0C;
}。