0%

DIY智能小车——寻迹与马达

在完成超声波避障和1602液晶显示之后,下一步要对小车车增加寻迹的功能,寻迹的模块TCRT5000红外反射传感器,主要的实现原理是:TCRT5000传感器的红外发射二极管不断发射红外时,3脚的电压大于2脚的电压,输出为低电平。根据这个原理就可以写代码啦~

实现的主要功能:

  • 白纸上画黑线,小车车会沿着黑线走
  • 顺路介绍下L298N电机驱动模块

L298N

可能这个图片已经写的很清楚了,一个驱动模块带动两个电极,一个L298N模块需要三个IO口。

寻迹程序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
#include <reg52.h>

/******************寻迹IO口声明********************/
sbit trace1 = P3^5; /*1路*/设置的为两个模块去寻迹
sbit trace2 = P2^5; /*2路*/
/**********************电机的IO口*****************/
sbit em1 = P1^4; //左后,四个电机的驱动
sbit em2 = P1^7; //右后
sbit em3 = P2^7; //右前
sbit em4 = P2^3; //左前
/*电机口*/
sbit in1 = P1^2; //左后
sbit in2 = P1^3;
sbit in3 = P1^5; //右后
sbit in4 = P1^6;
sbit in5 = P3^6; //右前
sbit in6 = P3^7;
sbit in7 = P2^1; //左前
sbit in8 = P2^2;

#define cycle 200 //宏定义一个周期,下面会进行说明

/*****************延时函数*****************/
void Delayms(unsigned int z)
{
unsigned int a, b;
for (a = z; a > 0; a--)
for (b = 110; b > 0; b--);
}
/****因为单片机上电后,电机对应端口送高电平,所以电机被启动,em1就没赋值****/
/********************电机转动************************/
void Forward() //前进
{
in1 = 1;
in2 = 0;
in3 = 1;
in4 = 0;
in5 = 1;
in6 = 0;
in7 = 1;
in8 = 0;
}

void Stop() //停止
{
in1 = 0;
in2 = 0;
in3 = 0;
in4 = 0;
in5 = 0;
in6 = 0;
in7 = 0;
in8 = 0;
}

void Reverse() //倒车
{
in1 = 0;
in2 = 1;
in3 = 0;
in4 = 1;
in5 = 0;
in6 = 1;
in7 = 0;
in8 = 1;
}

void Turn_left() //左转
{
in1 = 0;
in2 = 1;
in3 = 1;
in4 = 0;
in5 = 1;
in6 = 0;
in7 = 0;
in8 = 1;
}

void Turn_right() //右转
{
in1 = 1;
in2 = 0;
in3 = 0;
in4 = 1;
in5 = 0;
in6 = 1;
in7 = 1;
in8 = 0;
}
/*************************寻迹函数************************/
void Trace()
{
if((trace1 == 0) && (trace2 == 0)) //0代表检测到黑线
{
Delayms(50); //首先先做略微的延时,因为trace1、2不是很稳定
Forward(); //前进
Delayms(cycle); //前面宏定义的周期
Stop(); //小车停止,防止小车走的太快,不能很好的寻迹
Delayms(cycle); //再次延时,结束后进入下次循环
}

//因为这里没有写PWM小车的调速程序,怕小车走的太快而不能很好的寻迹,因此,就让小车以
//“走走停停的”形式缓慢前进。

if((trace1 == 0) && (trace2 == 1)) //0代表检测到黑线
{
Delayms(50);
Turn_left();
Delayms(cycle);
Stop(); //防止走的太快
Delayms(cycle);
}

if((trace1 == 1) && (trace2 == 0)) //0代表检测到黑线
{
Delayms(50);
Turn_right();
Delayms(cycle);
Stop(); //防止走的太快
Delayms(cycle);
}

if((trace1 == 1) && (trace2 == 1))
{
Delayms(50);
Forward();
Delayms(cycle);
Stop(); //防止走的太快
Delayms(cycle);
}
}

void main()
{
while(1)
{
Trace(); //死循环,进入寻迹
}
}

寻迹收获

  • 可能没啥好展示的,其中宏定义中的cycle数值,可能要根据自己的实际情况去改变一下,好了,明天写蓝牙的那部分代码,今晚有点困,先睡了,不熬夜~~~
  • 以及这些代码都是能运行的,不知道当初调了多少BUG,莫名其妙的不对,寻迹模块还是中途换过
    的,今晚过了测试,才写的这个博客。
  • 每个程序猿经历过的莫名奇妙的让人脑仁疼的破BUG,可能都能当一段故事吹一下,前几天不对,
    今天又对了,还真是奇怪,被我归结为模块原因(其实是代码是在改不动了)。嗯,Goodnight.

感谢上学期间打赏我的朋友们。赛博乞讨:我,秦始皇,打钱。

欢迎订阅我的文章