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

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

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

实现的功能:红外循迹、超声避障、直线运行等基本功能。

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


本系列教程目录

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


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


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


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


一、工具材料

(1)组装好的智能小车


二、程序代码

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

							
							
 /**********************************************************
*    文件: .ino      by 零知实验室([url=http://www.lingzhilab.com]www.lingzhilab.com[/url])
*    -^^- 零知开源,让电子制作变得更简单! -^^-
*    时间: 2019/11/19 16:35
*    说明:
************************************************************/
//电机模块
#define MotorIN1                        2
#define MotorIN2                        3
#define MotorIN3                        4
#define MotorIN4                        5
 
#define MotorIN5                        8
#define MotorIN6                        9
#define MotorIN7                        10
#define MotorIN8                        11
 
//循迹
#define TracePin1                        18
#define TracePin2                        17
#define TracePin3                        rst///
#define TracePin4                        12
#define TracePin5                        13
 
#define MotorSpeedTrace                      240
//#define MotorSpeedTraceSlow            220
#define MotorSpeedRoSlow                   180
#define MotorSpeedRoFast                    140
 
#define MotorSpeedSlow                        180
//避障,转弯速度调节
#define MotorSpeedNormal                  140        //正常前进速度
#define MotorSpeedRotate                    240
#define MotorSpeedFast                        80 //
 
//小车运行方向
enum carDirec{
        carForward = 1,
        carForwardSlow,
        carBack,
        carLeft,
        carRight,
        carForLeft,
        carForRight,
        carBacLeft,
        carBacRight,
        carRightFast,
        carRightSlow,
        carLeftFast,
        carLeftSlow,
        carStop
};
 
void motorRun(byte motorNum, bool forward, int speed){
        if(motorNum == 1){
                if(forward){
                        analogWrite(MotorIN1,speed);
                        analogWrite(MotorIN2,255);
                }else{
                        analogWrite(MotorIN1,255);
                        analogWrite(MotorIN2,speed);
                }
        }
         
        if(motorNum == 2){
                if(forward){
                        analogWrite(MotorIN3,255);
                        analogWrite(MotorIN4,speed);
                }else{
                        analogWrite(MotorIN3,speed);
                        analogWrite(MotorIN4,255);
                }
        }
         
        if(motorNum == 3){
                if(forward){
                        analogWrite(MotorIN5,speed);
                        analogWrite(MotorIN6,255);
                }else{
                        analogWrite(MotorIN5,255);
                        analogWrite(MotorIN6,speed);
                }
        }
         
        if(motorNum == 4){
                if(forward){
                        analogWrite(MotorIN7,speed);
                        analogWrite(MotorIN8,255);
                }else{
                        analogWrite(MotorIN7,255);
                        analogWrite(MotorIN8,speed);
                }
        }
}
 
void motorStop()
{
        analogWrite(MotorIN1,255);
        analogWrite(MotorIN2,255);
        analogWrite(MotorIN3,255);
        analogWrite(MotorIN4,255);
        analogWrite(MotorIN5,255);
        analogWrite(MotorIN6,255);
        analogWrite(MotorIN7,255);
        analogWrite(MotorIN8,255);
}
 
