forked from Comingle/OSSex
-
Notifications
You must be signed in to change notification settings - Fork 0
/
WiiChuck.cpp
207 lines (166 loc) · 5.09 KB
/
WiiChuck.cpp
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
// WiiChuck library -- originally by Tim Hirzel, building off of Tod Kurt,
// building off of Windmeadow Labs
// June 2015 - modified by Craig Durkin / Comingle. v0.1.
#include <WiiChuck.h>
WiiChuck::WiiChuck() {
buttonZ.button.setActiveLow(false);
buttonC.button.setActiveLow(false);
}
WiiChuck::WiiChuck(bool (*c_update)(void), bool (*z_update)(void)) {
buttonZ.button.setActiveLow(false);
buttonC.button.setActiveLow(false);
attachZUpdate(z_update);
attachCUpdate(c_update);
}
void WiiChuck::begin()
{
//send initialization handshake
Wire.begin();
//averageCounter = 0;
// instead of the common 0x40 -> 0x00 initialization, we
// use 0xF0 -> 0x55 followed by 0xFB -> 0x00.
// this lets us use 3rd party nunchucks (like cheap $4 ebay ones)
// while still letting us use official oness.
// only side effect is that we no longer need to decode bytes in _nunchuk_decode_byte
// see http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1264805255
//
Wire.beginTransmission(0x52); // device address
Wire.write(0xF0);
Wire.write(0x55);
Wire.endTransmission();
delay(1);
Wire.beginTransmission(0x52);
Wire.write(0xFB);
Wire.write((uint8_t)0x00);
Wire.endTransmission();
update();
for (int i = 0; i < 3;i++) {
angles[i] = 0;
}
zeroJoyX = DEFAULT_ZERO_JOY_X;
zeroJoyY = DEFAULT_ZERO_JOY_Y;
}
void WiiChuck::calibrateJoy() {
zeroJoyX = joyX;
zeroJoyY = joyY;
}
void WiiChuck::update() {
uint8_t cnt = 0;
Wire.requestFrom (0x52, 6);
if (Wire.available()) {
do {
// receive byte as an integer
status[cnt] = Wire.read();
cnt++;
} while (Wire.available());
if (cnt > 5) {
lastJoyX = readJoyX();
lastJoyY = readJoyY();
joyX = status[0];
joyY = status[1];
for (int i = 0; i < 3; i++) {
angles[i] = (status[i+2] << 2) + ((status[5] & (B00000011 << ((i+1)*2) ) >> ((i+1)*2)));
}
buttonZ.value = !(status[5] & B00000001);
buttonC.value = !((status[5] & B00000010) >> 1);
buttonZ.button.tick();
buttonC.button.tick();
_send_zero(); // send the request for next bytes
cnt = 0;
}
} else {
for (cnt; cnt < 6; cnt++) {
status[cnt] = 255;
}
}
}
byte * WiiChuck::getStatus() {
return status;
}
float WiiChuck::readAccelX() {
// total = 0; // accelArray[xyz][averageCounter] * FAST_WEIGHT;
return (float)angles[0] - ZEROX;
}
float WiiChuck::readAccelY() {
// total = 0; // accelArray[xyz][averageCounter] * FAST_WEIGHT;
return (float)angles[1] - ZEROY;
}
float WiiChuck::readAccelZ() {
// total = 0; // accelArray[xyz][averageCounter] * FAST_WEIGHT;
return (float)angles[2] - ZEROZ;
}
bool WiiChuck::zPressed() {
return buttonZ.value;
}
bool WiiChuck::cPressed() {
return buttonC.value;
}
// COMBINE right/leftJoy?
// for using the joystick like a directional button
bool WiiChuck::rightJoy(int thresh=60) {
return (readJoyX() > thresh and lastJoyX <= thresh);
}
// for using the joystick like a directional button
bool WiiChuck::leftJoy(int thresh=60) {
return (readJoyX() < -thresh and lastJoyX >= -thresh);
}
uint8_t WiiChuck::readJoyX() {
return joyX; // - zeroJoyX;
}
uint8_t WiiChuck::readJoyY() {
return joyY; // - zeroJoyY;
}
//R, the radius, generally hovers around 210 (at least it does with mine)
int WiiChuck::R() {
return sqrt(readAccelX() * readAccelX() +readAccelY() * readAccelY() + readAccelZ() * readAccelZ());
}
// returns roll degrees
int WiiChuck::readRoll() {
return (int)(atan2(readAccelX(),readAccelZ())/ M_PI * 180.0);
}
// returns pitch in degrees
int WiiChuck::readPitch() {
return (int) (acos(readAccelY()/R())/ M_PI * 180.0); // optionally swap 'RADIUS' for 'R()'
}
void WiiChuck::_send_zero()
{
Wire.beginTransmission (0x52);
Wire.write ((uint8_t)0x00);
Wire.endTransmission ();
}
void WiiChuck::attachZClick(void (*callback)(void)) {
buttonZ.button.attachClick(callback);
}
void WiiChuck::attachZDoubleClick(void (*callback)(void)) {
buttonZ.button.attachDoubleClick(callback);
}
void WiiChuck::attachZUpdate(bool (*callback)(void)) {
buttonZ.button.setPseudo(callback);
}
void WiiChuck::attachZLongPressStart(void (*callback)()) {
buttonZ.button.attachLongPressStart(callback);
}
void WiiChuck::attachZDuringLongPress(void (*callback)()) {
buttonZ.button.attachDuringLongPress(callback);
}
void WiiChuck::attachZLongPressStop(void (*callback)()) {
buttonZ.button.attachLongPressStop(callback);
}
void WiiChuck::attachCClick(void (*callback)(void)) {
buttonC.button.attachClick(callback);
}
void WiiChuck::attachCDoubleClick(void (*callback)(void)) {
buttonC.button.attachDoubleClick(callback);
}
void WiiChuck::attachCLongPressStart(void (*callback)()) {
buttonC.button.attachLongPressStart(callback);
}
void WiiChuck::attachCDuringLongPress(void (*callback)()) {
buttonC.button.attachDuringLongPress(callback);
}
void WiiChuck::attachCLongPressStop(void (*callback)()) {
buttonC.button.attachLongPressStop(callback);
}
void WiiChuck::attachCUpdate(bool (*callback)(void)) {
buttonC.button.setPseudo(callback);
}