Skip to content

Instantly share code, notes, and snippets.

@jfurcean
Last active January 24, 2021 21:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jfurcean/78a79e5f84680aa2432ba19ebe2e0eb4 to your computer and use it in GitHub Desktop.
Save jfurcean/78a79e5f84680aa2432ba19ebe2e0eb4 to your computer and use it in GitHub Desktop.
Testing nunchuk
# SPDX-FileCopyrightText: 2019 Carter Nelson for Adafruit Industries
#
# SPDX-License-Identifier: MIT
"""
`adafruit_nunchuk`
================================================================================
CircuitPython library for Nintendo Nunchuk controller
* Author(s): Carter Nelson
Implementation Notes
--------------------
**Hardware:**
* `Wii Remote Nunchuk <https://en.wikipedia.org/wiki/Wii_Remote#Nunchuk>`_
* `Wiichuck <https://www.adafruit.com/product/342>`_
**Software and Dependencies:**
* Adafruit CircuitPython firmware for the supported boards:
https://github.com/adafruit/circuitpython/releases
* Adafruit's Bus Device library: https://github.com/adafruit/Adafruit_CircuitPython_BusDevice
"""
import time
from adafruit_bus_device.i2c_device import I2CDevice
__version__ = "0.0.0-auto.0"
__repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_Nunchuk.git"
_I2C_INIT_DELAY = 0.1
class Nunchuk:
"""
Class which provides interface to Nintendo Nunchuk controller.
:param i2c: The `busio.I2C` object to use.
:param address: The I2C address of the device. Default is 0x52.
:type address: int, optional
:param i2c_read_delay: The time in seconds to pause between the
I2C write and read. This needs to be at least 200us. A
conservative default of 2000us is used since some hosts may
not be able to achieve such timing.
:type i2c_read_delay: float, optional
"""
def __init__(self, i2c, address=0x52, i2c_read_delay=0.002):
self.buffer = bytearray(8)
self.i2c_device = I2CDevice(i2c, address)
self._i2c_read_delay = i2c_read_delay
time.sleep(_I2C_INIT_DELAY)
with self.i2c_device as i2c_dev:
# turn off encrypted data
# http://wiibrew.org/wiki/Wiimote/Extension_Controllers
i2c_dev.write(b"\xF0\x55")
time.sleep(_I2C_INIT_DELAY)
i2c_dev.write(b"\xFB\x00")
self._last_read = 0
@property
def joystick(self):
"""Return tuple of current joystick position."""
self._read_data()
return self.buffer[0], self.buffer[1]
@property
def button_C(self): # pylint: disable=invalid-name
"""Return current pressed state of button C."""
return not bool(self._read_data()[5] & 0x02)
@property
def button_Z(self): # pylint: disable=invalid-name
"""Return current pressed state of button Z."""
return not bool(self._read_data()[5] & 0x01)
@property
def acceleration(self):
"""Return 3 tuple of accelerometer reading."""
self._read_data()
x = (self.buffer[5] & 0xC0) >> 6
x |= self.buffer[2] << 2
y = (self.buffer[5] & 0x30) >> 4
y |= self.buffer[3] << 2
z = (self.buffer[5] & 0x0C) >> 2
z |= self.buffer[4] << 2
return x, y, z
def _read_data(self):
if time.monotonic() - self._last_read > .0095:
self._read_register(b"\x00")
self._last_read = time.monotonic()
return self.buffer
def _read_register(self, address):
with self.i2c_device as i2c:
i2c.write(address)
time.sleep(self._i2c_read_delay) # at least 200us
i2c.readinto(self.buffer)
return self.buffer
import board
import usb_hid
from adafruit_hid.mouse import Mouse
from adafruit_nunchuk import Nunchuk
import busio
import time
# frequency must be set for the MCP9600 to function.
# If you experience I/O errors, try changing the frequency.
i2c = busio.I2C(board.SCL, board.SDA, frequency=100000)
m = Mouse(usb_hid.devices)
nc = Nunchuk(i2c)
centerX = 128
centerY = 128
scaleX = 0.3
scaleY = 0.3
cDown = False
zDown = False
# This is to allow double checking (only on left click - and it doesn't really work)
CHECK_COUNT = 0
total_time = 0
count = 0
while True:
start = time.monotonic()
x, y = nc.joystick
# Eliminate spurious reads
if x == 255 or y == 255:
continue
relX = x - centerX
relY = centerY - y
m.move(int(scaleX * relX), int(scaleY * relY), 0)
c = nc.button_C
z = nc.button_Z
if z and not zDown:
stillDown = True
for n in range(CHECK_COUNT):
if nc.button_Z:
stillDown = False
break
if stillDown:
m.press(Mouse.LEFT_BUTTON)
zDown = True
elif not z and zDown:
stillDown = True
for n in range(CHECK_COUNT):
if not nc.button_Z:
stillDown = False
break
if stillDown:
m.release(Mouse.LEFT_BUTTON)
zDown = False
if c and not cDown:
m.press(Mouse.RIGHT_BUTTON)
cDown = True
elif not c and cDown:
m.release(Mouse.RIGHT_BUTTON)
cDown = False
end = time.monotonic()
total_time += end - start
count += 1
print(total_time/count)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment