This is a demonstration of two Choro Q Hybrid cars.

Revision:
0:d825f8dae2be
diff -r 000000000000 -r d825f8dae2be extlib/WiiNunchuck/WiiNunchuckReader.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/extlib/WiiNunchuck/WiiNunchuckReader.cpp	Mon Nov 22 12:23:23 2010 +0000
@@ -0,0 +1,118 @@
+/*
+* 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;
+}
\ No newline at end of file