[QUOTE=HenrikOlsson;155986]You have turned off the WDT (for speed I suppose) but forgot to tell PBP about it so no speed gained.
You're assuming I know what I'm doing.
I didn't think I'd need WDT, until someone tells me I should use it.![]()
[QUOTE=HenrikOlsson;155986]You have turned off the WDT (for speed I suppose) but forgot to tell PBP about it so no speed gained.
You're assuming I know what I'm doing.
I didn't think I'd need WDT, until someone tells me I should use it.![]()
My Creality Ender 3 S1 Plus is a giant paperweight that can't even be used as a boat anchor, cause I'd be fined for polluting our waterways with electronic devices.
Not as dumb as yesterday, but stupider than tomorrow!
Henrik, maybe a video would be helpful. 1st half is with a encoder with 30detents/15pulses, 2nd half is 20detents (I don't have datasheet for that one, no idea how many pulses).
That rocker switch selects logic; mine is first in video, yours is 2nd when switch is rocked to the right.
My code with combined logic. I added a switch and moved LCDOUT into a subroutine to keep the code clean:
Code:goto Start ;--- Subroutines --------------------------------------------------------------- LCDoutput: LCDOUT $FE, $D4, "C:", dec5 Enc1_counter,_ " A:", DEC1 Enc1_WiperA,_ " B:", DEC1 Enc1_WiperB,_ " SW:", DEC1 Enc1_SPST : Pauseus 1 Return Start: Pause 500 ' Let PIC and LCD stabilize LCDOUT $FE, 1 : Pauseus 1 LCDOUT $FE, $80, "ROTARY ENCODER TEST" : Pauseus 1 Mainloop: BlinkLED1 = 1 ' Top of LOOP on Logic 2 probe if logicselector = 1 then goto MyLogic ' Wiper Chart: ' ============ ' A B ' --- --- ' 0 0 ' 1 0 /\ CCW ' 1 1 ' 0 1 \/ CW ' 0 0 ' ' Careful, EC11 30 detents 15 pulses will move from 00 to 11 ' EC11 20 detents can move from 00 back to 00 in one click New_Encoder = PortA & %00000011 ' Read encoder signals on RA0 and RA1 Test = New_Encoder ^ Old_Encoder ' Bitwise XOR current state with previous state to see if any pins changed. IF Test.0 = 1 THEN ' Edge detected on channel A? IF Old_Encoder.0 ^ Old_Encoder.1 THEN ' If Old_Encoder is 0 or 3 we count up, otherwise we count down. Enc1_counter = Enc1_counter + 1 ELSE Enc1_counter = Enc1_counter - 1 ENDIF BlinkLED1 = 0 ' Bottom of IFs on Logic 2 probe GOSUB LCDoutput GOTO MainLoop ENDIF IF Test.1 = 1 THEN ' Edge detected on channel B? IF Old_Encoder.0 ^/ Old_Encoder.1 THEN ' If Old_Encoder is 1 or 2 we count up, otherwise we count down. Enc1_counter = Enc1_counter + 1 ELSE Enc1_counter = Enc1_counter - 1 ENDIF BlinkLED1 = 0 ' Bottom of IFs on Logic 2 probe GOSUB LCDoutput Goto MainLoop ENDIF BlinkLED1 = 0 ' Bottom of IFs on Logic 2 probe GOSUB LCDoutput goto mainloop MyLogic: if Enc1_WiperA = 0 and Enc1_WiperB = 0 then ' See wiper chart above if Enc1_previous = 01 then ' 2 digits to follow chart better Enc1_direction = 1 ' 1=CW, 0=CCW Enc1_rotation = 1 ' Motion occurred else if Enc1_previous = 10 then Enc1_direction = 0 ' 0=CCW Enc1_rotation = 1 ' Motion occurred else Enc1_direction = 0 ' Not relevant without motion Enc1_rotation = 0 ' No motion occurred endif endif Enc1_previous = 00 ' Save wiper position endif if Enc1_WiperA = 1 and Enc1_WiperB = 0 then if Enc1_previous = 00 then Enc1_direction = 1 Enc1_rotation = 1 else if Enc1_previous = 11 then Enc1_direction = 0 Enc1_rotation = 1 else Enc1_direction = 0 Enc1_rotation = 0 endif endif Enc1_previous = 10 endif if Enc1_WiperA = 1 and Enc1_WiperB = 1 then if Enc1_previous = 10 then Enc1_direction = 1 Enc1_rotation = 1 else if Enc1_previous = 01 then Enc1_direction = 0 Enc1_rotation = 1 else Enc1_direction = 0 Enc1_rotation = 0 endif endif Enc1_previous = 11 endif if Enc1_WiperA = 0 and Enc1_WiperB = 1 then if Enc1_previous = 11 then Enc1_direction = 1 Enc1_rotation = 1 else if Enc1_previous = 00 then Enc1_direction = 0 Enc1_rotation = 1 else Enc1_direction = 0 Enc1_rotation = 0 endif endif Enc1_previous = 01 endif if Enc1_rotation = 1 then if (Enc1_WiperA = 0 and Enc1_WiperB = 0) or _ (Enc1_WiperA = 1 and Enc1_WiperB = 1) then if Enc1_direction = 1 then Enc1_counter = Enc1_counter + 1 ' Turned 1 position CW else if Enc1_counter > 0 then Enc1_counter = Enc1_counter - 1 ' Turned 1 position CCW endif endif endif endif GOSUB LCDoutput goto mainloop
Last edited by Demon; - 20th August 2024 at 00:14.
My Creality Ender 3 S1 Plus is a giant paperweight that can't even be used as a boat anchor, cause I'd be fined for polluting our waterways with electronic devices.
Not as dumb as yesterday, but stupider than tomorrow!
Henrik, inspired by your code. I got down to 6.4 - 8.6us:
Goes in initialization section:
MainLoop:Code:Enc1_previous = %11111111 Enc1_Current = %00000000 Enc1_counter = 0
Code:MyLogic: Enc1_Current = (Enc1_WiperA << 1) + Enc1_WiperB IF Enc1_Current != Enc1_Previous THEN IF Enc1_Current = %00000011 THEN IF Enc1_Previous = %00000010 THEN Enc1_counter = Enc1_counter + 1 ELSE IF Enc1_Previous = %00000001 THEN Enc1_counter = Enc1_counter - 1 ENDIF ENDIF ELSE IF Enc1_Current = %00000000 THEN IF Enc1_Previous = %00000001 THEN Enc1_counter = Enc1_counter + 1 ELSE IF Enc1_Previous = %00000010 THEN Enc1_counter = Enc1_counter - 1 ENDIF ENDIF ENDIF ENDIF ENDIF Enc1_Previous = Enc1_Current BlinkLED1 = 0 ' Bottom of IFs on Logic 2 probe GOSUB LCDoutput goto mainloop
Since my encoder doesn't stop on 01 or 10, I only need to check 11 and 00. Already 3 times faster than my original.
EDIT: Updated times
![]()
Last edited by Demon; - 20th August 2024 at 01:36.
My Creality Ender 3 S1 Plus is a giant paperweight that can't even be used as a boat anchor, cause I'd be fined for polluting our waterways with electronic devices.
Not as dumb as yesterday, but stupider than tomorrow!
I use that code with an optical encoder to convert from quartature to up/down pulses and it tracks the encoder perfectly to >200k edges per second. I modified it to incorporate your counter but I might have messed something up.
It might not have a detent at every quadrature state but it sure must "go thru" them.Since my encoder doesn't stop on 01 or 10, I only need to check 11 and 00. Already 3 times faster than my original.
If you are at 00 and go to 11, which direction did it turn? There's no way to know unless also decoding the 10/01 states in between the detents - and you are doing that.
Also, don't forget that your LCDoutput subroutine takes considerable amount of time, you can not allow the encoder to pass thru two (or more) states without reading it or it WILL miss pulses or even count backwards.
Take your logic analyzer capture and measure the time between the rising edges of channel A and B respectively.
The pulsewidth of channel A is 11ms but the time between the edges on A and B is much shorter than 5.5ms due to the fact that the phase shift is far from 90° on your encoder. Lets say it's 2ms... How long does your LCDoutput subroutine take?
Yeah, that's what I thought. We're not using the exact same device. I noticed such irregularities when I was switching between my own encoders (2 different batches).I use that code with an optical encoder to convert from quartature to up/down pulses and it tracks the encoder perfectly to >200k edges per second.
Oh definitely. I even see them display on the LCD when I turn my encoder REAL slow.It might not have a detent at every quadrature state but it sure must "go thru" them.
Yup, that's why I check the Current state against the Previous state. I only increase/decrease my counter on 00 and 11, cause that's where the encoder has a physical detent. A user turning the knob doesn't care about intermediate steps; only that the device actuates by one position when the knob goes click.If you are at 00 and go to 11, which direction did it turn? There's no way to know unless also decoding the 10/01 states in between the detents - and you are doing that.
The fastest interval between wiper A and B is on a drop, and it's 3.88msTake your logic analyzer capture and measure the time between the rising edges of channel A and B respectively.
The pulsewidth of channel A is 11ms but the time between the edges on A and B is much shorter than 5.5ms due to the fact that the phase shift is far from 90° on your encoder. Lets say it's 2ms...
~1.92msHow long does your LCDoutput subroutine take?
Note that the final product will use a dedicated PIC to display data on LCDs, and a separate PIC to process incoming encoder signals.
I'm only using the LCD alongside the encoder to help me understand how the encoder is behaving.
My Creality Ender 3 S1 Plus is a giant paperweight that can't even be used as a boat anchor, cause I'd be fined for polluting our waterways with electronic devices.
Not as dumb as yesterday, but stupider than tomorrow!
It might not have a detent at every quadrature state but it sure must "go thru" them.Oh definitely. I even see them display on the LCD when I turn my encoder REAL slow.
That's why I had put this comment in my code, to show the CW/CCW progression through the wiper states:
Code:' Wiper Chart: ' ============ ' A B ' --- --- ' 0 0 ' 1 0 /\ CCW ' 1 1 ' 0 1 \/ CW ' 0 0 ' ' Careful, EC11 30 detents 15 pulses will move from 00 to 11 ' EC11 20 detents can move from 00 back to 00 in one click
No wonder my older EC11 were causing me so much grief in my initial testing.![]()
My Creality Ender 3 S1 Plus is a giant paperweight that can't even be used as a boat anchor, cause I'd be fined for polluting our waterways with electronic devices.
Not as dumb as yesterday, but stupider than tomorrow!
Here's one of my faster ones:
A is 15.22ms duration
Difference between rise of A and B is 3.50ms
I nearly had time to send LCDOUT twice.
I'm more than satisfied with what I have so far as encoder logic. When I remove LCDOUT, this is how many times the encoder logic can cycle during a fast pulse; a gazillion.
I'm thrilled actually; with a big smile on my face as I type this.![]()
My Creality Ender 3 S1 Plus is a giant paperweight that can't even be used as a boat anchor, cause I'd be fined for polluting our waterways with electronic devices.
Not as dumb as yesterday, but stupider than tomorrow!
Bookmarks