Hi,
I am looking at a quadrature encoder, I wondered if anyone has an example before I spend too much time looking.
Regards,
Bob
hope this help you
From Les for 18F25k22
https://protoncompiler.com/index.php/topic,290.0.html
Here is one. Uses IOC interupt and reads two encoders.
' -------------------------------------------------------------
' Name : Quadrature.BAS
' Author : Flosi Guðmundssn
' Notice : Copyright (c) 2017 Flosi Guðmundsson
' : All Rights Reserved
' Date : 2.4.2017
' Version : 1.0
' Notes : Interrupt on Change is used to read two quadrature
' : encoders and increment counter. Mainloop sends
' : result serially over Bluetooth to TouchDRO app.
' -------------------------------------------------------------
Device 18F26K22
Declare Xtal 80
Symbol PLLEN = OSCTUNE.6 ' PLL enable
Symbol PLLRDY = OSCCON2.7 ' PLL run status
PLLEN=1 ' Enable PLL 4x 16MHz = 64Mhz
While PLLRDY=0:Wend ' Wait until PLL is stable
' Include "18f26k22intosc64.Inc"
Declare Hserial_Baud = 115200
Declare Reminders = Off
' Declare Optimiser_Level 3
Declare Dead_Code_Remove = On
On_Hardware_Interrupt Interrupt_handler
TRISA = %00000000
TRISB = %11110011 ' Quadrature inputs, Int0, Int1
TRISC = %00000000
Symbol GIE = INTCON.7 ' Global Interrupt Enable
Symbol PEIE = INTCON.6 ' Periferal Interrupt Enable
Symbol IPEN = RCON.7 ' Interrupt Priorty Enable
Dim wFSR1 As FSR1L.Word ' Used for look up table
' Setup for Interrupt On Change for PortB 6-7
' ----------------------------------------------------------------------------
Symbol RBIF = INTCON.0
Symbol RBIE = INTCON.3
' Setup for Int0
' ----------------------------------------------------------------------------
Symbol INT0F = INTCON.1
Symbol INT0IE = INTCON.4
Symbol INTEDG0 = INTCON2.6
' Setup for Int1
' ----------------------------------------------------------------------------
Symbol INT1F = INTCON3.0
Symbol INT1IE = INTCON3.3
Symbol INTEDG1 = INTCON2.5
' PortB pullups
' ------------------------------------------------------------------------
Symbol NOT_RBPU = INTCON2.7
IOCB = $F0 ' PortB 7-4 used
NOT_RBPU = 0 ' PortB pullups on
' Enable interrupts
' ----------------------------------------------------------------------------
IPEN = 0 ' Interrupt priority OFF
GIE = 1 ' Global Interrupt enable
PEIE = 1 ' Enable peripheral enable
INT0IE = 1 ' Int0 Interrupt Enable
INT1IE = 1 ' Int1 Interrupt Enable
RBIE = 1 ' PortB Interrupt Enable
'
' Look up table for incrementing or decrementing the counter
' and pointer to look up table
' ----------------------------------------------------------------------------
Dim tLookUp[16] As SByte = 0,-1,1,2,1,0,2,-1,-1,2,0,1,2,1,-1,0
wFSR1 = VarPtr tLookUp
Dim bNewX As Byte
Dim bNewZ As Byte
Dim bOldX As Byte
Dim bOldZ As Byte
Dim swCntX As SWord ' values to increment/decrement
Dim swCntZ As SWord
Dim sbInc As SByte ' value of increment,0,1,-1
' Dim bTmp As Byte
Dim fCntReady As Bit
swCntX = 0
swCntZ = 0
While 1 = 1
While fCntReady = 0 : Wend
fCntReady = 0
HRSOut "x",SDec swCntX,";","Z",SDec swCntZ,";",10
Wend
Interrupt_handler:
Context Save
If RBIF = 1 Then ' On RBIF interrupt
RBIF = 0
Swapf PORTB,WREG ' WREG 3-0 = PORTB 7-4
bNewZ = WREG
bNewX = WREG & 3 ' bNewX = PortB 4,5
Ror bNewZ
Ror bNewZ
bNewZ = bNewZ & 3 ' bNewZ = PortB 6,7
If bNewX <> bOldX Then
bOldX = bOldX * 4
WREG = bOldX + bNewX ' Index to table
sbInc = PLUSW1 ' Get element
bOldX = bNewX ' update old value
swCntX = swCntX + sbInc ' change count
Set fCntReady
EndIf
If bNewZ <> bOldZ Then
bOldZ = bOldZ * 4
WREG = bOldZ + bNewZ ' Index to table
swCntZ = swCntZ + PLUSW1
sbInc = PLUSW1 ' Get element
bOldZ = bNewZ ' update old value
swCntZ = swCntZ + sbInc ' change count
Set fCntReady
EndIf
RBIF=0
EndIf
If INT0F=1 Then ' Push button X to clear
INT0F=0
swCntX = 0
Set fCntReady
EndIf
If INT1F=1 Then ' Push button Z to clear
INT1F=0
swCntZ = 0
Set fCntReady
EndIf
Context Restore
Hi Basiclover,
I have got Les's code working but wondered if there will be an issue if the PIC has a lot to do. It is running on a PIC24 at 80mhz so probably not an issue?
Hi Flosigud,
I will have a look at your code later as it would be nice to have both options.
Regards,
Bob
@ RGV250
Good news that LES's code works for you. I think a faster pic would be rather a benefit
I'am interested in your findings about rotary encoders.I assume you didn't forget the debouncing RC on the 2 pins
My program was written with speed in mind on 18f25k22. It would need major rewrite to work on 24f.Some 16 bit PICs have hardware encoders that should be fast enough.
Hi,
I haven't put the caps in as it will be difficult due to the board design, I will keep an eye on it and see if I need it but so far so good using the serial port to show the count and direction. I am only thinking of menu's and things like that so probably not a great issue if it does miss a step.
I did wonder if it would be possible to modify for the 24HJ, the one I have does not have hardware encoders, at least I have the basis to work on if it is possible to change. It will be good to get into PIC24 interrupts as I have only just started with them really.
Bob