# 循迹模块

## 1.0 模块介绍

### 1.1 名称

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

### 1.2 图片

<figure><img src="/files/xiuQdEohJVObFYxBPrWP" alt=""><figcaption></figcaption></figure>

### 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[代码](https://github.com/NJURobotClub/arduino_2019/blob/main/week6/xunji.ino)

```
/* 宏定义部分
*******************************************************************/
#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);
}

```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://nju-robot-club.gitbook.io/arduino/week6/xun-ji-mo-kuai.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
