1. 要点说明

  • 使用VSCode+PlatformIO进行开发。
  • 将所需的库文件添加到/lib/库名称/ 文件夹中。

2. 遇到的坑点

  • 1、焊接电机驱动板的模拟信号引脚可能虚焊,导致无法读取到超声波信号。
  • 2、购买的直流电机质量参差不齐,转速不统一。设置低转速时,有可能无法转动。
  • 3、超声波传感器传入慢,或芯片运行慢,或电机转速过快,导致不能很精确的停止。

3. 代码

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
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
#include <Arduino.h>
#include <NewPing.h>
#include <AFMotor.h>
#include <stdlib.h>
/**
* 遇到的坑点:
* 1、焊接电机驱动板的模拟信号引脚可能虚焊,导致无法读取到超声波信号。
* 2、购买的直流电机质量参差不齐,转速不统一。设置低转速时,有可能无法转动。
* 3、超声波传感器传入慢,或芯片运行慢,或电机转速过快,导致不能很精确的停止。
*/
AF_DCMotor motor1(1);
AF_DCMotor motor2(2);
AF_DCMotor motor3(3);
AF_DCMotor motor4(4);

#define TRIG_PIN A4
#define ECHO_PIN A5

#define MAX_DISTANCE 200
#define MAX_SPEED 120 // sets speed of DC motors
#define MAX_SPEED_OFFSET 20

boolean goesForward = false;
int distance = 100;
int speedSet = 0;

NewPing sonar(TRIG_PIN, ECHO_PIN, MAX_DISTANCE);
// NewPing sonar(TRIG_PIN, ECHO_PIN);

void init_motor()
{
motor1.setSpeed(200); // 这4条语句的作用是通过setSpped库函数设置电机运行速度。
motor2.setSpeed(200); // setSpped库函数中的参数是运行速度参数。
motor3.setSpeed(200); // 运行速度参数允许范围是0~255。
motor4.setSpeed(200); // 速度参数越大,运转速度越快。参数为0时电机停止转动。
}

void moveForward()
{

if (!goesForward)
{
goesForward = true;
motor1.run(FORWARD);
motor2.run(FORWARD);
motor3.run(FORWARD);
motor4.run(FORWARD);
for (speedSet = 0; speedSet < MAX_SPEED; speedSet += 2) // slowly bring the speed up to avoid loading down the batteries too quickly
{
motor1.setSpeed(speedSet);
motor2.setSpeed(speedSet);
motor3.setSpeed(speedSet);
motor4.setSpeed(speedSet);
delay(5);
}
}
}

void moveStop()
{
motor1.run(RELEASE); // 这4条语句的作用是让4个电机在启动时停止转动
motor2.run(RELEASE); // run库函数允许使用的关键字参数有RELEASE、FORWARD、BACKWARD
motor3.run(RELEASE); // 使用关键字RELEASE作为参数使用时,run库函数将会让扩展板停止提供电机运转动力
motor4.run(RELEASE); // 电机旋转一旦失去动力就会自然的停止转动。
}

void backward_motor()
{
motor1.run(BACKWARD); // 这4条语句的作用是利用run库函数控制4个电机"反向"旋转。
motor2.run(BACKWARD); // 同样的,这里所谓的“反向”旋转也只是一种说法。这部分程序内容
motor3.run(BACKWARD); // 与本程序33-36行中的内容十分类似。唯一区别就是使用了“BACKWARD”
motor4.run(BACKWARD); // 关键字参数来通过库函数run控制电机“反向”旋转。
}

void moveBackward()
{
goesForward = false;
motor1.run(BACKWARD);
motor2.run(BACKWARD);
motor3.run(BACKWARD);
motor4.run(BACKWARD);
for (speedSet = 0; speedSet < MAX_SPEED; speedSet += 2) // slowly bring the speed up to avoid loading down the batteries too quickly
{
motor1.setSpeed(speedSet);
motor2.setSpeed(speedSet);
motor3.setSpeed(speedSet);
motor4.setSpeed(speedSet);
delay(5);
}
}
void turnRight()
{
motor1.run(FORWARD);
motor2.run(FORWARD);
motor3.run(BACKWARD);
motor4.run(BACKWARD);
delay(500);
motor1.run(FORWARD);
motor2.run(FORWARD);
motor3.run(FORWARD);
motor4.run(FORWARD);
}

void turnLeft()
{
motor1.run(BACKWARD);
motor2.run(BACKWARD);
motor3.run(FORWARD);
motor4.run(FORWARD);
delay(500);
motor1.run(FORWARD);
motor2.run(FORWARD);
motor3.run(FORWARD);
motor4.run(FORWARD);
}

// 读取超声波传感器值
int readPing()
{
delay(70);
int cm = sonar.ping_cm();
Serial.print(cm);
Serial.print("cm ---------->");
Serial.println(millis());
if (cm == 0)
{
cm = 250;
}
return cm;
}

void setup()
{
Serial.begin(9600);
// init_motor();
distance = readPing();
delay(1000);
}
void loop()
{
if (distance < 40)
{
delay(500);
moveStop();
delay(100);
moveBackward();
delay(300);
moveStop();
delay(200);
int randomNumber = rand() % 2;
if (randomNumber == 0)
{
turnLeft();
Serial.println("turn left");
}
else
{
turnRight();
Serial.println("turn right");
}
}
else
{
moveForward();
// moveBackward();
// turnLeft();
// turnRight();
}

distance = readPing();
}