diff --git a/Examples/example_mcp230xx.py b/Examples/example_mcp230xx.py new file mode 100644 index 0000000..42fd926 --- /dev/null +++ b/Examples/example_mcp230xx.py @@ -0,0 +1,34 @@ +# MIT License (MIT) +# Copyright (c) 2024 Daniel Siegmanski +# https://opensource.org/licenses/MIT + +# example for MicroPython rotary encoder connecten at an MCP23017 + +from machine import I2C +import mcp #MCP module from https://github.com/dsiggi/micropython-mcp230xx +from rotary_irq_mcp230xx import RotaryIRQ +import time + +i2c = I2C(0) +io = mcp.MCP23017(i2c) + +# CLK pin connected to mcp at GPIOA 0 +# DT pin connected to mcp at GPIOA 1 +# INTA pin from mcp connected to ESP pin 15 + +r = RotaryIRQ(mcp=io, + pin_num_clk=0, + pin_num_dt=1, + pin_num_int=15, + reverse=False, + range_mode=RotaryIRQ.RANGE_WRAP) + +val_old = r.value() +while True: + val_new = r.value() + + if val_old != val_new: + val_old = val_new + print('result =', val_new) + + time.sleep_ms(50) diff --git a/README.md b/README.md index fd047e2..82c8256 100644 --- a/README.md +++ b/README.md @@ -76,7 +76,15 @@ mpremote mip install github:miketeachman/micropython-rotary | ------------- | ------------- | | RotaryIRQ.RANGE_UNBOUNDED | encoder has no bounds on the counting range | | RotaryIRQ.RANGE_WRAP | encoder will count up to max_val then wrap to minimum value (similar behaviour for count down) | -| RotaryIRQ.RANGE_BOUNDED | encoder will count up to max_val then stop. Count down stops at min_val | +| RotaryIRQ.RANGE_BOUNDED | encoder will count up to max_val then stop. Count down stops at min_val | + +#### Special arguments for mcp version +| argument | description | value | +|-------------|-------------|---------| +| mcp | the mcp object to use | object (mcp module from https://github.com/dsiggi/micropython-mcp230xx) | +| pin_num_clk | mcp GPIO pin connected to encoder CLK pin | integer | +| pin_num_dt | GPIO pin connected to encoder DT pin | integer | +| pin_num_int | GPIO pin connected to mcp INTA/INTB pin | integer | ### Methods `value()` Return the encoder value diff --git a/rotary_irq_mcp230xx.py b/rotary_irq_mcp230xx.py new file mode 100644 index 0000000..2a828aa --- /dev/null +++ b/rotary_irq_mcp230xx.py @@ -0,0 +1,49 @@ +# The MIT License (MIT) +# Copyright (c) 2024 Daniel Siegmanski +# https://opensource.org/licenses/MIT + +# Platform-specific MicroPython code for the rotary encoder module +# mcp23017 implementation + +# Documentation: +# https://github.com/MikeTeachman/micropython-rotary + +from .rotary import Rotary +from machine import Pin + +class RotaryIRQ(Rotary): + + def __init__(self, mcp, pin_num_clk, pin_num_dt, pin_num_int, min_val=0, max_val=10, incr=1, + reverse=False, range_mode=Rotary.RANGE_UNBOUNDED, pull_up=False, half_step=False, invert=False): + + super().__init__(min_val, max_val, incr, reverse, range_mode, half_step, invert) + + self.mcp = mcp + self.clk = pin_num_clk + self.dt = pin_num_dt + + ### Configure MCP23017 ### + # Set CLK and DT pin as input + self.mcp.setup(self.clk, 1) + self.mcp.setup(self.dt, 1) + # enable pull ups + if pull_up: + self.mcp.pullup(self.clk, True) + self.mcp.pullup(self.dt, True) + # enable interrupt + self.mcp.set_interrupt(self.clk, True) + self.mcp.set_interrupt(self.dt, True) + self.mcp.configure(interrupt_polarity=True) + + # interrupt pin, set as input + self.int_pin = Pin(pin_num_int, Pin.IN) + self.int_pin.irq(trigger=self.int_pin.IRQ_RISING, handler=self._process_rotary_pins) + + def _hal_get_clk_value(self): + return self.mcp.read_captured_gpio()[self.clk] + + def _hal_get_dt_value(self): + return self.mcp.read_captured_gpio()[self.dt] + + def _hal_close(self): + self.int_pin.irq(handler=None) \ No newline at end of file