Circuit Python Libraries for Qwiic Joystick, Qwiic Relay and Qwiic Twist

Hi,

I have ported the Qwiic Joystick, Qwiic Relay and Qwiic Twist Arduino libraries to CircuitPython libraries. All the example programs were also ported, so one can follow along the Sparkfun Arduino tutorials and Hookup Guides with a Raspberry Pi using these CircuitPython classes and the python example code.

The Arduino function names were converted to Python following PEP8 style rules. Single value getter/setter methods were converted to Python class properties. For example, joystick.getHorizontal() in Arduino code becomes joystick.horizontal in python code. The Arduino methods relayOn() and relayOff() become relay_on() and relay_off() in python, and so on.

These libraries were released to the CircuitPython Community Repository. The source code, examples, installation information and documentation are available on GitHub.

Qwiic Joystick:

https://github.com/fourstix/Sparkfun_Ci … icJoystick

Qwiic Relay:

The source code, examples and documentation are available on GitHub here:

https://github.com/fourstix/Sparkfun_Ci … QwiicRelay

Qwiic Twist:

https://github.com/fourstix/Sparkfun_Ci … QwiicTwist

Adafruit has an excellent tutorial on installing CircuitPython on a Raspberry Pi.

https://learn.adafruit.com/circuitpytho … pberry-pi/

Once CircuitPython is installed on your Raspberry Pi, you can install the Qwiic CirucuitPython libraries you wish to use through Pip3 commands.

pip3 install sparkfun-circuitpython-qwiicjoystick
pip3 install sparkfun-circuitpython-qwiicrelay
pip3 install sparkfun-circuitpython-qwiictwist

Example:

Using the CircuitPython library on a Raspberry Pi, you can program the Joystick as follows:

    # import the CircuitPython board and busio libraries
    import board
    import busio
    import sparkfun_qwiicjoystick

    # Create bus object using the board's I2C port
    i2c = busio.I2C(board.SCL, board.SDA)

    joystick = sparkfun_qwiicjoystick.QwiiJoystick(i2c)  # default address is 0x20

    # For a different address use QwiicJoystick(i2c, address)
    # joysitck = sparkfun_qwiicjoystick.QwiicJoystick(i2c, 0x21)

    # show the joystick position and button values
    print('X: ' + str(joystick.horizontal) 
          + ' Y: ' + str(joystick.vertical) 
          + ' Button: ' + str(joystick.button))

For QwiicRelay you would create the class with:

    relay = sparkfun_qwiicrelay.QwiiRelay(i2c)  # default address is 0x18

And for QwiicTwist you would use:

    twist = sparkfun_qwiictwist.QwiiTwist(i2c)  # default address is 0x3F

I wrote these libraries on my own time and they are open source under the MIT license and free to use. They are based on Sparkfun and Adafruit products, tutorials and code. Sparkfun and Adafruit retain all rights to their respective intellectual properties. Please note that I am neither a Sparkfun nor Adafruit employee, so no official warranty or support for these libraries is implied or given by either company.

That said, please enjoy them and have fun!

Gaston Williams aka Fourstix

Thanks Gaston! (I already replied to one of your comments)

fonz.jpg

We’ve been trying to develop/finalize a structure for a python library package for all of our I2C products for a few months. I think we did an initial [release of the library recently, if you want to check that out. We are still working on adding more products to the python library first before we get to a micropython and/or circuitpython library.

I’ll pass on the information about your libraries. Maybe we will fork your libraries and modify them to work with our current library package.](GitHub - sparkfun/Qwiic_Py: Python package for the qwiic system.)

