This is a example application for StarBoard Orange designed by @logic_star. This example can be drive a CHORO Q HYBRID.

Dependencies:   mbed

extlib/WiiNunchuck/WiiNunchuckReader.cpp

Committer:
shintamainjp
Date:
2010-09-20
Revision:
1:03c8bc666945
Parent:
0:127b9ca59547

File content as of revision 1:03c8bc666945:

/*
* WiiNunchuckReader. A program allowing the output of one or two
* Wii Nunchucks to be read via I2C and decoded for use, using the mbed
* microcontroller and its associated libraries.
*
* Copyright (C) <2009> Petras Saduikis <petras@petras.co.uk>
*
* This file is part of WiiNunchuckReader.
*
* WiiNunchuckReader is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* WiiNunchuckReader is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with WiiNunchuckReader.  If not, see <http://www.gnu.org/licenses/>.
*/

#include "WiiNunchuckReader.h"

// constructor
WiiNunchuckReader::WiiNunchuckReader(PinName sda, PinName scl) :
        joyX(0), joyY(0), accelX(0), accelY(0), accelZ(0),
        buttonC(0), buttonZ(0), nunchuckInit(false),
        nunchuckPort(sda, scl) {
}

void WiiNunchuckReader::RequestRead() {
    // don't expect client to remember to send an init to the nunchuck
    // so do it for them here
    if (!nunchuckInit) {
        nunchuckInit = NunchuckInit();
    }

    if (nunchuckInit) {  // don't start reading if init failed
        if (NunchuckRead()) {
            // only decode successful reads
            NunchuckDecode();
        }
    }
}

bool WiiNunchuckReader::NunchuckInit() {
    bool success = false;

    const BYTE cmd[] = {NUNCHUCK_REGADDR, 0x00};
    if (I2C_OK == nunchuckPort.write(NUNCHUCK_ADDR, (const char*)cmd, sizeof(cmd))) success = true;

    return success;
}

bool WiiNunchuckReader::NunchuckRead() {
    bool success = false;

    // write the address we want to read from
    const BYTE cmd[] = {0x00};
    if (I2C_OK == nunchuckPort.write(NUNCHUCK_ADDR, (const char*)cmd, sizeof(cmd))) {
        // the Wii Nunchuck is non-standard I2C
        // and can't manage setting the read address and immediately supplying the data
        // so wait a bit
        wait(I2C_READ_DELAY);

        if (I2C_OK == nunchuckPort.read(NUNCHUCK_ADDR, readBuf, sizeof(readBuf))) success = true;
    }

    return success;
}

void WiiNunchuckReader::NunchuckDecode() {
    joyX = (int)readBuf[JOY_X];
    joyY = (int)readBuf[JOY_Y];

    // the accelerometer axis values are really 10 bit values
    // so shift the 8 bit values read from the nunchuck
    // 2 bits to the right
    accelX = (int)readBuf[ACCEL_X] << 2;
    accelY = (int)readBuf[ACCEL_Y] << 2;
    accelZ = (int)readBuf[ACCEL_Z] << 2;

    DecodeAdditional();
}

void WiiNunchuckReader::DecodeAdditional() {
    // the nunchcuk buttons have their own idea of state
    int buttonState = readBuf[ADDITIONAL] & MASK_CZ;
    switch (buttonState) {
        case 3:
            buttonZ = 0;
            buttonC = 0;
            break;
        case 2:
            buttonZ = 1;
            buttonC = 1;
            break;
        case 1:
            buttonZ = 0;
            buttonC = 1;
            break;
        case 0:
            buttonZ = 1;
            buttonC = 0;
            break;
    }

    // and the accelerometer axis - for each axis value add bit 1 and bit 0
    // as required
    if (readBuf[ADDITIONAL] & MASK_ACCLX1) accelX += 2;
    if (readBuf[ADDITIONAL] & MASK_ACCLX2) accelX += 1;
    if (readBuf[ADDITIONAL] & MASK_ACCLY1) accelY += 2;
    if (readBuf[ADDITIONAL] & MASK_ACCLY2) accelY += 1;
    if (readBuf[ADDITIONAL] & MASK_ACCLZ1) accelZ += 2;
    if (readBuf[ADDITIONAL] & MASK_ACCLZ2) accelZ += 1;
}