Skip to content

Commit 345e59c

Browse files
committed
feat: Add "smart car" V1 code
1 parent ab1d323 commit 345e59c

File tree

1 file changed

+276
-0
lines changed

1 file changed

+276
-0
lines changed

smart-car/smart-car.ino

Lines changed: 276 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,276 @@
1+
//#define DEBUG
2+
3+
#define ENA_PIN 10
4+
#define ENB_PIN 9
5+
#define IN1_PIN 2
6+
#define IN2_PIN 3
7+
#define IN3_PIN 5
8+
#define IN4_PIN 4
9+
10+
#define LEDR_PIN 6
11+
#define LEDL_PIN 7
12+
13+
#define ECHOR_PIN A0
14+
#define TRIGR_PIN A1
15+
#define ECHOC_PIN A2
16+
#define TRIGC_PIN A3
17+
#define ECHOL_PIN A4
18+
#define TRIGL_PIN A5
19+
20+
#define SPD 255
21+
22+
const int turnDist = 30; // distance in cm on which normal turn will be triggered to avoid collision
23+
const int spinDist = 7; // distance in cm on which obstacle is considered too close and radical spin or pulling back will be triggered
24+
25+
const char _FWD = 'f';
26+
const char _RHT = 'r';
27+
const char _LFT = 'l';
28+
const char _SPR = 'R';
29+
const char _SPL = 'L';
30+
const char _BCK = 'b';
31+
32+
// sensor distances and movement direction saved from the previous loop
33+
int pcd;
34+
int prd;
35+
int pld;
36+
int pdir;
37+
38+
void setup() {
39+
#ifdef DEBUG
40+
Serial.begin(9600);
41+
#endif
42+
43+
pinMode(ENA_PIN, OUTPUT);
44+
pinMode(ENB_PIN, OUTPUT);
45+
pinMode(IN1_PIN, OUTPUT);
46+
pinMode(IN2_PIN, OUTPUT);
47+
pinMode(IN3_PIN, OUTPUT);
48+
pinMode(IN4_PIN, OUTPUT);
49+
50+
pinMode(LEDR_PIN, OUTPUT);
51+
pinMode(LEDL_PIN, OUTPUT);
52+
53+
pinMode(ECHOR_PIN, INPUT);
54+
pinMode(TRIGR_PIN, OUTPUT);
55+
pinMode(ECHOC_PIN, INPUT);
56+
pinMode(TRIGC_PIN, OUTPUT);
57+
pinMode(ECHOL_PIN, INPUT);
58+
pinMode(TRIGL_PIN, OUTPUT);
59+
}
60+
61+
void debug(char dir, int cdist, int rdist, int ldist) {
62+
Serial.print(" > "); Serial.print(dir);
63+
Serial.print(" | C: "); Serial.print(cdist);
64+
Serial.print(" | R: "); Serial.print(rdist);
65+
Serial.print(" | L: "); Serial.print(ldist);
66+
Serial.println("");
67+
}
68+
69+
int calculateDistance(int trig, int echo) {
70+
digitalWrite(trig, LOW);
71+
delayMicroseconds(2);
72+
digitalWrite(trig, HIGH);
73+
delayMicroseconds(10);
74+
digitalWrite(trig, LOW);
75+
76+
int duration = pulseIn(echo, HIGH);
77+
78+
return duration * 0.034 / 2;
79+
}
80+
81+
int cDist() {
82+
return calculateDistance(TRIGC_PIN, ECHOC_PIN);
83+
}
84+
85+
int rDist() {
86+
return calculateDistance(TRIGR_PIN, ECHOR_PIN);
87+
}
88+
89+
int lDist() {
90+
return calculateDistance(TRIGL_PIN, ECHOL_PIN);
91+
}
92+
93+
byte chooseDirection(int cdist, int rdist, int ldist) {
94+
// "0" is a sensor quirk: continue with previously chosen direction in this case
95+
if ((cdist == 0) or (rdist == 0) or (ldist == 0)) {
96+
return pdir;
97+
}
98+
99+
// we got stuck: spin left or right ...
100+
if ((cdist == pcd) and (rdist == prd) and (ldist == pld)) {
101+
// ... or just pull back if we already were spinning
102+
if ((pdir == _SPR) or (pdir == _SPL)) {
103+
return _BCK;
104+
}
105+
if (rdist < ldist) {
106+
return _SPL;
107+
}
108+
return _SPR;
109+
}
110+
111+
// obstacle too close to center sensor: pull back to avoid collision ...
112+
if (cdist < spinDist) {
113+
return _BCK;
114+
}
115+
// ... or spin left or right in case of proximity with lateral sensors ...
116+
if (rdist < spinDist) {
117+
// ... or just pull back if we were already spinning left
118+
if (pdir == _SPL) {
119+
return _BCK;
120+
}
121+
return _SPL;
122+
}
123+
if (ldist < spinDist) {
124+
// ... or just pull back if we were already spinning right
125+
if (pdir == _SPR) {
126+
return _BCK;
127+
}
128+
return _SPR;
129+
}
130+
131+
// when obstacle detected: decide to turn left or right
132+
if (cdist < turnDist) {
133+
if (rdist < ldist) {
134+
return _LFT;
135+
}
136+
return _RHT;
137+
}
138+
if (rdist < turnDist) {
139+
return _LFT;
140+
}
141+
if (ldist < turnDist) {
142+
return _RHT;
143+
}
144+
145+
// no obstacles: move forward by default
146+
return _FWD;
147+
}
148+
149+
void goForward() {
150+
digitalWrite(IN1_PIN, LOW);
151+
digitalWrite(IN2_PIN, HIGH);
152+
digitalWrite(IN3_PIN, LOW);
153+
digitalWrite(IN4_PIN, HIGH);
154+
analogWrite(ENA_PIN, SPD);
155+
analogWrite(ENB_PIN, SPD);
156+
157+
digitalWrite(LEDR_PIN, LOW);
158+
digitalWrite(LEDL_PIN, LOW);
159+
}
160+
161+
void goRight() {
162+
digitalWrite(IN1_PIN, LOW);
163+
digitalWrite(IN2_PIN, HIGH);
164+
digitalWrite(IN3_PIN, LOW);
165+
digitalWrite(IN4_PIN, HIGH);
166+
analogWrite(ENA_PIN, SPD);
167+
analogWrite(ENB_PIN, 0);
168+
169+
digitalWrite(LEDR_PIN, HIGH);
170+
digitalWrite(LEDL_PIN, LOW);
171+
}
172+
173+
void goLeft() {
174+
digitalWrite(IN1_PIN, LOW);
175+
digitalWrite(IN2_PIN, HIGH);
176+
digitalWrite(IN3_PIN, LOW);
177+
digitalWrite(IN4_PIN, HIGH);
178+
analogWrite(ENA_PIN, 0);
179+
analogWrite(ENB_PIN, SPD);
180+
181+
digitalWrite(LEDR_PIN, LOW);
182+
digitalWrite(LEDL_PIN, HIGH);
183+
}
184+
185+
void spinRight() {
186+
digitalWrite(IN1_PIN, LOW);
187+
digitalWrite(IN2_PIN, HIGH);
188+
digitalWrite(IN3_PIN, HIGH);
189+
digitalWrite(IN4_PIN, LOW);
190+
analogWrite(ENA_PIN, SPD);
191+
analogWrite(ENB_PIN, SPD);
192+
193+
digitalWrite(LEDR_PIN, HIGH);
194+
digitalWrite(LEDL_PIN, LOW);
195+
}
196+
197+
void spinLeft() {
198+
digitalWrite(IN1_PIN, HIGH);
199+
digitalWrite(IN2_PIN, LOW);
200+
digitalWrite(IN3_PIN, LOW);
201+
digitalWrite(IN4_PIN, HIGH);
202+
analogWrite(ENA_PIN, SPD);
203+
analogWrite(ENB_PIN, SPD);
204+
205+
digitalWrite(LEDR_PIN, LOW);
206+
digitalWrite(LEDL_PIN, HIGH);
207+
}
208+
209+
void goBackward() {
210+
digitalWrite(IN1_PIN, HIGH);
211+
digitalWrite(IN2_PIN, LOW);
212+
digitalWrite(IN3_PIN, HIGH);
213+
digitalWrite(IN4_PIN, LOW);
214+
analogWrite(ENA_PIN, SPD);
215+
analogWrite(ENB_PIN, SPD);
216+
217+
digitalWrite(LEDR_PIN, HIGH);
218+
digitalWrite(LEDL_PIN, HIGH);
219+
}
220+
221+
void stopMovement() {
222+
digitalWrite(IN1_PIN, LOW);
223+
digitalWrite(IN2_PIN, LOW);
224+
digitalWrite(IN3_PIN, LOW);
225+
digitalWrite(IN4_PIN, LOW);
226+
analogWrite(ENA_PIN, 0);
227+
analogWrite(ENB_PIN, 0);
228+
}
229+
230+
void loop() {
231+
int cd = cDist();
232+
delay(33);
233+
int rd = rDist();
234+
delay(33);
235+
int ld = lDist();
236+
delay(33);
237+
238+
int dir = chooseDirection(cd, rd, ld);
239+
240+
#ifdef DEBUG
241+
debug(dir, cd, rd, ld);
242+
#endif
243+
244+
prd = rd;
245+
pcd = cd;
246+
pld = ld;
247+
pdir = dir;
248+
249+
switch (dir) {
250+
case _FWD:
251+
goForward();
252+
break;
253+
case _RHT:
254+
goRight();
255+
break;
256+
case _LFT:
257+
goLeft();
258+
break;
259+
case _SPR:
260+
spinRight();
261+
break;
262+
case _SPL:
263+
spinLeft();
264+
break;
265+
case _BCK:
266+
goBackward();
267+
break;
268+
default:
269+
stopMovement();
270+
break;
271+
}
272+
273+
delay(100);
274+
stopMovement();
275+
delay(100);
276+
}

0 commit comments

Comments
 (0)