Skip to content

How to read rotary encoders from i2C board?Β #58

@antiero

Description

@antiero

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))

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions