antiero ยท GitHub

A few years ago I bought a "5x Rotary Encoder I2C Expansion Board v2.0" from eBay - it had no datasheet (or I lost it! :), and I can't find any trace of the board online:

IMG_2500

I figured out the chip it used was the MCP23017 and discovered Adafruit_CircuitPython_MCP230xx... ๐Ÿ™Œ

I'm able to connect to the i2c board (on address 0x27) and can read values.
Push state of encoders is no problem, but I can't get my head around how to interpret the rotary encoders!

I hoped I could use the rotaryio module, however as this Issue explains, it's not compatible with an i2c / GPIO pin approach:

The CircuitPython Code I'm using with a Pi Pico:

import time
import board
import rotaryio
import busio
from micropython import const
from digitalio import Direction, Pull
from adafruit_mcp230xx.mcp23017 import MCP23017
i2c = busio.I2C(board.GP5, board.GP4)    # Pi Pico RP2040
mcp = MCP23017(i2c, address=0x27)
# Make a list of all the pins (a.k.a 0-16)
pins = []
for pin in range(0, 16):
    pins.append(mcp.get_pin(pin))
# Set all the pins to input
for pin in pins:
    pin.direction = Direction.INPUT
    pin.pull = Pull.UP
def configure_ports():
    mcp.gppub = 0b11111111   # enable pull-ups on all port B pins (switches)
    # Set up to check all the port B pins (pins 8-15) w/interrupts!
    mcp.interrupt_enable = 0xFFFF  # Enable Interrupts in all pins
    # If intcon is set to 0's we will get interrupts on
    # both button presses and button releases
    mcp.interrupt_configuration = 0x0000  # interrupt on any change, 0x0000
    mcp.io_control = 0x44  # Interrupt as open drain and mirrored, 0x44
    mcp.clear_ints()  # Interrupts need to be cleared initially
configure_ports()
# 5x Rotary Encoder I2C Expansion Board:
# ENC1: 7 (PUSH), 5-6 Turn
# ENC2: 4 (PUSH), 2-3 Turn
# ENC3: 8 (PUSH), 9-10 Turn
# ENC4: 11 (PUSH), 12-13 Turn
# ENC5: 14 (PUSH), 1-15 Turn
mcp.clear_ints()  # Interrupts need to be cleared initially
time.sleep(1)
pushButtons = [pins[7], pins[4], pins[8], pins[11], pins[14]]
while True:
    for num, button in enumerate(pins):
        if not button.value:
            print("Encoder PIN ACTIVE UP %s, value: %s" % (str(num), str(button.value)))
    for pin, state in enumerate(pushButtons):
        if (not state.value):
            print("ENCODER DOWN: %s" % str(pin))

Read the original on github.com โ†—