本系列教程讲解零知小车套件以零知迷你板为主控,使用零知开源平台进行智能小车开发。
使用的硬件:零知智能小车套件
实现的功能:红外循迹、超声避障、直线运行等基本功能。
扩展:可以在小车上加入其它传感器模块进行扩展,比如加入摄像头模块进行监控、加入火焰传感器做灭火小车、加入更多超声波模块实现自动跟随...
零知四轮小车入门版(零知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板上,循迹小车就完成了。
这里注意的是,循迹模块的安装高度需要根据实际进行调整,否则无法识别到白色和黑色的区域导致无法循迹。