-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathwall-follower.ino
297 lines (240 loc) · 6.74 KB
/
wall-follower.ino
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
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
#include <Servo.h>
#include "Adafruit_VL53L0X.h"
Adafruit_VL53L0X lox = Adafruit_VL53L0X();
/**
* Define PIN
*/
// Motor pin
#define RIGHT_SERVO_PWM 5
#define RIGHT_SERVO_IN_2 A0
#define RIGHT_SERVO_IN_1 7
#define LEFT_SERVO_PWM 3
#define LEFT_SERVO_IN_1 9
#define LEFT_SERVO_IN_2 8
// Contact sensor pin
#define SENSOR_LEFT 2
#define SENSOR_RIGHT 12
#define SENSOR_FRONT 4
// Servo for bee
#define BEE_RIGHT_PIN 10
#define BEE_LEFT_PIN 11
// Jumper pin
#define JUMPER 13 // Jumper pin
// Flag pin
#define FLAG_PIN 6
// Bee position
#define BEE_LEFT_CLOSE 175
#define BEE_RIGHT_CLOSE 10
#define BEE_LEFT_OPEN 30
#define BEE_RIGHT_OPEN 170
// Flag position
#define HIDE 130
#define VISIBLE 40
// Direction of robot
#define LEFT 0
#define RIGHT 1
int direction = LEFT;
// State
#define IDLE 0 // Wait jumper insertion
#define WAIT 1 // Wait match start (eject jumper)
#define STARTED 2
#define OBSTACLE 3
#define BEE 4
#define END 5
#define COEF_DIRECTION 0.6
#define MATCH_DURATION 90000
Servo pushBeeLeft;
Servo pushBeeRight;
Servo flag;
// Read jumper return 1 if present, 0 else
int readJumper()
{
return digitalRead(JUMPER);
}
void move();
void stop();
int detect();
void bee();
void installTouillette();
void setup()
{
pinMode(RIGHT_SERVO_PWM, OUTPUT);
pinMode(RIGHT_SERVO_IN_2, OUTPUT);
pinMode(RIGHT_SERVO_IN_1, OUTPUT);
pinMode(LEFT_SERVO_PWM, OUTPUT);
pinMode(LEFT_SERVO_IN_1, OUTPUT);
pinMode(LEFT_SERVO_IN_2, OUTPUT);
pinMode(SENSOR_LEFT, INPUT_PULLUP);
pinMode(SENSOR_RIGHT, INPUT_PULLUP);
pinMode(SENSOR_FRONT, INPUT_PULLUP);
pinMode(JUMPER, INPUT);
pinMode(FLAG_PIN, OUTPUT);
// Set direction : ALWAYS FORWARD
digitalWrite(RIGHT_SERVO_IN_2, LOW);
digitalWrite(RIGHT_SERVO_IN_1, HIGH);
digitalWrite(LEFT_SERVO_IN_2, HIGH);
digitalWrite(LEFT_SERVO_IN_1, LOW);
pushBeeLeft.attach(BEE_LEFT_PIN);
pushBeeRight.attach(BEE_RIGHT_PIN);
flag.attach(FLAG_PIN);
flag.write(HIDE);
pushBeeLeft.write(BEE_LEFT_CLOSE);
pushBeeRight.write(BEE_RIGHT_CLOSE);
Serial.begin(115200);
Serial.println("IDLE");
lox.begin();
}
void loop()
{
static unsigned int state = IDLE;
static unsigned long started_time = 0;
static unsigned int bee_break = 0;
switch(state)
{
case IDLE: // Wait jumper
// If jumper is inserted go to next state
if (readJumper()) {
if (!digitalRead(SENSOR_RIGHT))
direction = RIGHT;
state = WAIT;
Serial.println("GO TO WAIT START");
}
// Move arm to show position detected by robot
if (!digitalRead(SENSOR_RIGHT))
{
pushBeeRight.write((BEE_RIGHT_OPEN + BEE_RIGHT_CLOSE) / 2);
pushBeeLeft.write(BEE_LEFT_CLOSE);
}
else if (!digitalRead(SENSOR_LEFT))
{
pushBeeRight.write(BEE_RIGHT_CLOSE);
pushBeeLeft.write((BEE_LEFT_OPEN + BEE_LEFT_CLOSE) / 2);
}
else
{
pushBeeRight.write(BEE_RIGHT_CLOSE);
pushBeeLeft.write(BEE_LEFT_CLOSE);
}
break;
case WAIT: // Wait begin of match
// Set small perimeter (close arms)
pushBeeRight.write(BEE_RIGHT_CLOSE);
pushBeeLeft.write(BEE_LEFT_CLOSE);
// Jumper is removed
if (!readJumper()) {
started_time = millis(); // Register begin time of match
installTouillette(); // Deploy robot (to push bee)
state = STARTED; // Set state to start
Serial.println("STARTED");
}
break;
case STARTED: // Wait end of match or obstacle
// End of match ?
if (millis() - started_time >= MATCH_DURATION) {
bee();
Serial.println("END_OF_MATCH");
state = END;
}
// Obstacle ?
if (detect()) {
Serial.println("OBSTACLE OBSTACLE OBSTACLE");
state = OBSTACLE;
}
// End of the table
if (!digitalRead(SENSOR_FRONT)) {
Serial.println("Go to BEE");
state = BEE;
}
move();
break;
case OBSTACLE: // Wait end of match or no obstacle
// End of match
if (millis() - started_time >= MATCH_DURATION) {
bee();
Serial.println("END_OF_MATCH");
state = END;
}
// No obstacle
if (! detect()) {
Serial.println("No more obstacle");
state = STARTED;
}
// End of the table
if (!digitalRead(SENSOR_FRONT)) {
Serial.println("Go to BEE from OBSTACLE");
state = BEE;
}
stop();
break;
case BEE: // Push bee and stop program
stop();
bee_break = 1;
bee();
state = END;
break;
case END: // End of program
stop();
if (bee_break) { // Security : push the bee
delay(2000);
flag.write(VISIBLE); // Display number of points
bee_break = 0;
}
break;
}
}
// Set good position of arm to push bee
void installTouillette()
{
if (direction == RIGHT) {
pushBeeRight.write((BEE_RIGHT_OPEN + BEE_RIGHT_CLOSE) / 2);
pushBeeLeft.write(BEE_LEFT_CLOSE);
} else {
pushBeeRight.write(BEE_RIGHT_CLOSE);
pushBeeLeft.write((BEE_LEFT_OPEN + BEE_LEFT_CLOSE) / 2);
}
}
// Push the bee
void bee()
{
if (direction == RIGHT)
{
pushBeeRight.write(BEE_RIGHT_CLOSE);
delay(1000);
pushBeeLeft.write(BEE_LEFT_OPEN);
}
else
{
pushBeeLeft.write(BEE_LEFT_CLOSE);
delay(1000);
pushBeeRight.write(BEE_RIGHT_OPEN);
}
}
// Read Time of flight to know if there is a robot
int detect()
{
VL53L0X_RangingMeasurementData_t measure;
lox.rangingTest(&measure, false);
if (measure.RangeStatus != 4 && measure.RangeMilliMeter <= 150) {
return 1;
} else {
return 0;
}
}
// Move the robot
void move()
{
long left = 250, right = 250;
// If don't touch the wall, turn to touch the wall ...
if (direction == LEFT && digitalRead(SENSOR_LEFT))
left *= COEF_DIRECTION;
if (direction == RIGHT && digitalRead(SENSOR_RIGHT))
right *= COEF_DIRECTION;
analogWrite(LEFT_SERVO_PWM, left);
analogWrite(RIGHT_SERVO_PWM, right);
}
// STOP the robot
void stop()
{
analogWrite(LEFT_SERVO_PWM, 0);
analogWrite(RIGHT_SERVO_PWM, 0);
}