本帖是在参考了很多博客之后进行的一次实战加总结,参考连接如下:
Arduino智能小车寻迹篇
不适用PWM调速彻底解决L298n电机驱动转速不同的问题
1.工作原理
总体思想:小车通过四路寻迹模块得到路径信息,根据对其返回数据的判断,调整小车运行姿态,使其达到寻迹的功能
2.清单
1、小车套件(小车的底盘,轮子,开关这些)
2、Arduino Uno板
3、9~12V的电源一个(超过6V就可以,四节电池盒就能跑)
4、直流减速马达两个
5、四路寻迹模块(两个其实也可以实现寻迹)
6、L298n电机驱动
7、工具(黑胶带,胶枪,螺丝刀)
3.模块介绍
a)四路寻迹模块
规格参数:
1.工作电压:DC 3.3V-5V
2.工作电流:尽量选择1A以上电源供电
3.工作温度:-10℃—+50℃
4.安装孔径:M3螺丝
5.检测距离:1mm至60 CM可调,距离越近性能越稳定,白色反射距离远。
6.输出接口:6线制接口(1234为4路信号输出端,+为正电源,-为负电源也就是地线)
7.输出信号:TTL电平(可直接连接单片机I/0号,感应到传感器反射回来的红外光时,红指示灯亮,输出低电平;没有红外光时,指示灯不亮,输出高电平。)
单独测试代码:
int Input1 = 2; //定义引脚2,3,4,5为Input2345
int Input2 = 3;
int Input3 = 4;
int Input4 = 5;
void setup() {
//串口初始化
Serial.begin(9600);
//引脚初始化
pinMode(Input1,INPUT);
pinMode(Input2,INPUT);
pinMode(Input3,INPUT);
pinMode(Input4,INPUT);
}
void loop() {
// 设定一个数组接受数据
int data[4];
//读取数据并赋值
data[0] = digitalRead(2);
data[1] = digitalRead(3);
data[2] = digitalRead(4);
data[3] = digitalRead(5);
//打印测试结果
Serial.print(data[0]);
Serial.print("---");
Serial.print(data[1]);
Serial.print("---");
Serial.print(data[2]);
Serial.print("---");
Serial.println(data[3]);
delay(100);
}
b)L298n电机驱动模块
电机驱动模块需要注意的地方在于,L298n驱动两个轮子的速度可能会不一致,需要根据情况调整参数,另外电源千万不要接错了,看清楚再接,逻辑输入要选择Arduino上带PWM~的接口。
这个模块的具体使用资料:最详细的L298n电机驱动模块介绍
自己测试可以先看这一篇:Arduino通过L298n驱动电机
4.整体代码
int leftMotor1 = 6; //电机引脚,根据自己实际连线进行更改
int leftMotor2 = 5;
int rightMotor1 = 10;
int rightMotor2 = 9;
int IN1 = 7; //定义uno的pin1为红外寻迹模块输入IN1
int IN2 = 2;
int IN3 = 3;
int IN4 = 4;
#define STOP 0
#define FORWARD 1
#define BACKWARD 2
#define TURNLEFT 3
#define TURNRIGHT 4
void setup() {
//串口初始化
Serial.begin (9600);
//初始化各IO,模式为OUTPUT 输出模式
pinMode(leftMotor1, OUTPUT);
pinMode(leftMotor2, OUTPUT);
pinMode(rightMotor1, OUTPUT);
pinMode(rightMotor2, OUTPUT);
//初始化红外寻迹模块输入引脚为INPUT模式
pinMode(IN1,INPUT);
pinMode(IN2,INPUT);
pinMode(IN3,INPUT);
pinMode(IN4,INPUT);
}
void loop() {
Tracking();
}
void Tracking(){
//将寻迹模块的数据读入数组
int data[4];
data[0] = digitalRead(7);
data[1] = digitalRead(2);
data[2] = digitalRead(3);
data[3] = digitalRead(4);
//根据信号输入选择小车运动模式
if(!data[0] && !data[1] && !data[2] && !data[3]) //左右都没有检测到黑线
{
motorRun(FORWARD, 50);
}
if(data[0] || data[1]) //右边检测到黑线
{
motorRun(TURNRIGHT, 40);
//motorRun(TURNLEFT, 40);
}
if(data[2] || data[3]) //左边检测到黑线
{
motorRun(TURNLEFT, 40);
//motorRun(TURNRIGHT, 40);
}
if(data[0] && data[3]) //左右都检测到黑线是停止
{
motorRun(STOP, 0);
while(1);
}
Serial.print(data[0]);
Serial.print("---");
Serial.print(data[1]);
Serial.print("---");
Serial.print(data[2]);
Serial.print("---");
Serial.println(data[3]);
}
void motorRun(int cmd,int value)
{
switch(cmd){
case FORWARD:
Serial.println("FORWARD"); //输出状态
analogWrite(leftMotor1, value);
digitalWrite(leftMotor2, LOW);
analogWrite(rightMotor1, value);
digitalWrite(rightMotor2, LOW);
break;
case BACKWARD:
Serial.println("BACKWARD"); //输出状态
digitalWrite(leftMotor1, LOW);
analogWrite(leftMotor2, value);
digitalWrite(rightMotor1, LOW);
analogWrite(rightMotor2, value);
break;
case TURNLEFT:
Serial.println("TURN LEFT"); //输出状态
analogWrite(leftMotor1, value);
digitalWrite(leftMotor2, LOW);
digitalWrite(rightMotor1, LOW);
analogWrite(rightMotor2, value);
break;
case TURNRIGHT:
Serial.println("TURN RIGHT"); //输出状态
digitalWrite(leftMotor1, LOW);
analogWrite(leftMotor2, value);
analogWrite(rightMotor1, value);
digitalWrite(rightMotor2, LOW);
break;
default:
Serial.println("STOP"); //输出状态
digitalWrite(leftMotor1, LOW);
digitalWrite(leftMotor2, LOW);
digitalWrite(rightMotor1, LOW);
digitalWrite(rightMotor2, LOW);
}
}