Petras Saduikis
/
WiiNunchuckReader
A program allowing the output of one or two Wii Nunchucks to be read via I2C and decoded for use.
Embed:
(wiki syntax)
Show/hide line numbers
WiiNunchuckReader.cpp
00001 /* 00002 * WiiNunchuckReader. A program allowing the output of one or two 00003 * Wii Nunchucks to be read via I2C and decoded for use, using the mbed 00004 * microcontroller and its associated libraries. 00005 * 00006 * Copyright (C) <2009> Petras Saduikis <petras@petras.co.uk> 00007 * 00008 * This file is part of WiiNunchuckReader. 00009 * 00010 * WiiNunchuckReader is free software: you can redistribute it and/or modify 00011 * it under the terms of the GNU General Public License as published by 00012 * the Free Software Foundation, either version 3 of the License, or 00013 * (at your option) any later version. 00014 * 00015 * WiiNunchuckReader is distributed in the hope that it will be useful, 00016 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00017 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00018 * GNU General Public License for more details. 00019 * 00020 * You should have received a copy of the GNU General Public License 00021 * along with WiiNunchuckReader. If not, see <http://www.gnu.org/licenses/>. 00022 */ 00023 00024 #include "WiiNunchuckReader.h" 00025 00026 // constructor 00027 WiiNunchuckReader::WiiNunchuckReader(PinName sda, PinName scl) : 00028 nunchuckPort(sda, scl), 00029 joyX(0), joyY(0), accelX(0), accelY(0), accelZ(0), 00030 buttonC(0), buttonZ(0), nunchuckInit(false) 00031 { 00032 } 00033 00034 void WiiNunchuckReader::RequestRead() 00035 { 00036 // don't expect client to remember to send an init to the nunchuck 00037 // so do it for them here 00038 if (!nunchuckInit) 00039 { 00040 nunchuckInit = NunchuckInit(); 00041 } 00042 00043 if (nunchuckInit) // don't start reading if init failed 00044 { 00045 if (NunchuckRead()) 00046 { 00047 // only decode successful reads 00048 NunchuckDecode(); 00049 } 00050 } 00051 } 00052 00053 bool WiiNunchuckReader::NunchuckInit() 00054 { 00055 bool success = false; 00056 00057 const BYTE cmd[] = {NUNCHUCK_REGADDR, 0x00}; 00058 if (I2C_OK == nunchuckPort.write(NUNCHUCK_ADDR, (const char*)cmd, sizeof(cmd))) success = true; 00059 00060 return success; 00061 } 00062 00063 bool WiiNunchuckReader::NunchuckRead() 00064 { 00065 bool success = false; 00066 00067 // write the address we want to read from 00068 const BYTE cmd[] = {0x00}; 00069 if (I2C_OK == nunchuckPort.write(NUNCHUCK_ADDR, (const char*)cmd, sizeof(cmd))) 00070 { 00071 // the Wii Nunchuck is non-standard I2C 00072 // and can't manage setting the read address and immediately supplying the data 00073 // so wait a bit 00074 wait(I2C_READ_DELAY); 00075 00076 if (I2C_OK == nunchuckPort.read(NUNCHUCK_ADDR, readBuf, sizeof(readBuf))) success = true; 00077 } 00078 00079 return success; 00080 } 00081 00082 void WiiNunchuckReader::NunchuckDecode() 00083 { 00084 joyX = (int)readBuf[JOY_X]; 00085 joyY = (int)readBuf[JOY_Y]; 00086 00087 // the accelerometer axis values are really 10 bit values 00088 // so shift the 8 bit values read from the nunchuck 00089 // 2 bits to the right 00090 accelX = (int)readBuf[ACCEL_X] << 2; 00091 accelY = (int)readBuf[ACCEL_Y] << 2; 00092 accelZ = (int)readBuf[ACCEL_Z] << 2; 00093 00094 DecodeAdditional(); 00095 } 00096 00097 void WiiNunchuckReader::DecodeAdditional() 00098 { 00099 // the nunchcuk buttons have their own idea of state 00100 int buttonState = readBuf[ADDITIONAL] & MASK_CZ; 00101 switch (buttonState) 00102 { 00103 case 3: 00104 buttonZ = 0; 00105 buttonC = 0; 00106 break; 00107 case 2: 00108 buttonZ = 1; 00109 buttonC = 1; 00110 break; 00111 case 1: 00112 buttonZ = 0; 00113 buttonC = 1; 00114 break; 00115 case 0: 00116 buttonZ = 1; 00117 buttonC = 0; 00118 break; 00119 } 00120 00121 // and the accelerometer axis - for each axis value add bit 1 and bit 0 00122 // as required 00123 if (readBuf[ADDITIONAL] & MASK_ACCLX1) accelX += 2; 00124 if (readBuf[ADDITIONAL] & MASK_ACCLX2) accelX += 1; 00125 if (readBuf[ADDITIONAL] & MASK_ACCLY1) accelY += 2; 00126 if (readBuf[ADDITIONAL] & MASK_ACCLY2) accelY += 1; 00127 if (readBuf[ADDITIONAL] & MASK_ACCLZ1) accelZ += 2; 00128 if (readBuf[ADDITIONAL] & MASK_ACCLZ2) accelZ += 1; 00129 }
Generated on Tue Jul 12 2022 21:00:58 by 1.7.2