//小车根据命令运行
void carGo(byte cmd){
        switch(cmd){
                case carForward:
                motorRun(1,true,MotorSpeedNormal);
                motorRun(2,true,MotorSpeedNormal);
                motorRun(3,true,MotorSpeedNormal);
                motorRun(4,true,MotorSpeedNormal);
                break;
                case carForwardSlow:
                motorRun(1,true,MotorSpeedSlow);
                motorRun(2,true,MotorSpeedSlow);
                motorRun(3,true,MotorSpeedSlow);
                motorRun(4,true,MotorSpeedSlow);
                break;
                case carBack:
                motorRun(1,false,MotorSpeedNormal);
                motorRun(2,false,MotorSpeedNormal);
                motorRun(3,false,MotorSpeedNormal);
                motorRun(4,false,MotorSpeedNormal);
                break;
                case carLeft:
                motorRun(1,true,MotorSpeedRotate);
                motorRun(2,true,MotorSpeedFast);
                motorRun(3,true,MotorSpeedRotate);
                motorRun(4,true,MotorSpeedFast);
                break;
                case carRight:
                motorRun(1,true,MotorSpeedFast);
                motorRun(2,true,MotorSpeedRotate);
                motorRun(3,true,MotorSpeedFast);
                motorRun(4,true,MotorSpeedRotate);
                break;
                case carForLeft:
                motorRun(1,true,MotorSpeedRotate);
                motorRun(2,true,MotorSpeedNormal);
                motorRun(3,true,MotorSpeedRotate);
                motorRun(4,true,MotorSpeedNormal);
                break;
                case carForRight:
                motorRun(1,true,MotorSpeedNormal);
                motorRun(2,true,MotorSpeedRotate);
                motorRun(3,true,MotorSpeedNormal);
                motorRun(4,true,MotorSpeedRotate);
                break;
                case carLeftFast:
                motorRun(1,true,MotorSpeedTrace);
                motorRun(2,true,MotorSpeedRoFast);
                motorRun(3,true,MotorSpeedTrace);
                motorRun(4,true,MotorSpeedRoFast);
                break;
                case carLeftSlow:
                motorRun(1,true,MotorSpeedTrace);
                motorRun(2,true,MotorSpeedRoSlow);
                motorRun(3,true,MotorSpeedTrace);
                motorRun(4,true,MotorSpeedRoSlow);
                break;
                case carRightFast:
                motorRun(1,true,MotorSpeedRoFast);
                motorRun(2,true,MotorSpeedTrace);
                motorRun(3,true,MotorSpeedRoFast);
                motorRun(4,true,MotorSpeedTrace);
                break;
                case carRightSlow:
                motorRun(1,true,MotorSpeedRoSlow);
                motorRun(2,true,MotorSpeedTrace);
                motorRun(3,true,MotorSpeedRoSlow);
                motorRun(4,true,MotorSpeedTrace);
                break;
                case carStop:
                motorStop();
                break;
                default:
                motorStop();
                break;
        }
}
 
void lineTrace()
{
        int IR_1 = digitalRead(TracePin1);
        int IR_2 = digitalRead(TracePin2);
        int IR_4 = digitalRead(TracePin4);
        int IR_5 = digitalRead(TracePin5);
         
        Serial.print("IR:");
        Serial.print(IR_1);Serial.print("        ");
        Serial.print(IR_2);Serial.print("        ");
        Serial.print(IR_4);Serial.print("        ");
        Serial.print(IR_5);Serial.println();
         
        //1,2 3,4都在黑色,前进
        //        1白色,2,3,4黑色,右大转
        //        1黑色,2白色,右小转
        //        3白色,左小转
        //        4白色,左大转
         
        //黑色:0
        #define BLACK 0
        #define WHITE 1
         
        // 黑底白线,若是白底黑线,请调换颜色
        #define GROUND BLACK
        #define LINE   WHITE
         
        if(IR_1 == GROUND && IR_2 == GROUND && IR_4 == GROUND && IR_5 == GROUND)
        {
                carGo(carForwardSlow);
                Serial.println("直行。");
        }
        if(IR_1 == LINE && IR_2 == GROUND && IR_4 == GROUND && IR_5 == GROUND)
        {
                carGo(carLeftFast);
                Serial.println("左大转");
        }
        if(IR_1 == GROUND && IR_2 == LINE && IR_4 == GROUND && IR_5 == GROUND)
        {
                carGo(carLeftSlow);
                Serial.println("左小转");
        }
        if(IR_1 == GROUND && IR_2 == GROUND && IR_4 == LINE && IR_5 == GROUND)
        {
                carGo(carRightSlow);
                Serial.println("右小转。。");
        }
        if(IR_1 == GROUND && IR_2 == GROUND && IR_4 == GROUND && IR_5 == LINE)
        {
                carGo(carRightFast);
                Serial.println("右大转。。");
        }
         
        //        delay(300);
}
 
void setup() {
        //在这里加入初始化相关代码,只运行一次:
         
        //串口调试
        Serial.begin(9600);
         
        //设置引脚
        pinMode(MotorIN1,OUTPUT);
        pinMode(MotorIN2,OUTPUT);
        pinMode(MotorIN3,OUTPUT);
        pinMode(MotorIN4,OUTPUT);
         
        pinMode(MotorIN5,OUTPUT);
        pinMode(MotorIN6,OUTPUT);
        pinMode(MotorIN7,OUTPUT);
        pinMode(MotorIN8,OUTPUT);
         
        pinMode(TracePin1,INPUT);
        pinMode(TracePin2,INPUT);
        pinMode(TracePin4,INPUT);
        pinMode(TracePin5,INPUT);
}
 
void loop() {
        lineTrace();
}
							

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

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