Shinichiro Nakamura
/
Drive2ChoroQ
This is a demonstration of two Choro Q Hybrid cars.
extlib/WiiNunchuck/WiiNunchuckReader.cpp@0:d825f8dae2be, 2010-11-22 (annotated)
- Committer:
- shintamainjp
- Date:
- Mon Nov 22 12:23:23 2010 +0000
- Revision:
- 0:d825f8dae2be
Initial version.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
shintamainjp | 0:d825f8dae2be | 1 | /* |
shintamainjp | 0:d825f8dae2be | 2 | * WiiNunchuckReader. A program allowing the output of one or two |
shintamainjp | 0:d825f8dae2be | 3 | * Wii Nunchucks to be read via I2C and decoded for use, using the mbed |
shintamainjp | 0:d825f8dae2be | 4 | * microcontroller and its associated libraries. |
shintamainjp | 0:d825f8dae2be | 5 | * |
shintamainjp | 0:d825f8dae2be | 6 | * Copyright (C) <2009> Petras Saduikis <petras@petras.co.uk> |
shintamainjp | 0:d825f8dae2be | 7 | * |
shintamainjp | 0:d825f8dae2be | 8 | * This file is part of WiiNunchuckReader. |
shintamainjp | 0:d825f8dae2be | 9 | * |
shintamainjp | 0:d825f8dae2be | 10 | * WiiNunchuckReader is free software: you can redistribute it and/or modify |
shintamainjp | 0:d825f8dae2be | 11 | * it under the terms of the GNU General Public License as published by |
shintamainjp | 0:d825f8dae2be | 12 | * the Free Software Foundation, either version 3 of the License, or |
shintamainjp | 0:d825f8dae2be | 13 | * (at your option) any later version. |
shintamainjp | 0:d825f8dae2be | 14 | * |
shintamainjp | 0:d825f8dae2be | 15 | * WiiNunchuckReader is distributed in the hope that it will be useful, |
shintamainjp | 0:d825f8dae2be | 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
shintamainjp | 0:d825f8dae2be | 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
shintamainjp | 0:d825f8dae2be | 18 | * GNU General Public License for more details. |
shintamainjp | 0:d825f8dae2be | 19 | * |
shintamainjp | 0:d825f8dae2be | 20 | * You should have received a copy of the GNU General Public License |
shintamainjp | 0:d825f8dae2be | 21 | * along with WiiNunchuckReader. If not, see <http://www.gnu.org/licenses/>. |
shintamainjp | 0:d825f8dae2be | 22 | */ |
shintamainjp | 0:d825f8dae2be | 23 | |
shintamainjp | 0:d825f8dae2be | 24 | #include "WiiNunchuckReader.h" |
shintamainjp | 0:d825f8dae2be | 25 | |
shintamainjp | 0:d825f8dae2be | 26 | // constructor |
shintamainjp | 0:d825f8dae2be | 27 | WiiNunchuckReader::WiiNunchuckReader(PinName sda, PinName scl) : |
shintamainjp | 0:d825f8dae2be | 28 | joyX(0), joyY(0), accelX(0), accelY(0), accelZ(0), |
shintamainjp | 0:d825f8dae2be | 29 | buttonC(0), buttonZ(0), nunchuckInit(false), |
shintamainjp | 0:d825f8dae2be | 30 | nunchuckPort(sda, scl) { |
shintamainjp | 0:d825f8dae2be | 31 | } |
shintamainjp | 0:d825f8dae2be | 32 | |
shintamainjp | 0:d825f8dae2be | 33 | void WiiNunchuckReader::RequestRead() { |
shintamainjp | 0:d825f8dae2be | 34 | // don't expect client to remember to send an init to the nunchuck |
shintamainjp | 0:d825f8dae2be | 35 | // so do it for them here |
shintamainjp | 0:d825f8dae2be | 36 | if (!nunchuckInit) { |
shintamainjp | 0:d825f8dae2be | 37 | nunchuckInit = NunchuckInit(); |
shintamainjp | 0:d825f8dae2be | 38 | } |
shintamainjp | 0:d825f8dae2be | 39 | |
shintamainjp | 0:d825f8dae2be | 40 | if (nunchuckInit) { // don't start reading if init failed |
shintamainjp | 0:d825f8dae2be | 41 | if (NunchuckRead()) { |
shintamainjp | 0:d825f8dae2be | 42 | // only decode successful reads |
shintamainjp | 0:d825f8dae2be | 43 | NunchuckDecode(); |
shintamainjp | 0:d825f8dae2be | 44 | } |
shintamainjp | 0:d825f8dae2be | 45 | } |
shintamainjp | 0:d825f8dae2be | 46 | } |
shintamainjp | 0:d825f8dae2be | 47 | |
shintamainjp | 0:d825f8dae2be | 48 | bool WiiNunchuckReader::NunchuckInit() { |
shintamainjp | 0:d825f8dae2be | 49 | bool success = false; |
shintamainjp | 0:d825f8dae2be | 50 | |
shintamainjp | 0:d825f8dae2be | 51 | const BYTE cmd[] = {NUNCHUCK_REGADDR, 0x00}; |
shintamainjp | 0:d825f8dae2be | 52 | if (I2C_OK == nunchuckPort.write(NUNCHUCK_ADDR, (const char*)cmd, sizeof(cmd))) success = true; |
shintamainjp | 0:d825f8dae2be | 53 | |
shintamainjp | 0:d825f8dae2be | 54 | return success; |
shintamainjp | 0:d825f8dae2be | 55 | } |
shintamainjp | 0:d825f8dae2be | 56 | |
shintamainjp | 0:d825f8dae2be | 57 | bool WiiNunchuckReader::NunchuckRead() { |
shintamainjp | 0:d825f8dae2be | 58 | bool success = false; |
shintamainjp | 0:d825f8dae2be | 59 | |
shintamainjp | 0:d825f8dae2be | 60 | // write the address we want to read from |
shintamainjp | 0:d825f8dae2be | 61 | const BYTE cmd[] = {0x00}; |
shintamainjp | 0:d825f8dae2be | 62 | if (I2C_OK == nunchuckPort.write(NUNCHUCK_ADDR, (const char*)cmd, sizeof(cmd))) { |
shintamainjp | 0:d825f8dae2be | 63 | // the Wii Nunchuck is non-standard I2C |
shintamainjp | 0:d825f8dae2be | 64 | // and can't manage setting the read address and immediately supplying the data |
shintamainjp | 0:d825f8dae2be | 65 | // so wait a bit |
shintamainjp | 0:d825f8dae2be | 66 | wait(I2C_READ_DELAY); |
shintamainjp | 0:d825f8dae2be | 67 | |
shintamainjp | 0:d825f8dae2be | 68 | if (I2C_OK == nunchuckPort.read(NUNCHUCK_ADDR, readBuf, sizeof(readBuf))) success = true; |
shintamainjp | 0:d825f8dae2be | 69 | } |
shintamainjp | 0:d825f8dae2be | 70 | |
shintamainjp | 0:d825f8dae2be | 71 | return success; |
shintamainjp | 0:d825f8dae2be | 72 | } |
shintamainjp | 0:d825f8dae2be | 73 | |
shintamainjp | 0:d825f8dae2be | 74 | void WiiNunchuckReader::NunchuckDecode() { |
shintamainjp | 0:d825f8dae2be | 75 | joyX = (int)readBuf[JOY_X]; |
shintamainjp | 0:d825f8dae2be | 76 | joyY = (int)readBuf[JOY_Y]; |
shintamainjp | 0:d825f8dae2be | 77 | |
shintamainjp | 0:d825f8dae2be | 78 | // the accelerometer axis values are really 10 bit values |
shintamainjp | 0:d825f8dae2be | 79 | // so shift the 8 bit values read from the nunchuck |
shintamainjp | 0:d825f8dae2be | 80 | // 2 bits to the right |
shintamainjp | 0:d825f8dae2be | 81 | accelX = (int)readBuf[ACCEL_X] << 2; |
shintamainjp | 0:d825f8dae2be | 82 | accelY = (int)readBuf[ACCEL_Y] << 2; |
shintamainjp | 0:d825f8dae2be | 83 | accelZ = (int)readBuf[ACCEL_Z] << 2; |
shintamainjp | 0:d825f8dae2be | 84 | |
shintamainjp | 0:d825f8dae2be | 85 | DecodeAdditional(); |
shintamainjp | 0:d825f8dae2be | 86 | } |
shintamainjp | 0:d825f8dae2be | 87 | |
shintamainjp | 0:d825f8dae2be | 88 | void WiiNunchuckReader::DecodeAdditional() { |
shintamainjp | 0:d825f8dae2be | 89 | // the nunchcuk buttons have their own idea of state |
shintamainjp | 0:d825f8dae2be | 90 | int buttonState = readBuf[ADDITIONAL] & MASK_CZ; |
shintamainjp | 0:d825f8dae2be | 91 | switch (buttonState) { |
shintamainjp | 0:d825f8dae2be | 92 | case 3: |
shintamainjp | 0:d825f8dae2be | 93 | buttonZ = 0; |
shintamainjp | 0:d825f8dae2be | 94 | buttonC = 0; |
shintamainjp | 0:d825f8dae2be | 95 | break; |
shintamainjp | 0:d825f8dae2be | 96 | case 2: |
shintamainjp | 0:d825f8dae2be | 97 | buttonZ = 1; |
shintamainjp | 0:d825f8dae2be | 98 | buttonC = 1; |
shintamainjp | 0:d825f8dae2be | 99 | break; |
shintamainjp | 0:d825f8dae2be | 100 | case 1: |
shintamainjp | 0:d825f8dae2be | 101 | buttonZ = 0; |
shintamainjp | 0:d825f8dae2be | 102 | buttonC = 1; |
shintamainjp | 0:d825f8dae2be | 103 | break; |
shintamainjp | 0:d825f8dae2be | 104 | case 0: |
shintamainjp | 0:d825f8dae2be | 105 | buttonZ = 1; |
shintamainjp | 0:d825f8dae2be | 106 | buttonC = 0; |
shintamainjp | 0:d825f8dae2be | 107 | break; |
shintamainjp | 0:d825f8dae2be | 108 | } |
shintamainjp | 0:d825f8dae2be | 109 | |
shintamainjp | 0:d825f8dae2be | 110 | // and the accelerometer axis - for each axis value add bit 1 and bit 0 |
shintamainjp | 0:d825f8dae2be | 111 | // as required |
shintamainjp | 0:d825f8dae2be | 112 | if (readBuf[ADDITIONAL] & MASK_ACCLX1) accelX += 2; |
shintamainjp | 0:d825f8dae2be | 113 | if (readBuf[ADDITIONAL] & MASK_ACCLX2) accelX += 1; |
shintamainjp | 0:d825f8dae2be | 114 | if (readBuf[ADDITIONAL] & MASK_ACCLY1) accelY += 2; |
shintamainjp | 0:d825f8dae2be | 115 | if (readBuf[ADDITIONAL] & MASK_ACCLY2) accelY += 1; |
shintamainjp | 0:d825f8dae2be | 116 | if (readBuf[ADDITIONAL] & MASK_ACCLZ1) accelZ += 2; |
shintamainjp | 0:d825f8dae2be | 117 | if (readBuf[ADDITIONAL] & MASK_ACCLZ2) accelZ += 1; |
shintamainjp | 0:d825f8dae2be | 118 | } |