miketeachman / micropython-rotary

MicroPython module to read a rotary encoder.
MIT License
269 stars 56 forks source link

Works on Raspberry Pi Pico #11

Closed doctorleach closed 2 years ago

doctorleach commented 3 years ago

I tried the code on my Pi Pico and it works (using the rotary_irq_esp32.py import). For my application I had to delete the sleep line in rotary_test.py, otherwise it would skip counts if I turned the switch at a moderate to fast rate. Of course if I wanted to do something else in the main loop, the timing issues may become a problem, but I'm just experimenting at this point.

The code could be tightened for the Pico to have an appropriate list of excluded pins, but I haven't looked them up yet.

Anyway, thanks for the code.

miketeachman commented 3 years ago

Wow. That's great to know. I expected that some low-level PIO work might be needed. Thanks for trying this out and reporting. When my Pico boards arrive I'll take a closer look.

Of course if I wanted to do something else in the main loop

You might want to take a look at the uasyncio examples. It's possible to have separate tasks running (coroutines) that are unaffected by the encoder operation.

dgoadby commented 3 years ago

I have been experimenting with a a 360ppr encoder on the Pico and, so far, I cannot get it to take a high speed rotation without dropping steps. I'm currently trying to use the second core and a shared variable to see if that helps. The other plan is to integrate a C module into Micropython - not trivial. I also tried to make a native machine code (.mpy) file but so far without success. In order to progress an urgent project I ended up using an I2C Encoder Mini as, for less than 5UKP it was cheaper then more coding hours.

founfabug commented 3 years ago

Confirming epmoyer PR#12 commits work, tested library and examples. My comments below preserved for history :-)

Thank you for the code, example_simple.py worked a treat for me with minor modification (explicit include of const)

Neither asyncio examples worked for me. The event loop is running. def init(self, r1): is run async def action(self): is entered but does not proceed past await self.myevent.wait() Adjusting the rotary does not trigger any response I can see.

Additionally, using the simple example code, console output from pico seems to be related to dropped counts - more output, more missing counts. With no console output the example code is very reliable, no dropped counts with my testing with updates to OLED SSD1306 on I2C and WS2812s being updated by changes in rotary position, as well as an ADC read.

Thank you again.

epmoyer commented 3 years ago

PR#12 implements Pico support, with all examples updated accordingly and tested.

thlabbe commented 3 years ago

HI all,

I'm not yet fluent enough in micropython / cicruitpython / rp2 GIO / asembler ... but I found this : I imagine this is a state machine for a rotary encoder in CircuitPython

... If it could lead to any improvements on the dropped counts

Anyway great job, nice commitment to all. Thank you.

[edit] here comes an other implementation C++/pioAsm : https://github.com/GitJer/Some_RPI-Pico_stuff/blob/0fb6eb63be5df57f96d22242929be92ca400089f/Rotary_encoder/pio_rotary_encoder.pio#L4

miketeachman commented 3 years ago

@thlabbe thanks for sharing this implementation. That's really interesting. I'll have to see if the PIO can improve the performance. I'll add that as a TODO in the readme.

miketeachman commented 2 years ago

Works on the rPi Pico, so closing