Is there any plan (or status?) on a port of the SF Qwiic Relay from Arduino or fourstix’s CP port to SparkFun’s code base (https://github.com/sparkfun/Qwiic_Py)? I have just purchased a Single Relay and would appreciate having access to this package. Thanks.

I have created a qwiic single relay driver file for the SparkFun library, in case anyone finds this useful. To install, I placed it along side the other SparkFun qwiic drivers, under /usr/local/lib/ on my RPi. Note: I am not a python programmer, so review before using!

Edited by moderator to add code tags

[i]qwiic_singlerelay.py[/i]

from __future__ import print_function

import qwiic_i2c

# Define the device name and I2C addresses. These are set in the class defintion
# as class variables, making them avilable without having to create a class instance.
# This allows higher level logic to rapidly create a index of qwiic devices at
# runtine
#
# The name of this device
_DEFAULT_NAME = "SparkFun Qwiic Single Relay"

# Some devices have multiple availabel addresses - this is a list of these addresses.
# NOTE: The first address in this list is considered the default I2C address for the
# device.
_AVAILABLE_I2C_ADDRESS = [0x18, 0x19]

# Register codes for the QwiicSingleRelay
ADDRESS_LOCATION       = 0xC7
INCORR_PARAM           = 0xFF
#  Status codes
SINGLE_RELAY_OFF      = 0
SINGLE_RELAY_ON       = 1  
#  Commands codes
TURN_RELAY_OFF        = 0x00
TURN_RELAY_ON         = 0x01
FIRMWARE_VERSION      = 0x04
SINGLE_RELAY_STATUS   = 0x05

# define the class that encapsulates the device being created. All information associated with this
# device is encapsulated by this class. The device class should be the only value exported
# from this module.

class QwiicSingleRelay(object):
    """
    QwiicSingleRelay
        :param address: The I2C address to use for the device.
                        If not provided, the default address is used.
        :param i2c_driver: An existing i2c driver object. If not provided
                        a driver object is created.
        :return: The QwiicSingleRelay device object.
        :rtype: Object
    """
    # Constructor
    device_name         = _DEFAULT_NAME
    available_addresses = _AVAILABLE_I2C_ADDRESS

    def __init__(self, address=None, i2c_driver=None):

        # Did the user specify an I2C address?

        self.address = address if address is not None else self.available_addresses[0]

        # load the I2C driver if one isn't provided

        if i2c_driver is None:
            self._i2c = qwiic_i2c.getI2CDriver()
            if self._i2c is None:
                print("Unable to load I2C driver for this platform.")
                return
        else:
            self._i2c = i2c_driver

        ##### TODO: any vaules to initialize ???

    # ----------------------------------
    # is_connected()
    #
    # Is an actual board connected to our system?

    def is_connected(self):
        """
            Determine if a QwiicSingleRelay device is conntected to the system..
            :return: True if the device is connected, otherwise False.
            :rtype: bool
        """
        return qwiic_i2c.isDeviceConnected(self.address)
    
    connected = property(is_connected)

# from SF Arduino relay.h - functions defined
#  public:

    # ----------------------------------
    # begin()
    #
    # Initialize the system/validate the board.
    def begin(self):
        """
            Initialize the operation of the Keypad module
            :return: Returns true of the initializtion was successful, otherwise False.
            :rtype: bool
        """

        # Basically return True if we are connected...

        return self.is_connected()

    #----------------------------------------------------------------
    # get_status()
    #
    # Returns an int (0|1) for the status of the Single Relay (off|on)

    def get_status(self):
        """
        This function for the SparkFun Single Relay, gets the status of the relay:
            whether on: 1 or off: 0
        :return: Returns the relay status
        :rtype: int
        """
        
        status = self._i2c.readByte(self.address, SINGLE_RELAY_STATUS)

        return status 

    status = property(get_status)
    
    #----------------------------------------------------------------
    # turnRelayOn()
    #
    # This function turns the single relay board on if off

    def turnRelayOn(self):
        """
        This function for the SparkFun Single Relay, turns the relay ON
        :return: n/a
        :rtype: n/a
        """

        if (self.get_status() == SINGLE_RELAY_OFF):
            self._i2c.writeCommand(self.address, TURN_RELAY_ON) #, 0x01)

    #----------------------------------------------------------------
    # turnRelayOff()
    #
    # This function turns the single relay board off if on

    def turnRelayOff(self):
        """
        This function for the SparkFun Single Relay, turns the relay OFF
        :return: n/a
        :rtype: n/a
        """

        if (self.get_status() == SINGLE_RELAY_ON):
            self._i2c.writeCommand(self.address, TURN_RELAY_OFF) #, 0x01)


    #----------------------------------------------------------------
    # toggleRelay()
    #
    # This function gives toggle functionality to the single relay. First the
    # status of the relay is checked and is toggled according to what the status
    # of the relay: on ---> off or off ----> on.

    def toggleRelay(self):
        """
        This function for the SparkFun Single Relay, toggles the current status of the
            relay
        :return: n/a
        :rtype: n/a
        """

        if (self.get_status() == SINGLE_RELAY_OFF):
            self._i2c.writeCommand(self.address, TURN_RELAY_ON) #, 0x01)
        else:
            self._i2c.writeCommand(self.address, TURN_RELAY_OFF) #, 0x01)

    #----------------------------------------------------------------
    # get_version()
    #
    # Returns a string of the firmware version number

    def get_version(self):
        """
        Returns a string of the firmware version number
        :return: The firmware version
        :rtype: string
        """
        vers = self._i2c.readByte(self.address, FIRMWARE_VERSION)

        return "v %d" % (vers)

    version = property(get_version)


[i]relay_test_1.py[/i]


from __future__ import print_function
import qwiic_singlerelay
import time
import sys

def runExample():
    print("SparkFun qwiic single relay example")

    myRelay = qwiic_singlerelay.QwiicSingleRelay()

    if (myRelay.connected == False):
        print("The qwiic single relay is not connected", file=sys.stderr)
        return

    myRelay.begin()

    print("The qwiic single relay is connected.")
    print("Firmware version: %s" % myRelay.version)
    print("Current state is: %s" % myRelay.status)

    while True:

        print("Turning relay ON ...")
        myRelay.turnRelayOn()
        print("Current state is (on?): %s" % myRelay.status)

        time.sleep(1)

        print("Turning relay OFF ...")
        myRelay.turnRelayOff()
        print("Current state is (off?): %s" % myRelay.status)

        time.sleep(1)

        print("Toggling relay state ...")
        myRelay.toggleRelay()
        print("Current state is (toggled?): %s" % myRelay.status)

        time.sleep(1)

if __name__ == '__main__':
	try:
		runExample()
	except (KeyboardInterrupt, SystemExit) as exErr:
		print("\nEnding Example 1")
		sys.exit(0)

When posting code, please use [ code ] and [ /code ] tags (without the spaces around the square brackets). Otherwise, the formatting and spacing of the code will be munged, which, for a language like Python, makes a mess out of it.

/mike

I have successfully followed the instructions for Installing QWIIC Twist CircuitPython Libraries on Raspberry Pi (for me it was a RPi 400). Now I would like to put the CircuitPython library on a smaller device such as the XIAO RP2040. I looked in the most recent adafruit library bundle dated 2022/06/11 and could not find it there. Is there a “mpy” version or a way to transfer the one installed on a Raspberry Pi?

Hi,

I’m not too familiar with this method of installation, but on the release page in GitHub, https://github.com/fourstix/Sparkfun_Ci … t/releases the release contains zip files with the mpy files.

There’s one zip file named sparkfun-circuitpython-qwiictwist-6.x-mpy-1.0.8.zip and another named sparkfun-circuitpython-qwiictwist-7.x-mpy-1.0.8.zip. Download the version of zip file you need and unzip it.

The mpy files are in the /lib directory inside the zip. There is a tutorial on Adafruit https://learn.adafruit.com/welcome-to-c … -libraries that covers manually installing the mpy files. I’ve never done this, but it looks fairly straightforward basically one copies the mpy files from one /lib directory to another on the device.

Good luck to you!

Gaston aka fourstix

Perfect. Thank you. Not sure why I did not see that in my search.