Skip to content

Can I suggest that you wrap up the functions in to a class. #1

Description

@scotty3785

You mention that it takes 1ms each time to return values.

I've modified your code (untested on r-pi) and places it in to a class to store the values of the nunchuck in between reads which are now executed by calling the update_all() method of the class.

Modified code below.

from __future__ import division
import wiringpi
import fcntl
import os

class PiNunchuck:
    def __init__(i2c_file):
        self.i2c_file = i2c_file
        self.i2c_fd = -1
        self.i2c_addr = 0x52
        self.i2c_ioctl_num = 0x703

        self.joy_x_center = 128
        self.joy_y_center = 128
        self.joy_x = 0
        self.joy_y = 0
        self.acc_x = 0
        self.acc_y = 0
        self.acc_z = 0
        self.btn_z = 0
        self.btn_c = 0
        self.setup()

    def setup(self):
        self.i2c_fd = os.open(self.i2c_file, os.O_RDWR)
        ret = fcntl.ioctl(self.i2c_fd, self.i2c_ioctl_num, self.i2c_addr)
        ret = os.write(self.i2c_fd, "\xf0\x55")
        os.write(self.i2c_fd, "\xfb\x00")
        self.calibrate_joystick()

    def calibrate_joystick(self):
        self.update_all()
        self.joy_x_center = self.joy_x
        self.joy_y_center = self.joy_y

    def update_all(self):
        os.write(self.i2c_fd, "\x00")
        wiringpi.delay(1)
        ret = bytearray(os.read(self.i2c_fd, 6))
        self.joy_x = ret[0]
        self.joy_y = ret[1]
        self.acc_x = (ret[2] << 2) + (ret[5] >> 2 & 0x03)
        self.acc_y = (ret[3] << 2) + (ret[5] >> 4 & 0x03)
        self.acc_z = (ret[4] << 2) + (ret[5] >> 6 & 0x03)
        self.btn_z = ret[5] & 0x01 == 0
        self.btn_c = ret[5] & 0x02 == 0

    def read_joy(self):
        return self.joy_x,self.joy_y
    def read_acc(self):
        return self.acc_x,self.acc_y,self.acc_z

    # This is fairly basic. In my tests, without clamping, x ranged from -9 to 10
    # and y ranged from -9 to 8, so clamping to [-8, +8] gives us equal ranges
    # withou much loss of precision. Dividing by 10 and truncating to int means
    # small fluctuations get ignored, which is probably good for most purposes.
    def read_joy_normalized(self):
        x, y = (self.joy_x,self.joy_y)
        norm_x = clamp(int((x - self.joy_x_center)/10), -8, 8)
        norm_y = clamp(int((y - self.joy_y_center)/10), -8, 8)
        return norm_x, norm_y

    def clamp(self,val, minval, maxval):
        return min(maxval, max(minval, val))

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions