Browse Source

nunchuck: Initial implementation

This was tested with the Grove Nunchuck adapter.

Signed-off-by: Jon Trulson <jtrulson@ics.com>
Signed-off-by: Zion Orent <zorent@ics.com>
Signed-off-by: John Van Drasek <john.r.van.drasek@intel.com>
Jon Trulson 10 years ago
parent
commit
1f3d074261

+ 3
- 0
examples/CMakeLists.txt View File

@@ -84,6 +84,7 @@ add_executable (mma7660-example mma7660.cxx)
84 84
 add_executable (cjq4435-example cjq4435.cxx)
85 85
 add_executable (adxl335-example adxl335.cxx)
86 86
 add_executable (hmtrp-example hmtrp.cxx)
87
+add_executable (nunchuck-example nunchuck.cxx)
87 88
 
88 89
 include_directories (${PROJECT_SOURCE_DIR}/src/hmc5883l)
89 90
 include_directories (${PROJECT_SOURCE_DIR}/src/grove)
@@ -153,6 +154,7 @@ include_directories (${PROJECT_SOURCE_DIR}/src/mma7660)
153 154
 include_directories (${PROJECT_SOURCE_DIR}/src/cjq4435)
154 155
 include_directories (${PROJECT_SOURCE_DIR}/src/adxl335)
155 156
 include_directories (${PROJECT_SOURCE_DIR}/src/hmtrp)
157
+include_directories (${PROJECT_SOURCE_DIR}/src/nunchuck)
156 158
 
157 159
 target_link_libraries (hmc5883l-example hmc5883l ${CMAKE_THREAD_LIBS_INIT})
158 160
 target_link_libraries (groveled-example grove ${CMAKE_THREAD_LIBS_INIT})
@@ -240,3 +242,4 @@ target_link_libraries (mma7660-example mma7660 ${CMAKE_THREAD_LIBS_INIT})
240 242
 target_link_libraries (cjq4435-example cjq4435 ${CMAKE_THREAD_LIBS_INIT})
241 243
 target_link_libraries (adxl335-example adxl335 ${CMAKE_THREAD_LIBS_INIT})
242 244
 target_link_libraries (hmtrp-example hmtrp ${CMAKE_THREAD_LIBS_INIT})
245
+target_link_libraries (nunchuck-example nunchuck ${CMAKE_THREAD_LIBS_INIT})

+ 66
- 0
examples/javascript/nunchuck.js View File

@@ -0,0 +1,66 @@
1
+/*jslint node:true, vars:true, bitwise:true, unparam:true */
2
+/*jshint unused:true */
3
+
4
+/*
5
+* Author: Zion Orent <zorent@ics.com>
6
+* Copyright (c) 2015 Intel Corporation.
7
+*
8
+* Permission is hereby granted, free of charge, to any person obtaining
9
+* a copy of this software and associated documentation files (the
10
+* "Software"), to deal in the Software without restriction, including
11
+* without limitation the rights to use, copy, modify, merge, publish,
12
+* distribute, sublicense, and/or sell copies of the Software, and to
13
+* permit persons to whom the Software is furnished to do so, subject to
14
+* the following conditions:
15
+*
16
+* The above copyright notice and this permission notice shall be
17
+* included in all copies or substantial portions of the Software.
18
+*
19
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20
+* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
22
+* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
23
+* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
24
+* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
25
+* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26
+*/
27
+
28
+var nunchuck_lib = require('jsupm_nunchuck');
29
+
30
+// Instantiate a nunchuck controller bus 0
31
+var nunchuck_obj = new nunchuck_lib.NUNCHUCK(0);
32
+
33
+// always do this first
34
+console.log("Initializing... ");
35
+if (!nunchuck_obj.init())
36
+{
37
+	console.log("nunchuck->init() failed.");
38
+	process.exit(0);
39
+}
40
+
41
+setInterval(function()
42
+{
43
+	nunchuck_obj.update();
44
+
45
+	var outputStr = "stickX: " + nunchuck_obj.stickX +
46
+	", stickY: " + nunchuck_obj.stickY;
47
+	console.log(outputStr);
48
+	outputStr = "accelX: " + nunchuck_obj.accelX +
49
+	", accelY: " + nunchuck_obj.accelY +
50
+	", accelZ: " + nunchuck_obj.accelZ;
51
+	console.log(outputStr);
52
+
53
+	outputStr = "button C: " +
54
+	((nunchuck_obj.buttonC) ? "pressed" : "not pressed");
55
+	console.log(outputStr);
56
+	outputStr = "button Z: " +
57
+	((nunchuck_obj.buttonZ) ? "pressed" : "not pressed");
58
+	console.log(outputStr);
59
+}, 100);
60
+
61
+// Print message when exiting
62
+process.on('SIGINT', function()
63
+{
64
+	console.log("Exiting...");
65
+	process.exit(0);
66
+});

+ 79
- 0
examples/nunchuck.cxx View File

@@ -0,0 +1,79 @@
1
+/*
2
+ * Author: Jon Trulson <jtrulson@ics.com>
3
+ * Copyright (c) 2015 Intel Corporation.
4
+ *
5
+ * Permission is hereby granted, free of charge, to any person obtaining
6
+ * a copy of this software and associated documentation files (the
7
+ * "Software"), to deal in the Software without restriction, including
8
+ * without limitation the rights to use, copy, modify, merge, publish,
9
+ * distribute, sublicense, and/or sell copies of the Software, and to
10
+ * permit persons to whom the Software is furnished to do so, subject to
11
+ * the following conditions:
12
+ *
13
+ * The above copyright notice and this permission notice shall be
14
+ * included in all copies or substantial portions of the Software.
15
+ *
16
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
+ */
24
+
25
+#include <unistd.h>
26
+#include <iostream>
27
+#include <signal.h>
28
+
29
+#include "nunchuck.h"
30
+
31
+using namespace std;
32
+
33
+bool shouldRun = true;
34
+
35
+void sig_handler(int signo)
36
+{
37
+  if (signo == SIGINT)
38
+    shouldRun = false;
39
+}
40
+
41
+int main(int argc, char **argv)
42
+{
43
+  signal(SIGINT, sig_handler);
44
+
45
+//! [Interesting]
46
+  // Instantiate a nunchuck controller bus 0
47
+  upm::NUNCHUCK *nunchuck = new upm::NUNCHUCK(0);
48
+  
49
+  // always do this first
50
+  cout << "Initializing... " << endl;
51
+  if (!nunchuck->init())
52
+    {
53
+      cerr << "nunchuck->init() failed." << endl;
54
+      return 0;
55
+    }
56
+  
57
+  while (shouldRun)
58
+    {
59
+      nunchuck->update();
60
+
61
+      cout << "stickX: " << nunchuck->stickX 
62
+           << ", stickY: " << nunchuck->stickY << endl;
63
+      cout << "accelX: " << nunchuck->accelX 
64
+           << ", accelY: " << nunchuck->accelY 
65
+           << ", accelZ: " << nunchuck->accelZ << endl;
66
+      
67
+      cout << "button C: " 
68
+           << ((nunchuck->buttonC) ? "pressed" : "not pressed") << endl;
69
+      cout << "button Z: " 
70
+           << ((nunchuck->buttonZ) ? "pressed" : "not pressed") << endl;
71
+      cout << endl;
72
+
73
+      usleep(100000);
74
+    }
75
+  //! [Interesting]
76
+  
77
+  delete nunchuck;
78
+  return 0;
79
+}

+ 5
- 0
src/nunchuck/CMakeLists.txt View File

@@ -0,0 +1,5 @@
1
+set (libname "nunchuck")
2
+set (libdescription "upm wii nunchuck module")
3
+set (module_src ${libname}.cxx)
4
+set (module_h ${libname}.h)
5
+upm_module_init()

+ 8
- 0
src/nunchuck/jsupm_nunchuck.i View File

@@ -0,0 +1,8 @@
1
+%module jsupm_nunchuck
2
+%include "../upm.i"
3
+
4
+%{
5
+    #include "nunchuck.h"
6
+%}
7
+
8
+%include "nunchuck.h"

+ 143
- 0
src/nunchuck/nunchuck.cxx View File

