It's easy to use the Adafruit I2C QT Rotary Encoder with CircuitPython using the Adafruit CircuitPython seesaw library. This library allows you to write Python code that reads encoder position (relative to the starting position) and, if applicable to your rotary encoder, button presses.
You can use this sensor with any CircuitPython microcontroller board or with a computer that has GPIO and Python thanks to Adafruit_Blinka, our CircuitPython-for-Python compatibility library.
CircuitPython Microcontroller Wiring
First wire up an I2C QT Rotary Encoder breakout to your board exactly as follows. The following is the breakout wired to a Feather using the STEMMA connector:
- Board 3V to breakout VIN (red wire)
- Board GND to breakout GND (black wire)
- Board SCL to breakout SCL (yellow wire)
- Board SDA to breakout SDA (blue wire)
The following is the breakout wired to a Feather using a solderless breadboard:
- Board 3V to breakout VIN (red wire)
- Board GND to breakout GND (black wire)
- Board SCL to breakout SCL (yellow wire)
- Board SDA to breakout SDA (blue wire)
Python Computer Wiring
Since there's dozens of Linux computers/boards you can use we will show wiring for Raspberry Pi. For other platforms, please visit the guide for CircuitPython on Linux to see whether your platform is supported.
Here's the Raspberry Pi wired with I2C using the STEMMA connector:
- Pi 3V to breakout VIN (red wire)
- Pi GND to breakout GND (black wire)
- Pi SCL to breakout SCL (yellow wire)
- Pi SDA to breakout SDA (blue wire)
Here's the Raspberry Pi wired with I2C using a solderless breadboard:
- Pi 3V to breakout VIN (red wire)
- Pi GND to breakout GND (black wire)
- Pi SCL to breakout SCL (yellow wire)
- Pi SDA to breakout SDA (blue wire)
Python Installation of seesaw Library
You'll need to install the Adafruit_Blinka library that provides the CircuitPython support in Python. This may also require enabling I2C on your platform and verifying you are running Python 3. Since each platform is a little different, and Linux changes often, please visit the CircuitPython on Linux guide to get your computer ready!
Once that's done, from your command line run the following command:
pip3 install adafruit-circuitpython-seesaw
If your default Python is version 3 you may need to run 'pip' instead. Just make sure you aren't trying to use CircuitPython on Python 2.x, it isn't supported!
CircuitPython & Python Usage
To demonstrate using this breakout with CircuitPython, you'll install the necessary library, update your code, and then connect to the serial console to see the information printed out.
To use the I2C QT Rotary Encoder breakout with CircuitPython, you need to first install the seesaw library into the lib folder on your CIRCUITPY drive.
Then you need to update code.py.
Click the Download Project Bundle button below to download the necessary libraries and the code.py file in a zip file. Extract the contents of the zip file, and copy the entire lib folder and the code.py file to your CIRCUITPY drive.
# SPDX-FileCopyrightText: 2021 John Furcean # SPDX-License-Identifier: MIT """I2C rotary encoder simple test example.""" import board from adafruit_seesaw import seesaw, rotaryio, digitalio # For use with the STEMMA connector on QT Py RP2040 # import busio # i2c = busio.I2C(board.SCL1, board.SDA1) # seesaw = seesaw.Seesaw(i2c, 0x36) i2c = board.I2C() # uses board.SCL and board.SDA # i2c = board.STEMMA_I2C() # For using the built-in STEMMA QT connector on a microcontroller seesaw = seesaw.Seesaw(i2c, addr=0x36) seesaw_product = (seesaw.get_version() >> 16) & 0xFFFF print("Found product {}".format(seesaw_product)) if seesaw_product != 4991: print("Wrong firmware loaded? Expected 4991") # Configure seesaw pin used to read knob button presses # The internal pull up is enabled to prevent floating input seesaw.pin_mode(24, seesaw.INPUT_PULLUP) button = digitalio.DigitalIO(seesaw, 24) button_held = False encoder = rotaryio.IncrementalEncoder(seesaw) last_position = None while True: # negate the position to make clockwise rotation positive position = -encoder.position if position != last_position: last_position = position print("Position: {}".format(position)) if not button.value and not button_held: button_held = True print("Button pressed") if button.value and button_held: button_held = False print("Button released")
Your CIRCUITPY drive should resemble the image.
You should have in / of the CIRCUITPY drive:
- code.py
And in the lib folder on your CIRCUITPY drive:
- adafruit_seesaw/
Now, connect to the serial console. Try rotating the rotary encoder to see the position change, and, if applicable, press the button to see the button status printed out!
That's all there is to using the I2C QT Rotary Encoder with CircuitPython!
NeoPixel Color Picker Example
Update your code.py file to the following.
Click the Download Project Bundle button below to download the necessary libraries and the code.py file in a zip file. Extract the contents of the zip file, and copy the entire lib folder and the seesaw_rotary_neopixel.py file to your CIRCUITPY drive.
Rename seesaw_rotary_neopixel.py to code.py.
# SPDX-FileCopyrightText: 2021 Kattni Rembor for Adafruit Industries # SPDX-License-Identifier: MIT """I2C rotary encoder NeoPixel color picker and brightness setting example.""" import board from rainbowio import colorwheel from adafruit_seesaw import seesaw, neopixel, rotaryio, digitalio # For use with the STEMMA connector on QT Py RP2040 # import busio # i2c = busio.I2C(board.SCL1, board.SDA1) # seesaw = seesaw.Seesaw(i2c, 0x36) i2c = board.I2C() # uses board.SCL and board.SDA # i2c = board.STEMMA_I2C() # For using the built-in STEMMA QT connector on a microcontroller seesaw = seesaw.Seesaw(i2c, 0x36) encoder = rotaryio.IncrementalEncoder(seesaw) seesaw.pin_mode(24, seesaw.INPUT_PULLUP) switch = digitalio.DigitalIO(seesaw, 24) pixel = neopixel.NeoPixel(seesaw, 6, 1) pixel.brightness = 0.5 last_position = -1 color = 0 # start at red while True: # negate the position to make clockwise rotation positive position = -encoder.position if position != last_position: print(position) if switch.value: # Change the LED color. if position > last_position: # Advance forward through the colorwheel. color += 1 else: color -= 1 # Advance backward through the colorwheel. color = (color + 256) % 256 # wrap around to 0-256 pixel.fill(colorwheel(color)) else: # If the button is pressed... # ...change the brightness. if position > last_position: # Increase the brightness. pixel.brightness = min(1.0, pixel.brightness + 0.1) else: # Decrease the brightness. pixel.brightness = max(0, pixel.brightness - 0.1) last_position = position
Rotate the rotary encoder to cycle through the NeoPixel rainbow. Press the rotary encoder switch and rotate while holding the switch to change the brightness.
That's all there is to using the NeoPixel with the rotary encoder using CircuitPython!
Multiple QT Rotary Encoder Example
Here's an example that uses multiple boards. The first board is in the default state, while the second board has it's A0 jumper bridged to set the I2C address to 0x37
.
# SPDX-FileCopyrightText: 2021 John Park # SPDX-License-Identifier: MIT # I2C rotary encoder multiple test example. # solder the A0 jumper on the second QT Rotary Encoder board import board from adafruit_seesaw import seesaw, rotaryio, digitalio, neopixel i2c = board.I2C() # uses board.SCL and board.SDA # i2c = board.STEMMA_I2C() # For using the built-in STEMMA QT connector on a microcontroller qt_enc1 = seesaw.Seesaw(i2c, addr=0x36) qt_enc2 = seesaw.Seesaw(i2c, addr=0x37) qt_enc1.pin_mode(24, qt_enc1.INPUT_PULLUP) button1 = digitalio.DigitalIO(qt_enc1, 24) button_held1 = False qt_enc2.pin_mode(24, qt_enc2.INPUT_PULLUP) button2 = digitalio.DigitalIO(qt_enc2, 24) button_held2 = False encoder1 = rotaryio.IncrementalEncoder(qt_enc1) last_position1 = None encoder2 = rotaryio.IncrementalEncoder(qt_enc2) last_position2 = None pixel1 = neopixel.NeoPixel(qt_enc1, 6, 1) pixel1.brightness = 0.2 pixel1.fill(0xff0000) pixel2 = neopixel.NeoPixel(qt_enc2, 6, 1) pixel2.brightness = 0.2 pixel2.fill(0x0000ff) while True: # negate the position to make clockwise rotation positive position1 = -encoder1.position position2 = -encoder2.position if position1 != last_position1: last_position1 = position1 print("Position 1: {}".format(position1)) if not button1.value and not button_held1: button_held1 = True pixel1.brightness = 0.5 print("Button 1 pressed") if button1.value and button_held1: button_held1 = False pixel1.brightness = 0.2 print("Button 1 released") if position2 != last_position2: last_position2 = position2 print("Position 2: {}".format(position2)) if not button2.value and not button_held2: button_held2 = True pixel2.brightness = 0.5 print("Button 2 pressed") if button2.value and button_held2: button_held2 = False pixel2.brightness = 0.2 print("Button 2 released")
Page last edited January 22, 2025
Text editor powered by tinymce.