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