diff --git a/README.md b/README.md index d987316..a40450e 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,7 @@ This is an Arduino library for talking to Nintendo extension controllers over I ## Supported Controllers * Wii Nunchuk * Wii Classic Controller +* Guitar Hero Guitar ## License This library is licensed under the terms of the [GNU Lesser General Public License (LGPL)](https://www.gnu.org/licenses/lgpl.html), either version 3 of the License, or (at your option) any later version. diff --git a/examples/Generic/IdentifyController/IdentifyController.ino b/examples/Generic/IdentifyController/IdentifyController.ino index 07a3db5..82cc2f6 100644 --- a/examples/Generic/IdentifyController/IdentifyController.ino +++ b/examples/Generic/IdentifyController/IdentifyController.ino @@ -21,6 +21,9 @@ void setup() { case(NXC_ClassicController): Serial.println("Classic Controller detected!"); break; + case(NXC_GuitarController): + Serial.println("Guitar controller connected!"); + break; } } diff --git a/examples/Guitar/Guitar_DebugPrint/Guitar_DebugPrint.ino b/examples/Guitar/Guitar_DebugPrint/Guitar_DebugPrint.ino new file mode 100644 index 0000000..291cb6c --- /dev/null +++ b/examples/Guitar/Guitar_DebugPrint/Guitar_DebugPrint.ino @@ -0,0 +1,24 @@ +#include + +GuitarController guitar; + +void setup() { + Serial.begin(115200); + + while (!guitar.begin()) { + Serial.println("Guitar controller not detected!"); + delay(1000); + } +} + +void loop() { + boolean success = guitar.update(); // Get new data from the controller + + if (success == true) { // We've got data! + guitar.printDebug(); // Print all of the values! + } + else { // Data is bad :( + Serial.println("Controller Disconnected!"); + guitar.reconnect(); + } +} diff --git a/examples/Guitar/Guitar_Demo/Guitar_Demo.ino b/examples/Guitar/Guitar_Demo/Guitar_Demo.ino new file mode 100644 index 0000000..495513e --- /dev/null +++ b/examples/Guitar/Guitar_Demo/Guitar_Demo.ino @@ -0,0 +1,95 @@ +#include + +GuitarController guitar; + +void setup() { + Serial.begin(115200); + + while (!guitar.begin()) { + Serial.println("Guitar controller not detected!"); + delay(1000); + } +} + +void loop() { + Serial.println("----- Guitar Controller Demo -----"); // Making things easier to read + + boolean success = guitar.update(); // Get new data from the controller + + if (!success) { // Ruh roh + Serial.println("Controller disconnected!"); + delay(1000); + } + else { + // Read the strum bar (up/down, or neither) + Serial.print("The strum bar is "); + + if (guitar.strumUp()) { + Serial.println("pressed up"); + } + else if (guitar.strumDown()) { + Serial.println("pressed down"); + } + else { + Serial.println("not pressed"); + } + + // Read the fret buttons (Green, Red, Yellow, Blue, Orange) + boolean green = guitar.fretGreen(); + + Serial.print("The green fret button is "); + if (green == 1) { + Serial.println("pressed"); + } + else if (green == 0) { + Serial.println("released"); + } + + // Read the touchbar (if the controller has one) + if (guitar.supportsTouchbar()) { + + // Touchbar raw value (0-31) + uint8_t touchbarValue = guitar.touchbar(); + + Serial.print("The touchbar is at "); + Serial.println(touchbarValue); + + // Touchbar zones (Green, Red, Yellow, Blue, Orange) + boolean touchGreen = guitar.touchGreen(); + + Serial.print("The green touch zone is "); + if (touchGreen == 1) { + Serial.println("pressed"); + } + else if (touchGreen == 0) { + Serial.println("not pressed"); + } + } + + // Read the whammy bar (0-31) + uint8_t whammy = guitar.whammyBar(); + + Serial.print("The whammy bar's position is "); + Serial.println(whammy); + + // Read the joystick axis (0-63 XY) + int joyVal = guitar.joyX(); + + Serial.print("The joystick's X axis is at "); + Serial.println(joyVal); + + // Read a button (Plus/Minus) + boolean plusButton = guitar.buttonPlus(); + + Serial.print("The plus button is "); + if (plusButton == 1) { + Serial.println("pressed"); + } + else if (plusButton == 0) { + Serial.println("released"); + } + + // Print all the values! + guitar.printDebug(); + } +} diff --git a/keywords.txt b/keywords.txt index 775dd6d..62e8544 100644 --- a/keywords.txt +++ b/keywords.txt @@ -15,6 +15,7 @@ ExtensionController KEYWORD1 # Controller Types Nunchuk KEYWORD1 ClassicController KEYWORD1 +GuitarController KEYWORD1 # Enumerations NXC_ControllerType KEYWORD1 @@ -81,6 +82,34 @@ buttonPlus KEYWORD2 buttonMinus KEYWORD2 buttonHome KEYWORD2 +## Guitar Controller +joyX KEYWORD2 +joyY KEYWORD2 + +strum KEYWORD2 +strumUp KEYWORD2 +strumDown KEYWORD2 + +fretGreen KEYWORD2 +fretRed KEYWORD2 +fretYellow KEYWORD2 +fretBlue KEYWORD2 +fretOrange KEYWORD2 + +whammyBar KEYWORD2 + +touchbar KEYWORD2 +touchGreen KEYWORD2 +touchRed KEYWORD2 +touchYellow KEYWORD2 +touchBlue KEYWORD2 +touchOrange KEYWORD2 + +buttonPlus KEYWORD2 +buttonMinus KEYWORD2 + +supportsTouchbar KEYWORD2 + ####################################### # Instances (KEYWORD2) ####################################### @@ -94,3 +123,4 @@ NXC_NoController LITERAL1 NXC_UnknownController LITERAL1 NXC_Nunchuk LITERAL1 NXC_ClassicController LITERAL1 +NXC_GuitarController LITERAL1 diff --git a/library.properties b/library.properties index e8841e5..a51c16e 100644 --- a/library.properties +++ b/library.properties @@ -3,7 +3,7 @@ version=0.0.2 author=David Madison maintainer=David Madison sentence=Library for talking to Nintendo extension controllers over I2C. -paragraph=Supports the Wii Nunchuk and Wii Classic Controller. +paragraph=Supports the Wii Nunchuk, Wii Classic Controller, and Guitar Hero guitar. category=Communication url=https://github.com/dmadison/NintendoExtensionCtrl architectures=* diff --git a/src/ExtensionController.cpp b/src/ExtensionController.cpp index 17de932..3356331 100644 --- a/src/ExtensionController.cpp +++ b/src/ExtensionController.cpp @@ -82,6 +82,13 @@ NXC_ControllerType ExtensionController::identifyController() { return NXC_ClassicController; } + // Guitar Controller: 0x0000, 0xA420, 0x0103 + else if (idData[0] == 0x00 && idData[1] == 0x00 + && idData[2] == 0xA4 && idData[3] == 0x20 + && idData[4] == 0x01 && idData[5] == 0x03) { + return NXC_GuitarController; + } + return NXC_UnknownController; // No matches } diff --git a/src/ExtensionController.h b/src/ExtensionController.h index 4e40d91..66ba280 100644 --- a/src/ExtensionController.h +++ b/src/ExtensionController.h @@ -31,6 +31,7 @@ enum NXC_ControllerType { NXC_UnknownController, NXC_Nunchuk, NXC_ClassicController, + NXC_GuitarController, }; class ExtensionController { diff --git a/src/GuitarController.cpp b/src/GuitarController.cpp new file mode 100644 index 0000000..649eb8a --- /dev/null +++ b/src/GuitarController.cpp @@ -0,0 +1,168 @@ +/* +* Project Nintendo Extension Controller Library +* @author David Madison +* @link github.com/dmadison/NintendoExtensionCtrl +* @license LGPLv3 - Copyright (c) 2018 David Madison +* +* This file is part of the Nintendo Extension Controller Library. +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program 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 Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with this program. If not, see . +*/ + +#include "GuitarController.h" + +GuitarController::GuitarController() : ExtensionController(NXC_GuitarController, 6) {} + +uint8_t GuitarController::joyX() { + return controlData[0] & 0x3F; +} + +uint8_t GuitarController::joyY() { + return controlData[1] & 0x3F; +} + +boolean GuitarController::strum() { + return strumUp() | strumDown(); +} + +boolean GuitarController::strumUp() { + return extractBit(5, 0); +} + +boolean GuitarController::strumDown() { + return extractBit(4, 6); +} + +boolean GuitarController::fretGreen() { + return extractBit(5, 4); +} + +boolean GuitarController::fretRed() { + return extractBit(5, 6); +} + +boolean GuitarController::fretYellow() { + return extractBit(5, 3); +} + +boolean GuitarController::fretBlue() { + return extractBit(5, 5); +} + +boolean GuitarController::fretOrange() { + return extractBit(5, 7); +} + +uint8_t GuitarController::whammyBar() { + return controlData[3] & 0x1F; +} + +uint8_t GuitarController::touchbar() { + return controlData[2] & 0x1F; +} + +boolean GuitarController::touchGreen() { + return touchbar() != 0 && touchbar() <= 7; +} + +boolean GuitarController::touchRed() { + return touchbar() >= 7 && touchbar() <= 13; +} + +boolean GuitarController::touchYellow() { + return touchbar() >= 12 && touchbar() <= 21 + && touchbar() != 15; // The "not touched" value +} + +boolean GuitarController::touchBlue() { + return touchbar() >= 20 && touchbar() <= 26; +} + +boolean GuitarController::touchOrange() { + return touchbar() >= 26; +} + +boolean GuitarController::buttonPlus() { + return extractBit(4, 2); +} + +boolean GuitarController::buttonMinus() { + return extractBit(4, 4); +} + +boolean GuitarController::supportsTouchbar() { + if (touchbarData) { + return true; + } + else if (touchbar() > 0) { + touchbarData = true; + } + return false; +} + +void GuitarController::printDebug(Stream& stream) { + const char fillCharacter = '_'; + + char buffer[20]; + + stream.print("Guitar: "); + + // Strum + Fret Buttons + char strumPrint = fillCharacter; + if (strumUp()) { + strumPrint = '^'; + } + else if (strumDown()) { // Mutually exclusive + strumPrint = 'v'; + } + + char greenPrint = fretGreen() ? 'G' : fillCharacter; + char redPrint = fretRed() ? 'R' : fillCharacter; + char yellowPrint = fretYellow() ? 'Y' : fillCharacter; + char bluePrint = fretBlue() ? 'B' : fillCharacter; + char orangePrint = fretOrange() ? 'O' : fillCharacter; + + sprintf(buffer, + "%c | %c%c%c%c%c | ", + strumPrint, + greenPrint, redPrint, yellowPrint, bluePrint, orangePrint); + stream.print(buffer); + buffer[0] = 0; + + // Touchbar, if World Controller + if (supportsTouchbar()) { + greenPrint = touchGreen() ? 'G' : fillCharacter; + redPrint = touchRed() ? 'R' : fillCharacter; + yellowPrint = touchYellow() ? 'Y' : fillCharacter; + bluePrint = touchBlue() ? 'B' : fillCharacter; + orangePrint = touchOrange() ? 'O' : fillCharacter; + + sprintf(buffer, + "Touch:%2u - %c%c%c%c%c | ", + touchbar(), + greenPrint, redPrint, yellowPrint, bluePrint, orangePrint); + stream.print(buffer); + buffer[0] = 0; + } + + // Joy + Plus/Minus + char plusPrint = buttonPlus() ? '+' : fillCharacter; + char minusPrint = buttonMinus() ? '-' : fillCharacter; + + sprintf(buffer, + "%c%c | Joy:(%2u, %2u)", + plusPrint, minusPrint, + joyX(), joyY()); + stream.println(buffer); +} diff --git a/src/GuitarController.h b/src/GuitarController.h new file mode 100644 index 0000000..00953a8 --- /dev/null +++ b/src/GuitarController.h @@ -0,0 +1,65 @@ +/* +* Project Nintendo Extension Controller Library +* @author David Madison +* @link github.com/dmadison/NintendoExtensionCtrl +* @license LGPLv3 - Copyright (c) 2018 David Madison +* +* This file is part of the Nintendo Extension Controller Library. +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program 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 Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with this program. If not, see . +*/ + +#ifndef GuitarController_h +#define GuitarController_h + +#include "ExtensionController.h" + +class GuitarController : public ExtensionController { +public: + GuitarController(); + + uint8_t joyX(); // 6 bits, 0-63 + uint8_t joyY(); + + boolean strum(); + boolean strumUp(); + boolean strumDown(); + + boolean fretGreen(); + boolean fretRed(); + boolean fretYellow(); + boolean fretBlue(); + boolean fretOrange(); + + uint8_t whammyBar(); // 5 bits, 0-31 + + uint8_t touchbar(); // 5 bits, 0-31 + boolean touchGreen(); + boolean touchRed(); + boolean touchYellow(); + boolean touchBlue(); + boolean touchOrange(); + + boolean buttonPlus(); + boolean buttonMinus(); + + void printDebug(Stream& stream=Serial); + + boolean supportsTouchbar(); + +private: + boolean touchbarData = false; // Flag for touchbar data found +}; + +#endif diff --git a/src/NintendoExtensionCtrl.h b/src/NintendoExtensionCtrl.h index 05d2b86..1bfcbb2 100644 --- a/src/NintendoExtensionCtrl.h +++ b/src/NintendoExtensionCtrl.h @@ -29,6 +29,7 @@ // Controller Types #include "Nunchuk.h" #include "ClassicController.h" +#include "GuitarController.h" #endif