-
Notifications
You must be signed in to change notification settings - Fork 1
/
yoda_control.ino
172 lines (163 loc) · 4.45 KB
/
yoda_control.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
#include <XBOXONE.h>
#include <Servo.h>
#include <SPI.h>
/**
How to use Baby Yoda:
Setup requirements:
- Arduino Uno
- USB Host Shield 2.0
- USB to USB-C cable
- XBOX ONE (S) controller
- Solder?
Setup process:
- Make sure the 3.3 / 5V pin connections and the 5V VBUS PWR connection are soldered. If there's no solder on them, solder them.
- Connect the controller to the cable to the host shield to the Uno to your PC.
- Upload the sketch to the Arduino.
- Turn the controller on.
(Note: This part can be finicky. If the controller is on and doesn't work, turn the Arduino off,
then turn the Arduino and controller on simultaneously. Repeat until it responds to input.)
Usage:
- The arrow keys control what servos the joysticks control. Pressing LEFT will make them control the left arm/elbow, RIGHT will make them control the right arm/elbow,
and UP will make them control the head/neck. DOWN will make them control nothing.
- The joysticks control what direction the servos rotate in. Holding right will make them rotate to the right and vice-versa.
- The triggers control the speed the servos rotate at. Pressing LT will make them rotate slower and RT will make them rotate faster.
*/
USB Usb;
XBOXONE Xbox(&Usb);
// all servos are 0-180 degrees
Servo leftArm;
int leftArmState = 1500;
Servo leftElbow;
int leftElbowState = 1500;
Servo rightArm;
int rightArmState = 1500;
Servo rightElbow;
int rightElbowState = 1500;
Servo head;
int headState = 1500;
Servo neck;
int neckState = 1500;
// 0: left arm, 1: right arm, 2: head
int joystickState = 0;
Servo currentLeft = leftArm;
Servo currentRight = leftElbow;
int *currentLeftState = &leftArmState;
int *currentRightState = &leftElbowState;
int speed = 1;
void setup()
{
Serial.begin(115200);
while (!Serial)
; // Wait for serial port to connect - used on Leonardo, Teensy and other boards with built-in USB CDC serial connection
if (Usb.Init() == -1)
{
Serial.print(F("\r\nOSC did not start"));
while (1)
; // halt
}
// can't use pins 0, 1, 10, 11, 12, 13 on SPI
leftArm.attach(2);
// leftElbowServo.attach(7);
Serial.print(F("\r\nSetup complete"));
}
void loop()
{
Usb.Task();
if (Xbox.XboxOneConnected)
{
if (Xbox.getButtonClick(UP))
{
joystickState = 2;
Serial.println(F("Up"));
}
if (Xbox.getButtonClick(LEFT))
{
joystickState = 0;
Serial.println(F("Left"));
}
if (Xbox.getButtonClick(RIGHT))
{
joystickState = 1;
Serial.println(F("Right"));
}
if (Xbox.getButtonClick(DOWN))
{
joystickState = 3;
Serial.println(F("Down"));
}
if (Xbox.getButtonClick(LT))
{
Serial.println(F("LT"));
speed -= 1;
if (speed < 1)
{
speed = 1;
}
}
if (Xbox.getButtonClick(RT))
{
Serial.println(F("RT"));
speed += 1;
if (speed > 10)
{
speed = 10;
}
}
int16_t leftX = Xbox.getAnalogHat(LeftHatX);
int16_t rightX = Xbox.getAnalogHat(RightHatX);
if (joystickState == 0)
{
currentLeft = leftArm;
currentRight = leftElbow;
currentLeftState = &leftArmState;
currentRightState = &leftElbowState;
}
else if (joystickState == 1)
{
currentLeft = rightArm;
currentRight = rightElbow;
currentLeftState = &rightArmState;
currentRightState = &rightElbowState;
}
else if (joystickState == 2)
{
currentLeft = head;
currentRight = neck;
currentLeftState = &headState;
currentRightState = &neckState;
}
// may need special handling for head / neck?
// TODO: change speed depending on joystick magnitude?
if (joystickState != 3 && (leftX > 7500 || leftX < -7500))
{
if (leftX > 0)
{
*currentLeftState = min(2000, *currentLeftState + speed * 5);
}
else
{
*currentLeftState = max(1000, *currentLeftState - speed * 5);
}
currentLeft.writeMicroseconds(*currentLeftState);
Serial.println(*currentLeftState);
}
if (rightX > 7500 || rightX < -7500)
{
if (rightX > 0)
{
*currentRightState = min(2000, *currentRightState + speed * 5);
}
else
{
*currentRightState = max(1000, *currentRightState - speed * 5);
}
// currentRight.writeMicroseconds(*currentRightState);
Serial.println(*currentRightState);
}
if (leftX > 7500 || leftX < -7500 || rightX > 7500 || rightX < -7500)
{
delay(100);
}
}
delay(1);
}