@@ -0,0 +1,143 @@
1
+/*
2
+ * Author: Jon Trulson <jtrulson@ics.com>
3
+ * Copyright (c) 2015 Intel Corporation.
4
+ *
5
+ * Permission is hereby granted, free of charge, to any person obtaining
6
+ * a copy of this software and associated documentation files (the
7
+ * "Software"), to deal in the Software without restriction, including
8
+ * without limitation the rights to use, copy, modify, merge, publish,
9
+ * distribute, sublicense, and/or sell copies of the Software, and to
10
+ * permit persons to whom the Software is furnished to do so, subject to
11
+ * the following conditions:
12
+ *
13
+ * The above copyright notice and this permission notice shall be
14
+ * included in all copies or substantial portions of the Software.
15
+ *
16
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
+ */
24
+
25
+#include <iostream>
26
+#include <string>
27
+#include <unistd.h>
28
+
29
+#include "nunchuck.h"
30
+
31
+using namespace upm;
32
+using namespace std;
33
+
34
+
35
+NUNCHUCK::NUNCHUCK(int bus, uint8_t addr)
36
+{
37
+  stickX = 0;
38
+  stickY = 0;
39
+  accelX = 0;
40
+  accelY = 0;
41
+  accelZ = 0;
42
+  buttonC = false;
43
+  buttonZ = false;
44
+
45
+  // setup our i2c link
46
+  m_i2c = mraa_i2c_init(bus);
47
+
48
+  mraa_result_t rv;
49
+
50
+  if ( (rv = mraa_i2c_address(m_i2c, addr)) != MRAA_SUCCESS )
51
+    {
52
+      cerr << __FUNCTION__ << ": mraa_i2c_address() failed." << endl;
53
+      mraa_result_print(rv);
54
+    }
55
+}
56
+
57
+NUNCHUCK::~NUNCHUCK()
58
+{
59
+  mraa_i2c_stop(m_i2c);
60
+}
61
+
62
+bool NUNCHUCK::writeByte(uint8_t reg, uint8_t byte)
63
+{
64
+  mraa_result_t rv;
65
+
66
+  if ( (rv = mraa_i2c_write_byte_data(m_i2c, byte, reg)) != MRAA_SUCCESS )
67
+    {
68
+      cerr << __FUNCTION__ << ": mraa_i2c_write_byte_data() failed." << endl;
69
+      mraa_result_print(rv);
70
+      return false;
71
+    }
72
+
73
+  return true;
74
+}
75
+
76
+uint8_t NUNCHUCK::readBytes(uint8_t reg, uint8_t *buffer, unsigned int len)
77
+{
78
+  if (!len || !buffer)
79
+    return 0;
80
+
81
+  mraa_i2c_address(m_i2c, NUNCHUCK_I2C_ADDR);
82
+  mraa_i2c_write_byte(m_i2c, reg);
83
+
84
+  return mraa_i2c_read(m_i2c, buffer, len);
85
+}
86
+
87
+bool NUNCHUCK::init()
88
+{
89
+  usleep(1000000);
90
+
91
+  // disable encryption
92
+  if (!writeByte(0xf0, 0x55))
93
+    return false;
94
+
95
+  if (!writeByte(0xfb, 0x00))
96
+    return false;
97
+
98
+  return true;
99
+}
100
+
101
+void NUNCHUCK::update()
102
+{
103
+  const int bufsize = 6;
104
+  uint8_t buf[bufsize];
105
+  int rv;
106
+
107
+  rv = readBytes(0x00, buf, bufsize);
108
+
109
+  if (rv != bufsize)
110
+    {
111
+      cerr << __FUNCTION__ << "read failed, expected " << bufsize 
112
+           << "bytes, got " << rv << endl;
113
+      return;
114
+    }
115
+
116
+  // analog stick X
117
+  stickX = buf[0];
118
+
119
+  // analog stick Y
120
+  stickY = buf[1];
121
+
122
+  // accelerometer X
123
+  accelX = ( (buf[2] << 2) | ((buf[5] & 0x0c) >> 2) );
124
+
125
+  // accelerometer Y
126
+  accelY = ( (buf[3] << 2) | ((buf[5] & 0x30) >> 4) );
127
+
128
+  // accelerometer Z
129
+  accelZ = ( (buf[4] << 2) | ((buf[5] & 0xc0) >> 6) );
130
+
131
+  // buttonC
132
+  if (buf[5] & 0x02)
133
+    buttonC = false;
134
+  else
135
+    buttonC = true;
136
+
137
+  // buttonZ
138
+  if (buf[5] & 0x01)
139
+    buttonZ = false;
140
+  else
141
+    buttonZ = true;
142
+}
143
+

+ 148
- 0
src/nunchuck/nunchuck.h View File

@@ -0,0 +1,148 @@
1
+/*
2
+ * Author: Jon Trulson <jtrulson@ics.com>
3
+ * Copyright (c) 2015 Intel Corporation.
4
+ *
5
+ * Permission is hereby granted, free of charge, to any person obtaining
6
+ * a copy of this software and associated documentation files (the
7
+ * "Software"), to deal in the Software without restriction, including
8
+ * without limitation the rights to use, copy, modify, merge, publish,
9
+ * distribute, sublicense, and/or sell copies of the Software, and to
10
+ * permit persons to whom the Software is furnished to do so, subject to
11
+ * the following conditions:
12
+ *
13
+ * The above copyright notice and this permission notice shall be
14
+ * included in all copies or substantial portions of the Software.
15
+ *
16
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
+ */
24
+#pragma once
25
+
26
+#include <string>
27
+#include <mraa/i2c.h>
28
+
29
+#define NUNCHUCK_I2C_ADDR    0x52
30
+
31
+namespace upm {
32
+
33
+  /**
34
+   * @brief C++ API for the Wii Nunchuck
35
+   *
36
+   * UPM module for the Wii Nunchuck.  This module was tested with the
37
+   * Wii Nunchuck connected to I2C via a Grove Wii Nunchuck adapter.
38
+   *
39
+   * See http://wiibrew.org/wiki/Wiimote/Extension_Controllers and
40
+   * http://wiibrew.org/wiki/Wiimote/Extension_Controllers/Nunchuck
41
+   * for more detailed information on the controller and it's protocol.
42
+   *
43
+   * A warning for the Grove nunchuck adapter: It has 2 traces on one
44
+   * side, and 3 traces on the other.  Do not match these up with the
45
+   * nunchuck connector's traces.  The nunchuck connector 'groove'
46
+   * should be on the same side as the grove interface socket on the
47
+   * adapter.
48
+   *
49
+   * @ingroup nunchuck 
50
+   * @defgroup nunchuck libupm-nunchuck
51
+   * @snippet nunchuck.cxx Interesting
52
+   */
53
+  class NUNCHUCK {
54
+  public:
55
+    /**
56
+     * NUNCHUCK constructor
57
+     *
58
+     * @param bus i2c bus to use
59
+     * @param addr i2c address to use
60
+     */
61
+    NUNCHUCK(int bus, uint8_t addr=NUNCHUCK_I2C_ADDR);
62
+
63
+    /**
64
+     * NUNCHUCK destructor
65
+     */
66
+    ~NUNCHUCK();
67
+
68
+    /**
69
+     * Write value(s) into registers
70
+     *
71
+     * @param reg register location to start writing into
72
+     * @param byte byte to write
73
+     * @return true if successful
74
+     */
75
+    bool writeByte(uint8_t reg, uint8_t byte);
76
+
77
+    /**
78
+     * Read value(s) from registers
79
+     *
80
+     * @param reg register location to start reading from
81
+     * @param buffer buffer for data storage
82
+     * @param len number of bytes to read
83
+     * @return number of bytes read
84
+     */
85
+    uint8_t readBytes(uint8_t reg, uint8_t *buffer, unsigned int len);
86
+
87
+    /**
88
+     * Initialize the controller.  Here, we disable encryption after
89
+     * delaying for a time to ensure the controller is ready.
90
+     *
91
+     * @return true if initialized successfully
92
+     */
93
+    bool init();
94
+
95
+    /**
96
+     * Read and update the current state of the controller.
97
+     *
98
+     */
99
+    void update();
100
+
101
+    /**
102
+     * Current analog stick X position
103
+     *
104
+     */
105
+    int stickX;
106
+
107
+    /**
108
+     * Current analog stick Y position
109
+     *
110
+     */
111
+    int stickY;
112
+
113
+    /**
114
+     * Current accelerometer X value
115
+     *
116
+     */
117
+    int accelX;
118
+
119
+    /**
120
+     * Current accelerometer Y value
121
+     *
122
+     */
123
+    int accelY;
124
+
125
+    /**
126
+     * Current accelerometer Z value
127
+     *
128
+     */
129
+    int accelZ;
130
+
131
+    /**
132
+     * Button C pressed?
133
+     *
134
+     */
135
+    bool buttonC;
136
+
137
+    /**
138
+     * Button Z pressed?
139
+     *
140
+     */
141
+    bool buttonZ;
142
+
143
+  private:
144
+    mraa_i2c_context m_i2c;
145
+  };
146
+}
147
+
148
+

+ 9
- 0
src/nunchuck/pyupm_nunchuck.i View File

@@ -0,0 +1,9 @@
1
+%module pyupm_nunchuck
2
+%include "../upm.i"
3
+
4
+%feature("autodoc", "3");
5
+
6
+%include "nunchuck.h"
7
+%{
8
+    #include "nunchuck.h"
9
+%}