191 lines
3.8 KiB
C++
191 lines
3.8 KiB
C++
#ifndef WiiChuck_h
|
|
#define WiiChuck_h
|
|
|
|
#include "Arduino.h"
|
|
#include "Wire.h"
|
|
#include "math.h"
|
|
|
|
|
|
// these may need to be adjusted for each nunchuck for calibration
|
|
#define ZEROX 510
|
|
#define ZEROY 490
|
|
#define ZEROZ 460
|
|
#define RADIUS 210 // probably pretty universal
|
|
|
|
#define DEFAULT_ZERO_JOY_X 124
|
|
#define DEFAULT_ZERO_JOY_Y 132
|
|
|
|
#define MAXANGLE 90
|
|
#define MINANGLE -90
|
|
|
|
class WiiChuck {
|
|
private:
|
|
byte cnt;
|
|
uint8_t status[6]; // array to store wiichuck output
|
|
byte averageCounter;
|
|
int i;
|
|
int total;
|
|
uint8_t zeroJoyX; // these are about where mine are
|
|
uint8_t zeroJoyY; // use calibrateJoy when the stick is at zero to correct
|
|
int lastJoyX;
|
|
int lastJoyY;
|
|
int angles[3];
|
|
|
|
boolean lastZ, lastC;
|
|
|
|
|
|
public:
|
|
|
|
byte joyX;
|
|
byte joyY;
|
|
boolean buttonZ;
|
|
boolean buttonC;
|
|
boolean plugd;
|
|
void begin()
|
|
{
|
|
Wire.begin();
|
|
cnt = 0;
|
|
averageCounter = 0;
|
|
Wire.beginTransmission (0x52); // transmit to device 0x52
|
|
Wire.write((byte)0x40); // sends memory address
|
|
Wire.write((byte)0x00); // sends memory address
|
|
Wire.endTransmission (); // stop transmitting
|
|
update();
|
|
for (i = 0; i<3;i++) {
|
|
angles[i] = 0;
|
|
}
|
|
zeroJoyX = DEFAULT_ZERO_JOY_X;
|
|
zeroJoyY = DEFAULT_ZERO_JOY_Y;
|
|
}
|
|
|
|
|
|
void calibrateJoy() {
|
|
zeroJoyX = joyX;
|
|
zeroJoyY = joyY;
|
|
}
|
|
|
|
void CheckifPlugd()
|
|
{
|
|
if (this->plugd == false){
|
|
this->begin();
|
|
|
|
#ifdef GLCD
|
|
GLCD.CursorTo(1, 1);
|
|
GLCD.print("No Chuck");
|
|
delay(100);
|
|
#endif
|
|
|
|
this->begin();
|
|
if (this->plugd)
|
|
this->calibrateJoy();
|
|
}
|
|
}
|
|
|
|
void update() {
|
|
|
|
Wire.requestFrom (0x52, 6); // request data from nunchuck
|
|
while (Wire.available ()) {
|
|
// receive byte as an integer
|
|
status[cnt] = _nunchuk_decode_byte((byte)Wire.read()); //
|
|
cnt++;
|
|
}
|
|
if (cnt > 5) {
|
|
lastZ = buttonZ;
|
|
lastC = buttonC;
|
|
lastJoyX = readJoyX();
|
|
lastJoyY = readJoyY();
|
|
|
|
cnt = 0;
|
|
joyX = (status[0]);
|
|
joyY = (status[1]);
|
|
for (i = 0; i < 3; i++)
|
|
angles[i] = (status[i+2] << 2) + ((status[5] & (B00000011 << ((i+1)*2) ) >> ((i+1)*2)));
|
|
|
|
buttonZ = !( status[5] & B00000001);
|
|
buttonC = !((status[5] & B00000010) >> 1);
|
|
_send_zero(); // send the request for next bytes
|
|
plugd = true;
|
|
}
|
|
else if (cnt == 0)
|
|
plugd = false;
|
|
}
|
|
|
|
float readAccelX() {
|
|
return (float)angles[0] - ZEROX;
|
|
}
|
|
float readAccelY() {
|
|
return (float)angles[1] - ZEROY;
|
|
}
|
|
float readAccelZ() {
|
|
return (float)angles[2] - ZEROZ;
|
|
}
|
|
|
|
boolean zPressed() {
|
|
return (buttonZ && ! lastZ);
|
|
}
|
|
boolean cPressed() {
|
|
return (buttonC && ! lastC);
|
|
}
|
|
|
|
// for using the joystick like a directional button
|
|
boolean rightJoy(int thresh=60) {
|
|
return (readJoyX() > thresh and lastJoyX <= thresh);
|
|
}
|
|
|
|
// for using the joystick like a directional button
|
|
boolean leftJoy(int thresh=60) {
|
|
return (readJoyX() < -thresh and lastJoyX >= -thresh);
|
|
}
|
|
|
|
|
|
int readJoyX() {
|
|
return (int) joyX - zeroJoyX;
|
|
}
|
|
|
|
int readJoyY() {
|
|
return (int)joyY - zeroJoyY;
|
|
}
|
|
|
|
|
|
// R, the radius, generally hovers around 210 (at least it does with mine)
|
|
int R() {
|
|
return sqrt(readAccelX() * readAccelX() +readAccelY() * readAccelY() + readAccelZ() * readAccelZ());
|
|
}
|
|
|
|
|
|
// returns roll degrees
|
|
int readRoll() {
|
|
return (int)(atan2(readAccelX(),readAccelZ())/ M_PI * 180.0);
|
|
}
|
|
|
|
// returns pitch in degrees
|
|
int readPitch() {
|
|
return (int) (acos(readAccelY()/RADIUS)/ M_PI * 180.0); // optionally swap 'RADIUS' for 'R()'
|
|
}
|
|
|
|
private:
|
|
byte _nunchuk_decode_byte (byte x)
|
|
{
|
|
x = (x ^ 0x17) + 0x17;
|
|
return x;
|
|
}
|
|
|
|
void _send_zero()
|
|
{
|
|
Wire.beginTransmission (0x52); // transmit to device 0x52
|
|
Wire.write ((byte)0x00); // sends one byte
|
|
Wire.endTransmission (); // stop transmitting
|
|
}
|
|
|
|
};
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|