循迹模块

1.0 模块介绍

1.1 名称

循迹模块TCRT5000红外反射传感器

1.2 图片

1.3 功能

1.31 Vcc和GND

分别接5v接口和地

1.32 D0

TTL开关信号输出

1.33 A0

模拟信号输出(不同距离输出不同电压,此脚一般不接)

1.34 作用原理

传感器的红外发射二极管不断发射红外线,当发射出的红外线没有被反射回来或者反射回来但是强度不够大时,红外接收管一直处于关断状态,此时模块的输出端为高电平,指示二极管一直处于熄灭状态,被检测物体出现在检测范围时,红外线被反射回来且强度足够大,红外接收管饱和,此时模块的输出端为低电平,指示二极管被点亮

2.0 操作以及代码示例

2.1操作

2.11数量

2个模块,左右各一个

2.12接线

vcc和GND接上相应5v和地,一个模块的A0接arduino板的A5,另一个模块的A0接arduino板的A6

2.2代码示例

2.21代码

/* 宏定义部分
*******************************************************************/
#define Vo 80// Vo (0-255)
#define k 2     //k (0-10)
/***********************************************************************
*******/
/* 变量声明部分
*****************************************************************/
const int trigPin = 8; // the number of the trigger output pin
const int echoPin = 7; // the number of the echo input pin
////////////////////////////////// variables used for distance calculation 
long duration;                               
int distance; 
float r;
int IN[4]={5,3,6,9};
//单片机上的 D5、D3、D6、D9 分别连驱动模块上的 IN1、IN2、IN3、IN4 
int p1,p2,p;//来反应光强的 
int last_proportional = 0;//上一个比例项 
//long integral = 0;//积分 
int proportional,derivative,power_difference;//比例,导数,差异 
int maxspeed=255;//8 位的芯片 0-255 共 256=2^8 个 
/***********************************************************************
*******
/* 自写函数部分
*****************************************************************/
int readl(){ //read 读取光电管反映的“光强“
p1=analogRead(A6);//读取模拟信号,读取数字信号为 digitalRead(端口)
p2=analogRead(A5); 
p=p1-p2; 
return p;//返回值为“光强差” 
} 
void motor(int speed2,int speed1){ //驱动电机 speed1 右边的速度,speed2 左边的速度 
int s1,s2,s3,s4;
if(speed1<0){//右 
s1=0;
s2=1;
} 
else{
s1=1;
s2=0;
} 
digitalWrite(IN[s1],LOW); 
//数字信号写入,给 IN[s1]所代表的端口(D5 或 D3)写入低电平,高电平为 HIGH 
analogWrite(IN[s2],abs(speed1));
//模拟信号写入,给 IN[s2] 所代表的端口(D3 或 D5)写入一定的电平
if(speed2<0){//左
s3=3;
s4=2;
}
else{
s3=2;
s4=3;
}
digitalWrite(IN[s3],LOW);
//数字信号写入,给 IN[s3]所代表的端口(D6 或 D9)写入低电平,高电平为 HIGH 
analogWrite(IN[s4],abs(speed2));
//模拟信号写入,给 IN[s4] 所代表的端口(D9 或 D6)写入一定的电平
}
void pid(int max_speed){
proportional = readl();//p"光强差"
Serial.println(proportional);
//derivative = proportional-last_proportional;//导数(变化量)
//integral+= proportional;//积分+8
last_proportional = proportional;
power_difference = proportional*k;// + integral/20000 + derivative*3/4; 
//power_difference = proportional*5;
/*这个是学长给的程序,刚开始应有 PID 算法的,后来就只剩下 P(比例了),有兴
趣的
可以把后面加上调参数 PID 指 proportional 比例、integral 积分、derivative 导数 */
if(power_difference > max_speed)
power_difference = max_speed;
if(power_difference < -max_speed)
power_difference = -max_speed;
if(power_difference<0)
motor(max_speed+power_difference,max_speed);//左右 p<0 左拐
else
motor(max_speed,max_speed-power_difference);//左右 p>=0 右拐或不拐
delay(30);
motor(max_speed,max_speed);
}

void find_distance(void)                   
{ 
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);
  duration = pulseIn(echoPin, HIGH, 5000);
  r = 3.4 * duration / 2;                  // calculation to get the measurement in cm using the time returned by the pulsein function.     
  distance = r / 100.00;
  delay(50);
}
void walk(int aim_distance)
{
  distance=0;
  find_distance();
  Serial.println(distance);
  if(distance>aim_distance){
    motor(-100,-100);
  }
  else{
    motor(0,0);
  }
}
/***********************************************************************
*******/
/* 固有两个函数部分
*************************************************************/ 
void setup() {
//setup 函数只执行一次
//设置 D5,D3,D6,D9 为输出引脚,定义输入引脚为 INPUT
/*另外,A5 和 A6 是模拟信号的串口,单片机是不能输出模拟信号,
所以模拟信号串口只能做输入端,故就无需设置了 */ 
pinMode(IN[0],OUTPUT);
pinMode(IN[1],OUTPUT);
pinMode(IN[2],OUTPUT);
pinMode(IN[3],OUTPUT);
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
Serial.begin(9600);//设置波特率,串口之间通信要用的,我也不清楚这种东西
}
void loop() { 
//loop 函数反复执行
pid(Vo);
//walk(30);
}

Last updated