Shinichiro Nakamura
/
Drive2ChoroQ
This is a demonstration of two Choro Q Hybrid cars.
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 joyX(0), joyY(0), accelX(0), accelY(0), accelZ(0), 00029 buttonC(0), buttonZ(0), nunchuckInit(false), 00030 nunchuckPort(sda, scl) { 00031 } 00032 00033 void WiiNunchuckReader::RequestRead() { 00034 // don't expect client to remember to send an init to the nunchuck 00035 // so do it for them here 00036 if (!nunchuckInit) { 00037 nunchuckInit = NunchuckInit(); 00038 } 00039 00040 if (nunchuckInit) { // don't start reading if init failed 00041 if (NunchuckRead()) { 00042 // only decode successful reads 00043 NunchuckDecode(); 00044 } 00045 } 00046 } 00047 00048 bool WiiNunchuckReader::NunchuckInit() { 00049 bool success = false; 00050 00051 const BYTE cmd[] = {NUNCHUCK_REGADDR, 0x00}; 00052 if (I2C_OK == nunchuckPort.write(NUNCHUCK_ADDR, (const char*)cmd, sizeof(cmd))) success = true; 00053 00054 return success; 00055 } 00056 00057 bool WiiNunchuckReader::NunchuckRead() { 00058 bool success = false; 00059 00060 // write the address we want to read from 00061 const BYTE cmd[] = {0x00}; 00062 if (I2C_OK == nunchuckPort.write(NUNCHUCK_ADDR, (const char*)cmd, sizeof(cmd))) { 00063 // the Wii Nunchuck is non-standard I2C 00064 // and can't manage setting the read address and immediately supplying the data 00065 // so wait a bit 00066 wait(I2C_READ_DELAY); 00067 00068 if (I2C_OK == nunchuckPort.read(NUNCHUCK_ADDR, readBuf, sizeof(readBuf))) success = true; 00069 } 00070 00071 return success; 00072 } 00073 00074 void WiiNunchuckReader::NunchuckDecode() { 00075 joyX = (int)readBuf[JOY_X]; 00076 joyY = (int)readBuf[JOY_Y]; 00077 00078 // the accelerometer axis values are really 10 bit values 00079 // so shift the 8 bit values read from the nunchuck 00080 // 2 bits to the right 00081 accelX = (int)readBuf[ACCEL_X] << 2; 00082 accelY = (int)readBuf[ACCEL_Y] << 2; 00083 accelZ = (int)readBuf[ACCEL_Z] << 2; 00084 00085 DecodeAdditional(); 00086 } 00087 00088 void WiiNunchuckReader::DecodeAdditional() { 00089 // the nunchcuk buttons have their own idea of state 00090 int buttonState = readBuf[ADDITIONAL] & MASK_CZ; 00091 switch (buttonState) { 00092 case 3: 00093 buttonZ = 0; 00094 buttonC = 0; 00095 break; 00096 case 2: 00097 buttonZ = 1; 00098 buttonC = 1; 00099 break; 00100 case 1: 00101 buttonZ = 0; 00102 buttonC = 1; 00103 break; 00104 case 0: 00105 buttonZ = 1; 00106 buttonC = 0; 00107 break; 00108 } 00109 00110 // and the accelerometer axis - for each axis value add bit 1 and bit 0 00111 // as required 00112 if (readBuf[ADDITIONAL] & MASK_ACCLX1) accelX += 2; 00113 if (readBuf[ADDITIONAL] & MASK_ACCLX2) accelX += 1; 00114 if (readBuf[ADDITIONAL] & MASK_ACCLY1) accelY += 2; 00115 if (readBuf[ADDITIONAL] & MASK_ACCLY2) accelY += 1; 00116 if (readBuf[ADDITIONAL] & MASK_ACCLZ1) accelZ += 2; 00117 if (readBuf[ADDITIONAL] & MASK_ACCLZ2) accelZ += 1; 00118 }
Generated on Wed Aug 3 2022 05:08:17 by 1.7.2