Home
JAQForum Ver 24.01
Log In or Join  
Active Topics
Local Time 06:59 02 Aug 2025 Privacy Policy
Jump to

Notice. New forum software under development. It's going to miss a few functions and look a bit ugly for a while, but I'm working on it full time now as the old forum was too unstable. Couple days, all good. If you notice any issues, please contact me.

Forum Index : Microcontroller and PC projects : Picomite: rotary encoder interrupt kills I2C

Author Message
lizby
Guru

Joined: 17/05/2016
Location: United States
Posts: 3378
Posted: 09:50pm 17 Jul 2021
Copy link to clipboard 
Print this post

At least I think that's what's happening. This was hard for me to track down.

I'm working through trying to get my 2x20 I/O expansion board working with the Pico PCB I made.

I could get the MCP23017 to work with an independent program, but not in the sensors.bas program.

I finally narrowed it down to this: as soon as the rotary encoder is turned, the lights stop flashing on the MCP23017 (the program doesn't error out--it continues to say that it's writing to the MCP23017).

I'm using pins 1 and 2 for I2C0: SetPin 1,I2C0sda: SetPin 2,I2C0scl

Pins 32 and 10 for the rotary encoder:
 dim integer in0=32 'encoder pins pulled high so should be reading high in detent positions, centre pin connected to ground
 dim integer in1=10 'swap the pin definitions as required to get the correct sense of rotation

The rotary encoder code is from matherp's 2018 post: encoder

It may not be easy for anybody else to set up to test, but perhaps something about the interactions of I2C and interrupts for the rotary encoder will be clear to someone.


' MCP23017test.bas I2C test

 const mcp23017 = &h20 ' A2, A1, A0, R/W all connected to 0V
 Const i2caddr=mcp23017
 const IODIRA = &h00 ' Port A IO Direction register DEFAULT = I/P
 const IODIRB = &h01 ' Port B IO Direction register DEFAULT = I/P
 const IOCON = &h0A ' IO Expander config register - address &h0B accesses  same register
 const GPIOA = &h12 ' Port A General purpose register
 const GPIOB = &h13 ' Port B General Purpose register
 const OLATA = &h14 ' Port A latch register
 const OLATB = &h15 ' Port B latch register
 const GPUPB = &h0D ' Port B pull-up register

 SetPin 1,I2C0sda
 SetPin 2,I2C0scl
 dim integer in0=32 'encoder pins pulled high so should be reading high in detent positions, centre pin connected to ground
 dim integer in1=10 'swap the pin definitions as required to get the correct sense of rotation

setpin in0,intB,rint 'enable interrupts on both edges of both pins
setpin in1,intB,rint
rotatedright=false
rotatedleft=false
resetenc=true

 I2C open 100, 1000
 I2C WRITE MCP23017,0,2,IODIRA,0 ' set direction to output
 I2C WRITE MCP23017,0,2,IODIRB,0 ' set direction to output

do
 mcp17
loop

sub mcp17
 print "write to mcp23017"
 for i = 1 to 6
   I2C Write MCP23017,0,2,OLATA,&b10101010 '  
   I2C Write MCP23017,0,2,OLATB,&b01010101 '  
   PAUSE     1000
   I2C Write MCP23017,0,2,OLATA,&b01010101 '  
   I2C Write MCP23017,0,2,OLATB,&b10101010 '  
   PAUSE     1000
 Next i
 I2C Write MCP23017,0,2,OLATA,0 ' turn all off
 I2C Write MCP23017,0,2,OLATB,0 ' turn all off
 pause 1000
end sub

sub rint ' rotary encoder interrupt
' code: https://www.thebackshed.com/forum/ViewTopic.php?TID=10568&PID=124755#124755
' from matherp & goc
rint2:
pin0=NOT pin(in0) 'reverse sense to get positive logic
pin1=NOT pin(in1)
if pin0 then
if pin1 and not resetenc then 'in0 and in1 both active
if rotatedleft and not rotatedright then
value=fix(max(1,value-1)) ' minimum of 1
rotatedleft=false
endif
if rotatedright and not rotatedleft then
value=fix(min(maxSensor,value+1))
rotatedright=false
endif
else 'only in0 active
if resetenc and not rotatedleft then
rotatedright=true
resetenc=false
endif
endif
else
if pin1 then 'only in1 active
if resetenc and not rotatedright then
rotatedleft=true
resetenc=false
endif
else 'both off so reset
rotatedleft=false
rotatedright=false
resetenc=true
endif
endif
if pin(in0)=pin0 or pin(in1)=pin1 then goto rint2 're-enter if another change has happened almost immediately
end sub

> option list
OPTION SYSTEM I2C GP10,GP11
OPTION LCDPANEL SSD1306I2C, LANDSCAPE
OPTION RTC AUTO ENABLED
OPTION GUI CONTROLS 59
OPTION MEMORY 60160, 100608
>


~
Edited 2021-07-18 07:55 by lizby
PicoMite, Armmite F4, SensorKits, MMBasic Hardware, Games, etc. on fruitoftheshed
 
lizby
Guru

Joined: 17/05/2016
Location: United States
Posts: 3378
Posted: 12:46am 18 Jul 2021
Copy link to clipboard 
Print this post

Well, hold any thoughts.

I set up the program to run on an F4, changing the pins appropriately and plugging the MCP23017 into the I2C port on the 2x20 expansion board. It worked--flashing lights on the MCP23017 were not affected by the rotary encoder.

I switched back to Picomite, leaving the MCP23017 connected to the expansion PCB. It worked.

I moved the MCP23017 back to the header on my main Picomite PCB. The blinking lights work, but moving the rotary encoder causes them to stop.  So it has to be something about the PCB.

So more head-scratching. If anyone has ideas about what to look for, I'm open to suggestions. But I can continue my testing of the Picomite PCB with the MCP23017 plugged into the expansion PCB.
PicoMite, Armmite F4, SensorKits, MMBasic Hardware, Games, etc. on fruitoftheshed
 
Volhout
Guru

Joined: 05/03/2018
Location: Netherlands
Posts: 5091
Posted: 07:22am 18 Jul 2021
Copy link to clipboard 
Print this post

Where are the pullups? Both for encoders and i2c bus? Are the encoders optical? Differet power? 3.3v versus 5v...just some ideas. Lower capacitance, causing glitches?
PicomiteVGA PETSCII ROBOTS
 
lizby
Guru

Joined: 17/05/2016
Location: United States
Posts: 3378
Posted: 11:25am 18 Jul 2021
Copy link to clipboard 
Print this post

I2C pullups are on the MCP23017 module. There are 2 10K pullups on the encoder module, but in any case, the exact same encoder plus expansion PCB worked without issues on the F4 and CMM2, plugged into the 2x20 header.

All 3V3. The perplexing part is that it works fine with the rotary encoder when plugged into the I2C pins on the expansion header (connected to header pins 3 and 5), but not when plugged into the header which I put on the Pico board which is controlled by the same I2C pico pins (and the MCP23017 works until I turn the encoder shaft).

Thanks for the thoughts. I will continue with my testing of other 2x20 pins and see if enlightenment occurs at some point.
PicoMite, Armmite F4, SensorKits, MMBasic Hardware, Games, etc. on fruitoftheshed
 
Print this page


To reply to this topic, you need to log in.

The Back Shed's forum code is written, and hosted, in Australia.
© JAQ Software 2025