零知四轮小车入门版(ESP32主控)教程5-红外循迹

本系列教程讲解零知小车套件以零知esp32为主控,使用零知开源平台进行智能小车开发。

使用的硬件:零知智能小车套件

实现的功能:红外循迹、超声避障、直线运行、手机蓝牙控制等基本功能。

扩展:可以在小车上加入其它传感器模块进行扩展,比如加入摄像头模块进行监控、加入火焰传感器做灭火小车、加入更多超声波模块实现自动跟随...


本系列教程目录

零知四轮小车入门版(零知esp32主控)系列教程-小车组装


零知四轮小车入门版(零知esp32主控)系列教程-程序控制电机开跑


零知四轮小车入门版(零知esp32主控)系列教程-加入蓝牙实现手机控制


零知四轮小车入门版(零知esp32主控)系列教程-红外循迹走S弯


零知四轮小车入门版(零知esp32主控)系列教程-超声波自动避障


一、准备工作

我们需要如下工具和材料:

(1)组装好的智能小车


二、程序代码

循迹小车是利用小车前面的红外循迹模块感应地面上的白色线条来控制小车左右轮子的速度进行转弯的,实现代码如下所示

							
							
	/**********************************************************
	*    文件: 4WD_xunji.ino      by 零知实验室([url=http://www.lingzhilab.com]www.lingzhilab.com[/url])
	*    -^^- 零知开源,让电子制作变得更简单! -^^-
	*    时间: 2019/12/02 15:07
	*    说明:
	************************************************************/
	//设置电机引脚
	#define LEFT_MOTO1  27
	#define LEFT_MOTO2  14
	#define LEFT2_MOTO1 33
	#define LEFT2_MOTO2 32
	#define RIGHT_MOTO1 12
	#define RIGHT_MOTO2 13
	#define RIGHT2_MOTO1 26
	#define RIGHT2_MOTO2 25
	  
	//寻迹模块引脚
	#define XUNJI1 17
	#define XUNJI2 16
	#define XUNJI3 4
	#define XUNJI4 2
	#define XUNJI5 15
	  
	//循迹转弯调整
	#define Speed        140
	#define TraceLSpeed  80
	#define TraceHSpeed  120
	#define TraceSpeed   20
	  
	//循迹的颜色,非黑即白
	#define BLACK 0
	#define WHITE 1
	  
	//黑底白线,若白底黑线,请调换颜色
	#define LINE    WHITE
	#define GROUND  BLACK
	  
	// 复位或上电后运行一次:
	void setup() {
	        //在这里加入初始化相关代码,只运行一次:
	        Serial.begin(9600);
	        pinMode(LEFT_MOTO1,OUTPUT);
	        pinMode(LEFT_MOTO2,OUTPUT);
	        pinMode(LEFT2_MOTO1,OUTPUT);
	        pinMode(LEFT2_MOTO2,OUTPUT);
	        pinMode(RIGHT_MOTO1,OUTPUT);
	        pinMode(RIGHT_MOTO2,OUTPUT);
	        pinMode(RIGHT2_MOTO1,OUTPUT);
	        pinMode(RIGHT2_MOTO2,OUTPUT);
	          
	        //设置引脚输出PWM的通道
	        ledcAttachPin(LEFT_MOTO1,1);
	        ledcAttachPin(LEFT_MOTO2,2);
	        ledcAttachPin(LEFT2_MOTO1,3);
	        ledcAttachPin(LEFT2_MOTO2,4);
	        ledcAttachPin(RIGHT_MOTO1,5);
	        ledcAttachPin(RIGHT_MOTO2,6);
	        ledcAttachPin(RIGHT2_MOTO1,7);
	        ledcAttachPin(RIGHT2_MOTO2,8);
	        ledcSetup(1, 12000, 8);
	        ledcSetup(2, 12000, 8);
	        ledcSetup(3, 12000, 8);
	        ledcSetup(4, 12000, 8);
	        ledcSetup(5, 12000, 8);
	        ledcSetup(6, 12000, 8);
	        ledcSetup(7, 12000, 8);
	        ledcSetup(8, 12000, 8);
	          
	        pinMode(XUNJI1,INPUT);
	        pinMode(XUNJI2,INPUT);
	        pinMode(XUNJI3,INPUT);
	        pinMode(XUNJI4,INPUT);
	        pinMode(XUNJI5,INPUT);
	          
	}
	  
	//一直循环执行:
	void loop() {
	        // 在这里加入主要程序代码,重复执行:
	        lineTrace();  //自动循迹
	}
	  
	//控制电机,正值前进,复制后退
	void motoRun(int speedL,int speedR){
	        if(speedL>0){
	                ledcWrite(1,0);
	                ledcWrite(2,speedL);
	                ledcWrite(3,0);
	                ledcWrite(4,speedL);
	        }else{
	                ledcWrite(1,-speedL);
	                ledcWrite(2,0);
	                ledcWrite(3,-speedL);
	                ledcWrite(4,0);
	        }
	        if(speedR>0){
	                ledcWrite(5,0);
	                ledcWrite(6,speedR);
	                ledcWrite(7,0);
	                ledcWrite(8,speedR);
	        }else{
	                ledcWrite(5,-speedR);
	                ledcWrite(6,0);
	                ledcWrite(7,-speedR);
	                ledcWrite(8,0);
	        }
	          
	}
	  
	//停车
	void motoStop(){
	        ledcWrite(1,0);
	        ledcWrite(2,0);
	        ledcWrite(3,0);
	        ledcWrite(4,0);
	        ledcWrite(5,0);
	        ledcWrite(6,0);
	        ledcWrite(7,0);
	        ledcWrite(8,0);
	}
	  
	void lineTrace()
	{
	        //读取红外寻迹模块的状态
	        int IR_1 = digitalRead(XUNJI1);
	        int IR_2 = digitalRead(XUNJI2);
	        int IR_3 = digitalRead(XUNJI3);
	        int IR_4 = digitalRead(XUNJI4);
	        int IR_5 = digitalRead(XUNJI5);
	        Serial.println("—————————————");
	        char c[256];
	        sprintf(c,"%d   %d   %d   %d   %d",IR_1,IR_2,IR_3,IR_4,IR_5);
	        Serial.println(c);
	        //delay(500);
	          
	          
	        //00 00  直行
	        if(IR_1 == GROUND && IR_2 == GROUND && IR_4 == GROUND && IR_5 == GROUND){
	                motoRun(Speed,Speed);
	                Serial.println("直行");
	        }
	        //01 00  小左转
	        if(IR_1 == GROUND && IR_2 == LINE && IR_4 == GROUND && IR_5 == GROUND){
	                motoRun(TraceSpeed,TraceLSpeed);  //若效果不理想可调整参数
	                Serial.println("小左转");
	        }
	        //10 00  大左转
	        if(IR_1 == LINE && IR_2 == GROUND && IR_4 == GROUND && IR_5 == GROUND){
	                motoRun(TraceSpeed,TraceHSpeed);
	                Serial.println("大左转");
	        }
	        //00 10  小右转
	        if(IR_1 == GROUND && IR_2 == GROUND && IR_4 == LINE && IR_5 == GROUND){
	                motoRun(TraceLSpeed,TraceSpeed);
	                Serial.println("小右转");
	        }
	        //00 01  大右转
	        if(IR_1 == GROUND && IR_2 == GROUND && IR_4 == GROUND && IR_5 == LINE){
	                motoRun(TraceHSpeed,TraceSpeed);
	                Serial.println("大右转");
	        }
	  
	}
								

验证上传以上代码至智能小车上的esp32板上,循迹小车就完成了。

这里注意的是,循迹模块的安装高度需要根据实际进行调整,否则无法识别到白色和黑色的区域导致无法循迹。