![]() |
Forum Index : Microcontroller and PC projects : Picomite: rotary encoder interrupt kills I2C
Author | Message | ||||
lizby Guru ![]() Joined: 17/05/2016 Location: United StatesPosts: 3378 |
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 StatesPosts: 3378 |
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: NetherlandsPosts: 5091 |
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 StatesPosts: 3378 |
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 |
||||
![]() |
![]() |
The Back Shed's forum code is written, and hosted, in Australia. | © JAQ Software 2025 |