Team: Yu Jiang & Max Kornyev

Maze Frame 3D Design

We created a CAD rendering of our basic maze design, which will be ready to be laser cut and assembled next week.

Handsfree Controller

We also refined our sensor input to create a responsive handsfree control of a 20 degree tilt on the two maze axes. We employ a simple filter to scale the value to our desired range, and implemented incremental movement of our servo mechanism.

The input is relatively faultless, but a low pass filter could also be implemented to avoid the occasional erroneous reading.

Code Artifacts

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
#include <Servo.h&gt;
bool DEBUG = true; // Print output
 
 
// CONSTANTS
const int X_SERVO_PIN = 6;
const int Y_SERVO_PIN = 7;
 
const int L_ECHO_PIN = 13;
const int L_TRIGGER_PIN = 12;
const int R_ECHO_PIN = 11;
const int R_TRIGGER_PIN = 10;
 
// Change the following as needed
const int MAX_ANGLE = 20;  // Max angle that the servo will rotate in either direction
const int START_ANGLE = 15; // Starting angle for a servo
 
const int MAX_DISTANCE = 30; // cm
const int MIN_DISTANCE = 0;
 
// GLOBALS
Servo xServo;
Servo yServo;
float leftDistance; // Hand distance in cm
float rightDistance;
int lAngle; // Corresponding servo angle
int rAngle;
 
void setup()
{
 Serial.begin(9600);
 xServo.attach(X_SERVO_PIN);
 yServo.attach(Y_SERVO_PIN);
 pinMode(X_SERVO_PIN, OUTPUT);
 pinMode(Y_SERVO_PIN, OUTPUT);
 xServo.write(START_ANGLE);
 yServo.write(START_ANGLE);
}
 
void loop()
{
 // Get hardware input
 leftDistance = 0.01723 * handDistance(L_TRIGGER_PIN, L_ECHO_PIN);
 lAngle = map(leftDistance, 0, MAX_DISTANCE, -MAX_ANGLE, MAX_ANGLE);
 
 rightDistance = 0.01723 * handDistance(R_TRIGGER_PIN, R_ECHO_PIN);
 rAngle = map(rightDistance, 0, MAX_DISTANCE, -MAX_ANGLE, MAX_ANGLE);
 
 // Sanitize input
 sanitizeAngles();
 
 if (DEBUG) {
   Serial.print("L: ");
   Serial.print(leftDistance);
   Serial.print(" --&gt; ");
   Serial.println(lAngle);
 
   Serial.print("R: ");
   Serial.print(rightDistance);
   Serial.print(" --&gt; ");
   Serial.println(rAngle);
 }
 
 // Smooth motion
 moveServo(yServo, START_ANGLE + lAngle); // L
 moveServo(xServo, START_ANGLE + rAngle); // R
 
 // Naive Motion
 //yServo.write(START_ANGLE + lAngle); // L
 //xServo.write(START_ANGLE + rAngle); // R
 
 delay(100);
}
 
long handDistance(int TRIGGER_PIN, int ECHO_PIN)
{
 pinMode(TRIGGER_PIN, OUTPUT);
 digitalWrite(TRIGGER_PIN, LOW);
 delayMicroseconds(2);
 digitalWrite(TRIGGER_PIN, HIGH);
 delayMicroseconds(10);
 digitalWrite(TRIGGER_PIN, LOW);
 pinMode(ECHO_PIN, INPUT);
 return pulseIn(ECHO_PIN, HIGH);
}
 
// Prepares the input for parsing
void sanitizeAngles() {
 if (lAngle &gt; MAX_ANGLE) { // Left
   lAngle = MAX_ANGLE;
 }
 if (lAngle < -MAX_ANGLE) {
   lAngle = -MAX_ANGLE;
 }
 if (rAngle &gt; MAX_ANGLE) { // Right
   rAngle = MAX_ANGLE;
 }
 if (rAngle < -MAX_ANGLE) {
   rAngle = -MAX_ANGLE;
 }
}
 
// Smooth/incremented servo movement
void moveServo(Servo &amp;s, int angle) { // pass servo by reference
 int previousAngle = s.read();
 
 if (angle &gt; previousAngle)
 {
   for (int i = previousAngle; i <= angle; i++)
   {
     s.write(i);
     delay(10);
   }
 }
 
 if (angle < previousAngle)
 {
   for (int i = previousAngle; i &gt;= angle; i--)
   {
     s.write(i);
     delay(10);
   }
 }
}