diff --git a/README.md b/README.md index 1d1f864..caf9845 100644 --- a/README.md +++ b/README.md @@ -1,15 +1,41 @@ # Nintendo Extension Controller Library -This is an Arduino library for talking to Nintendo extension controllers over I²C. +This is an Arduino library that makes it easy to read data from Nintendo extension controllers such as the Wii Nunchuk and Classic Controller. + +"Extension controller" is the name given to devices that *extend* the functionality of the [Wiimote](https://en.wikipedia.org/wiki/Wii_Remote), plugging into the expansion port at the bottom of the device. While originally designed for Wiimote accessories, the port and communication protocol is now also being used for the controllers of Nintendo's new line of "Mini" consoles. + +## Getting Started + +![ClassicController Example in IDE](/extras/NXCtrl_ClassicExample.png) + +### Make Your Connections + +Before anything else, you need to connect your controller to the Arduino. The easist way to do this is with a breakout board, which slides in to the extension controller plug and doesn't require dismantaling your controller. I recommend the [Nunchucky](https://www.adafruit.com/product/345) breakout, which is inexpensive and available at Adafruit. + +Controllers require 3.3V power. If you don't have 3.3V power available on your board, you will need to use an external regulator. Using 5V power can result in erratic data and risks damaging your controller. For this reason it's recommended *not* to use so-called "inline" adapters that attach to the Arduino Uno's analog pins. + +The "data" and "clock" lines on the breakout go to the SDA and SCL pins (respectively) on the microcontroller. For the Arduino Uno, these are pins A4 and A5. If you're not using an Uno, look [here](https://www.arduino.cc/en/reference/wire) to find the I²C pins for your Arduino board. + +### Run an Example + +After [installing the library](https://www.arduino.cc/en/guide/libraries), load an example by going to `File -> Examples -> NintendoExtensionCtrl` in the Arduino IDE and selecting an example specific to your controller. I recommend the `DebugPrint` examples to start, as they give you a nice overview of what data is available for your controller. + +Plug in your controller, upload the example to your board, and have fun! ## Supported Controllers -* Wii Nunchuk -* Wii Classic Controller + +### Wii +* Nunchuk +* Classic Controller * Guitar Hero Guitar * Guitar Hero World Tour Drums * DJ Hero Turntable + +### Mini Console * NES Mini Controller * SNES Mini Controller +Currently the library supports any extension controller using unencrypted communication and data reporting mode [0x37 (6 byte request)](http://wiibrew.org/wiki/Wiimote#0x37:_Core_Buttons_and_Accelerometer_with_10_IR_bytes_and_6_Extension_Bytes). If you'd like to add support for another controller, I've written [a short guide](extras/AddingControllers.md) that should be helpful. + ## 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/Any/DebugPrint/DebugPrint.ino b/examples/Any/DebugPrint/DebugPrint.ino index 4da3dff..c03c9b2 100644 --- a/examples/Any/DebugPrint/DebugPrint.ino +++ b/examples/Any/DebugPrint/DebugPrint.ino @@ -1,3 +1,29 @@ +/* +* 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 . +* +* Example: DebugPrint +* Description: Connect to an extension controller and continuously print +* the raw control data over serial. +*/ + #include ExtensionController controller; diff --git a/examples/Any/IdentifyController/IdentifyController.ino b/examples/Any/IdentifyController/IdentifyController.ino index e351fd1..d9b8b06 100644 --- a/examples/Any/IdentifyController/IdentifyController.ino +++ b/examples/Any/IdentifyController/IdentifyController.ino @@ -1,3 +1,29 @@ +/* +* 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 . +* +* Example: IdentifyController +* Description: Attempt to connect to an extension controller, then print +* out the matching ID and ID data bytes. +*/ + #include ExtensionController controller; diff --git a/examples/Any/MultipleBus/MultipleBus.ino b/examples/Any/MultipleBus/MultipleBus.ino index 7e5d986..69e6575 100644 --- a/examples/Any/MultipleBus/MultipleBus.ino +++ b/examples/Any/MultipleBus/MultipleBus.ino @@ -1,6 +1,35 @@ +/* +* 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 . +* +* Example: MultipleBus +* Description: Communicate with two extension controllers, each on their own +* I2C bus (e.g. Wire and Wire1). Requires a microcontroller +* with two I2C buses (e.g. Arduino Due or Teensy). +* +* This example uses Nunchuks, but this process works the same +* with any controller in the library. +*/ + #include -// Requries a microcontroller with two I2C buses, e.g. Arduino Due or Teensy Nunchuk nchuk1(Wire); // Controller on bus #1 Nunchuk nchuk2(Wire1); // Controller on bus #2 diff --git a/examples/Any/MultipleTypes/MultipleTypes.ino b/examples/Any/MultipleTypes/MultipleTypes.ino index 47b2611..bcec11d 100644 --- a/examples/Any/MultipleTypes/MultipleTypes.ino +++ b/examples/Any/MultipleTypes/MultipleTypes.ino @@ -1,3 +1,29 @@ +/* +* 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 . +* +* Example: MultipleTypes +* Description: Connect to a controller and then switch between two controller +* types depending on the identity of the connected controller. +*/ + #include ExtensionController controller; // Port for communicating with extension controllers diff --git a/examples/Any/SpeedTest/SpeedTest.ino b/examples/Any/SpeedTest/SpeedTest.ino index 43b1c7d..e24e926 100644 --- a/examples/Any/SpeedTest/SpeedTest.ino +++ b/examples/Any/SpeedTest/SpeedTest.ino @@ -1,3 +1,29 @@ +/* +* 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 . +* +* Example: SpeedTest +* Description: Connect to an extension controller and record the max +* number of updates per second. +*/ + #include ExtensionController controller; // Generic controller, 6 bytes @@ -22,7 +48,7 @@ void loop() { long millisStart = millis(); while (millis() - millisStart <= TestDuration && validData) { - validData = controller.update(); + validData = controller.update(); // Update and check if sucessful numUpdates++; } diff --git a/examples/Classic Controller/Classic_DebugPrint/Classic_DebugPrint.ino b/examples/Classic Controller/Classic_DebugPrint/Classic_DebugPrint.ino index b87c0a4..284d5aa 100644 --- a/examples/Classic Controller/Classic_DebugPrint/Classic_DebugPrint.ino +++ b/examples/Classic Controller/Classic_DebugPrint/Classic_DebugPrint.ino @@ -1,3 +1,30 @@ +/* +* 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 . +* +* Example: Classic_DebugPrint +* Description: Connect to a Classic Controller and continuously print +* its control data, nicely formatted for debugging, over +* the serial bus. +*/ + #include ClassicController classic; diff --git a/examples/Classic Controller/Classic_Demo/Classic_Demo.ino b/examples/Classic Controller/Classic_Demo/Classic_Demo.ino index a9e890a..754661c 100644 --- a/examples/Classic Controller/Classic_Demo/Classic_Demo.ino +++ b/examples/Classic Controller/Classic_Demo/Classic_Demo.ino @@ -1,3 +1,29 @@ +/* +* 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 . +* +* Example: Classic_Demo +* Description: Connect to a Classic Controller and demonstrate all of +* the avaiable control data functions. +*/ + #include ClassicController classic; diff --git a/examples/DJ/DJ_DebugPrint/DJ_DebugPrint.ino b/examples/DJ/DJ_DebugPrint/DJ_DebugPrint.ino index 65affc3..0365a06 100644 --- a/examples/DJ/DJ_DebugPrint/DJ_DebugPrint.ino +++ b/examples/DJ/DJ_DebugPrint/DJ_DebugPrint.ino @@ -1,3 +1,30 @@ +/* +* 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 . +* +* Example: DJ_DebugPrint +* Description: Connect to a DJ Hero turntable and continuously print +* its control data, nicely formatted for debugging, over +* the serial bus. +*/ + #include DJTurntableController dj; diff --git a/examples/DJ/DJ_Demo/DJ_Demo.ino b/examples/DJ/DJ_Demo/DJ_Demo.ino index 848b503..eef761d 100644 --- a/examples/DJ/DJ_Demo/DJ_Demo.ino +++ b/examples/DJ/DJ_Demo/DJ_Demo.ino @@ -1,3 +1,29 @@ +/* +* 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 . +* +* Example: DJ_Demo +* Description: Connect to a DJ Hero turntable and demonstrate all of +* the avaiable control data functions. +*/ + #include DJTurntableController dj; diff --git a/examples/DJ/DJ_EffectDial/DJ_EffectDial.ino b/examples/DJ/DJ_EffectDial/DJ_EffectDial.ino index fecc626..a517ff0 100644 --- a/examples/DJ/DJ_EffectDial/DJ_EffectDial.ino +++ b/examples/DJ/DJ_EffectDial/DJ_EffectDial.ino @@ -1,3 +1,30 @@ +/* +* 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 . +* +* Example: DJ_EffectDial +* Description: Connect to a DJ Hero turntable and show how the +* EffectRollover class works to track the change in +* the effect dial, even between rollovers. +*/ + #include DJTurntableController dj; diff --git a/examples/Drums/Drums_DebugPrint/Drums_DebugPrint.ino b/examples/Drums/Drums_DebugPrint/Drums_DebugPrint.ino index 31ff6be..cc8ee80 100644 --- a/examples/Drums/Drums_DebugPrint/Drums_DebugPrint.ino +++ b/examples/Drums/Drums_DebugPrint/Drums_DebugPrint.ino @@ -1,3 +1,30 @@ +/* +* 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 . +* +* Example: Drums_DebugPrint +* Description: Connect to a Guitar Hero drum set and continuously print +* its control data, nicely formatted for debugging, over +* the serial bus. +*/ + #include DrumController drums; diff --git a/examples/Drums/Drums_Demo/Drums_Demo.ino b/examples/Drums/Drums_Demo/Drums_Demo.ino index 445ca81..ad958f2 100644 --- a/examples/Drums/Drums_Demo/Drums_Demo.ino +++ b/examples/Drums/Drums_Demo/Drums_Demo.ino @@ -1,3 +1,29 @@ +/* +* 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 . +* +* Example: Drums_Demo +* Description: Connect to a Guitar Hero drum set and demonstrate all of +* the avaiable control data functions. +*/ + #include DrumController drums; diff --git a/examples/Guitar/Guitar_DebugPrint/Guitar_DebugPrint.ino b/examples/Guitar/Guitar_DebugPrint/Guitar_DebugPrint.ino index fa0294a..25115de 100644 --- a/examples/Guitar/Guitar_DebugPrint/Guitar_DebugPrint.ino +++ b/examples/Guitar/Guitar_DebugPrint/Guitar_DebugPrint.ino @@ -1,3 +1,30 @@ +/* +* 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 . +* +* Example: Guitar_DebugPrint +* Description: Connect to a Guitar Hero controller and continuously print +* its control data, nicely formatted for debugging, over +* the serial bus. +*/ + #include GuitarController guitar; diff --git a/examples/Guitar/Guitar_Demo/Guitar_Demo.ino b/examples/Guitar/Guitar_Demo/Guitar_Demo.ino index f70d088..571fb6c 100644 --- a/examples/Guitar/Guitar_Demo/Guitar_Demo.ino +++ b/examples/Guitar/Guitar_Demo/Guitar_Demo.ino @@ -1,3 +1,29 @@ +/* +* 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 . +* +* Example: Guitar_Demo +* Description: Connect to a Guitar Hero controller and demonstrate all +* of the avaiable control data functions. +*/ + #include GuitarController guitar; diff --git a/examples/NES Mini/NES_DebugPrint/NES_DebugPrint.ino b/examples/NES Mini/NES_DebugPrint/NES_DebugPrint.ino index 9ae305f..5f699ff 100644 --- a/examples/NES Mini/NES_DebugPrint/NES_DebugPrint.ino +++ b/examples/NES Mini/NES_DebugPrint/NES_DebugPrint.ino @@ -1,3 +1,30 @@ +/* +* 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 . +* +* Example: NES_DebugPrint +* Description: Connect to an NES Mini controller and continuously print +* its control data, nicely formatted for debugging, over +* the serial bus. +*/ + #include NESMiniController nes; diff --git a/examples/NES Mini/NES_Demo/NES_Demo.ino b/examples/NES Mini/NES_Demo/NES_Demo.ino index 2739a40..b92c8b4 100644 --- a/examples/NES Mini/NES_Demo/NES_Demo.ino +++ b/examples/NES Mini/NES_Demo/NES_Demo.ino @@ -1,3 +1,29 @@ +/* +* 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 . +* +* Example: NES_Demo +* Description: Connect to an NES Mini controller and demonstrate all of +* the avaiable control data functions. +*/ + #include NESMiniController nes; diff --git a/examples/Nunchuk/Nunchuk_DebugPrint/Nunchuk_DebugPrint.ino b/examples/Nunchuk/Nunchuk_DebugPrint/Nunchuk_DebugPrint.ino index 444ebcf..f6c2093 100644 --- a/examples/Nunchuk/Nunchuk_DebugPrint/Nunchuk_DebugPrint.ino +++ b/examples/Nunchuk/Nunchuk_DebugPrint/Nunchuk_DebugPrint.ino @@ -1,3 +1,29 @@ +/* +* 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 . +* +* Example: Nunchuk_DebugPrint +* Description: Connect to a Nunchuk and continuously print its control +* data, nicely formatted for debugging, over the serial bus. +*/ + #include Nunchuk nchuk; diff --git a/examples/Nunchuk/Nunchuk_Demo/Nunchuk_Demo.ino b/examples/Nunchuk/Nunchuk_Demo/Nunchuk_Demo.ino index 3a4f01c..9db7d30 100644 --- a/examples/Nunchuk/Nunchuk_Demo/Nunchuk_Demo.ino +++ b/examples/Nunchuk/Nunchuk_Demo/Nunchuk_Demo.ino @@ -1,3 +1,29 @@ +/* +* 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 . +* +* Example: Nunchuk_Demo +* Description: Connect to a Nunchuk and demonstrate all of the avaiable +* control data functions. +*/ + #include Nunchuk nchuk; diff --git a/examples/SNES Mini/SNES_DebugPrint/SNES_DebugPrint.ino b/examples/SNES Mini/SNES_DebugPrint/SNES_DebugPrint.ino index 83c5437..78aefe4 100644 --- a/examples/SNES Mini/SNES_DebugPrint/SNES_DebugPrint.ino +++ b/examples/SNES Mini/SNES_DebugPrint/SNES_DebugPrint.ino @@ -1,3 +1,30 @@ +/* +* 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 . +* +* Example: SNES_DebugPrint +* Description: Connect to an SNES Mini controller and continuously print +* its control data, nicely formatted for debugging, over +* the serial bus. +*/ + #include SNESMiniController snes; diff --git a/examples/SNES Mini/SNES_Demo/SNES_Demo.ino b/examples/SNES Mini/SNES_Demo/SNES_Demo.ino index 83be43a..4af5a3b 100644 --- a/examples/SNES Mini/SNES_Demo/SNES_Demo.ino +++ b/examples/SNES Mini/SNES_Demo/SNES_Demo.ino @@ -1,3 +1,29 @@ +/* +* 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 . +* +* Example: SNES_Demo +* Description: Connect to an SNES Mini controller and demonstrate all of +* the avaiable control data functions. +*/ + #include NESMiniController snes; diff --git a/extras/AddingControllers.md b/extras/AddingControllers.md new file mode 100644 index 0000000..1f35383 --- /dev/null +++ b/extras/AddingControllers.md @@ -0,0 +1,184 @@ +# Adding a Controller to the NintendoExtensionCtrl Library +If you want to use an extension controller that is not currently supported by this library, you'll have to add it yourself. But fear not! This guide should walk you through how to quickly and easily add a new controller. + +## Step #1: Creating The Class Framework +The first step in adding support for your controller is building it a class. The header (.h) and implementation (.cpp) files live within the `controllers` folder in the source directory. You'll need to create both of these files with the name of your controller. + +Controller classes live inside the library namespace and inherit from the `ControlDataMap` class, which links back to the extension controller communication class and defines how control data is manipulated. This includes combining multi-byte data and extracting bits that correspond to button presses. To use this you'll need to include the "ExtensionController.h" header, which is in the `internal` source directory. + +The class name itself is the "Data-Only" version of the class, which only manipulates the control data and doesn't include any communication methods - thus it has a `_Data` suffix. Here is what the start of the `ClassicController_Data` class looks like: + +```C++ +#include "internal/ExtensionController.h" + +namespace NintendoExtensionCtrl { + class ClassicController_Data : protected ControlDataMap { + public: + using ControlDataMap::ControlDataMap; +``` + +## Step #2: Building Your Data Maps +The next step is to add the data maps for your controller. These define where the data for each control input lies within in the data array. Currently (v0.5.2), all controllers use the Wiimote 0x37 data reporting mode, returning 6 bytes of control data starting at offset 0x00. If your controller requires sending more than 6 bytes of data to function, you'll need to modify the `ExtensionController` class to increase the size of the control data array. + +Each map represents the size and position for all of the data of a control surface (button, joystick, etc.). The library has three data types for this, each with a different purpose: + +### CtrlIndex + +The simplest data format. This takes one value that represents the index in the array for your control data. Passing this to `getControlData` will return the full byte of data. + +```C++ +CtrlIndex JoyX = 1; // Array[1] is the data for JoyX +``` + +### ByteMap +A `ByteMap` is a struct that takes four input values: + +1. The index of the data in the control data array +2. The size of the data, in bits +3. The starting position of the data, in bits from the right +4. The offset, or amount of bits to shift the final data *to* the right + +From the `size` and `position` values, the constructor will generate a bitmask to apply to the control data, saving cycles at runtime. Note that the 'offset' value cannot be negative. If you need to shift the data left you must do it yourself. + +```C++ +// Data is at Array[1] +// 5 bits wide, starting 3 bits from the right (0xF8 mask) +// Shift the final data 2 bits to the right +ByteMap JoyY = ByteMap(1, 5, 3, 2); +``` + +If the data is spread out over multiple bytes, just use an array of `ByteMap` structs: + +```C++ +ByteMap TriggerL[2] = { ByteMap(2, 2, 5, 2), ByteMap(3, 3, 5, 5) }; +``` + +### BitMap +A `BitMap` is a simpler struct that takes two input values: + +1. The index of the data in the control data array +2. The position of the bit, in bits from the right + +The resulting bit from the control data is extracted and inverted, as extension controller buttons are `0` if pressed. + +```C++ +BitMap ButtonA = { 5, 4 }; +``` +Full definitions of these data types can be found in the [`NXC_DataMaps.h`](../src/internal/NXC_DataMaps.h) file. + +--- + +For each control input on your controller, you will need to reverse-engineer the data positions and format. You can use the `printDebugRaw` function of the `ExtensionController` class to help with this. I'd also recommend checking out the information available at [WiiBrew](http://wiibrew.org/wiki/Wiimote/Extension_Controllers), which was tremendously helpful to me in putting the rest of the library together. + +Once you have your mappings you'll need to add them to the controller class. Within the class definition, create a `Maps` struct. This will be filled with the `constexpr static` data for each control surface mapping. It's important to use the `constexpr static` keywords so that these are evaluated as expressions and no memory is allocated. + +Here is a sampling of some of the mappings for the Classic Controller: + +```C++ +struct Maps { + constexpr static ByteMap LeftJoyX = ByteMap(0, 6, 0, 0); + constexpr static ByteMap LeftJoyY = ByteMap(1, 6, 0, 0); + + constexpr static ByteMap RightJoyX[3] = { ByteMap(0, 2, 6, 3), ByteMap(1, 2, 6, 5), ByteMap(2, 1, 7, 7) }; + constexpr static ByteMap RightJoyY = ByteMap(2, 5, 0, 0); + + constexpr static BitMap ButtonA = { 5, 4 }; + constexpr static BitMap ButtonB = { 5, 6 }; +}; +``` + +## Step #3: Add Your "Get" Functions +With your control maps in place, you'll now need to add your 'get' functions. These functions are public, and will return their respective control data to the user. + +Since the library is based around "getting" and working with this control data, I elected early-on to ditch the "get" prefix for simplicity. All functions are just the name of the control input itself. Here are the Classic Controller function declarations for the above maps: + +```C++ +uint8_t leftJoyX() const; // 6 bits, 0-63 +uint8_t leftJoyY() const; + +uint8_t rightJoyX() const; // 5 bits, 0-31 +uint8_t rightJoyY() const; + +boolean buttonA() const; +boolean buttonB() const; +``` + +Since you've already spent the time creating the data maps, the function definitions should be straight-forward. Either call `getControlBit()` passing a `BitMap`, or call `getControlData()` passing your `CtrlIndex` or `ByteMap` value(s). Here are the function definitions for the above controls: + +```C++ +uint8_t ClassicController_Data::leftJoyX() const { + return getControlData(Maps::LeftJoyX); +} + +uint8_t ClassicController_Data::leftJoyY() const { + return getControlData(Maps::LeftJoyY); +} + +uint8_t ClassicController_Data::rightJoyX() const { + return getControlData(Maps::RightJoyX); +} + +uint8_t ClassicController_Data::rightJoyY() const { + return getControlData(Maps::RightJoyY); +} + +boolean ClassicController_Data::buttonA() const { + return getControlBit(Maps::ButtonA); +} + +boolean ClassicController_Data::buttonB() const { + return getControlBit(Maps::ButtonB); +} +``` + +***Note:** I decided to use two different function names for generic control data and bits, just because the bits are automatically inverted. I might decide to change this in the future, but for now it seems to work fine.* + +## Step #4: Add a `printDebug` Function +This should be a fun step. Create a `printDebug` function that prints out the values for your controller! Since this should only *ever* be called when debugging, I say go crazy with the formatting. Most of the other controllers use `sprintf` to make things easy, in spite of the extra overhead. + +Here's how the Classic Controller debug line looks: +``` +<^v> | +H- | ABXY L:(32, 32) R:(16, 16) | LT:31X RT:31X Z:LR +``` +This includes all of the possible control data: the directional pad, +/- and home buttons, ABXY buttons, left and right joysticks, left and right triggers, and ZL/ZR buttons. You can check [the code](../src/controllers/ClassicController.cpp#L119) to see how it was put together. + +## Step #5: Add Your Controller's Identity +Now that your controller definition is nearly done, it's time to add its identity to the list of available controllers! + +Open up the [`NXC_Identity.h`](../src/internal/NXC_Identity.h) file and add your controller name to the `ExtensionType` enumeration. Then, modify the `identifyController` function so that it will return your controller's ID if the identity bytes match. You can run the [`IdentifyController`](../examples/Any/IdentifyController/IdentifyController.ino) example to fetch the string of ID bytes. + +You will also need to edit the switch statement in the `IdentifyControllers` example to add your controller to the 'switch' statement. + +## Step #6: Create the Combined Class +The last step to get your controller working is to create a combined class that inherits from the extension controller communication class and your newly created data class. This will be accessible by the user, and is how the controller's class will be interfaced with. Thankfully I've already built something to make this easy. Just copy this line, replacing all instances of `YourController` with your controller's name: + +```C++ +typedef NintendoExtensionCtrl::BuildControllerClass + + YourController; +``` + +Be sure to place this *outside* of the namespace, in the header file. See other controller definitions for reference. + +## Step #7: Add Examples +What use is a good controller definition if no one knows how to use it? You should add some examples showing off how the controller works. I usually like to add two: + +* `DebugPrint`, which is barebones and only includes connection and the `printDebug` function. This is useful for testing that your controller and all of your data maps are functioning properly. +* `Demo`, which is longer and includes references to all of the different 'get' function types. This should explain to the user how to access your controller's data, including ranges and any quirks. + +## Step #8: Library Housekeeping +At this point your controller is up and running, and everyone should know how to use it! There's just a little bit of housekeeping left to do to make the controller fit in nicely with the others in the library. + +### Update the Keyword Map +The library includes a file called [`keywords.txt`](../keywords.txt), which includes the names of classes, functions, datatypes, and other useful keywords worth highlighting in the Arduino IDE. Please update this with the public version of your class name and any unique functions. See the [Arduino Library Specification](https://github.com/arduino/arduino/wiki/arduino-ide-1.5:-library-specification) for more information. + +### Update Supported Controllers +Add your controller to the list of supported controllers! This must be done in **two** places: +* [README.md](../README.md) +* [library.properties](../library.properties) + +This will let others know that the controller is supported and is available to use. + +--- + +That's it! Once you've completed these steps and tested your controller, create a pull request and add your controller to the library! diff --git a/extras/NXCtrl_ClassicExample.png b/extras/NXCtrl_ClassicExample.png new file mode 100644 index 0000000..6f55ee7 Binary files /dev/null and b/extras/NXCtrl_ClassicExample.png differ