encoder reading problem
I am working on a project that uses a US digital 400ppr to measure distance and then at two preset values it puts a pin to high in order signaling a basic stamp which takes care of everything else. I am not very experienced programming at all but feel comfortable enough with the basic stamp and have the code i need for that is working. However my code for counting the encoder pulses and signaling the basic stamp does not work. For counting encoder pulses i took the code from an encoder thread listed under "the best SX threads" I kind of understand how it works but could not write it myself. I have channel A of the encoder connected to RA0 and channel B is connected to RA1. I was wondering if someone could take a quick look at this and point out my stupid mistake. A big thank you to anyone who takes the time to help a beginner.
P.S. Is there any reason not to run the sx at 50mhz? Would i have to change anything except the initializing code at the beginning? (i do know how to do that)
' BLINK1.SXB
DEVICE SX28, OSC4MHZ, TURBO, STACKX, OPTIONX
FREQ 4_000_000
EncPort VAR RA ' encoder port
TRIS_Enc VAR TRIS_A
MaxVal CON 255
EndVal Con 400
SlowVal Con 300
'encCheck VAR Byte
EncodersOld VAR byte
EncodersNew VAR byte
Encoder_A_Count VAR word
tmpB1 VAR byte
tmpB2 VAR Byte
tmpB3 VAR Byte
' =========================================================================
INTERRUPT
' =========================================================================
' Runs every 64 uS @ 4 MHz (no prescaler)
ISR_Start:
EncodersNew = EncPort
TmpB1 = EncodersOld XOR EncodersNew ' compare old with new
' to work out which channels have changed
TmpB2 = TmpB1 << 1 ' make single bit that shows change on A or B phase
TmpB1 = TmpB1 OR TmpB2
EncodersOld = EncodersOld << 1 ' make direction bits by comparing old A with new B
EncodersOld = EncodersOld XOR EncodersNew ' xor old A with new B
IF TmpB1.3 = 1 THEN
IF EncodersOld.3 = 1 THEN
INC Encoder_A_Count
ELSE
DEC Encoder_A_Count
ENDIF
ENDIF
EncodersOld=EncodersNew
'ISR_Exit:
RETURNINT
' =========================================================================
PROGRAM Start
' =========================================================================
Start:
EncodersNew = EncPort
EncodersOld = EncodersNew
Encoder_A_Count = 0
OPTION = $88 ' interrupt, no prescaler
bgn:
Do
If Encoder_A_Count >= EndVal then goto stop 'tells BS2 when to slow down and when to stop a robot
IF Encoder_A_Count >= SlowVal then goto slowdown
loop
stop:
high RC.7
slowdown:
high RC.6
goto bgn
P.S. Is there any reason not to run the sx at 50mhz? Would i have to change anything except the initializing code at the beginning? (i do know how to do that)
' BLINK1.SXB
DEVICE SX28, OSC4MHZ, TURBO, STACKX, OPTIONX
FREQ 4_000_000
EncPort VAR RA ' encoder port
TRIS_Enc VAR TRIS_A
MaxVal CON 255
EndVal Con 400
SlowVal Con 300
'encCheck VAR Byte
EncodersOld VAR byte
EncodersNew VAR byte
Encoder_A_Count VAR word
tmpB1 VAR byte
tmpB2 VAR Byte
tmpB3 VAR Byte
' =========================================================================
INTERRUPT
' =========================================================================
' Runs every 64 uS @ 4 MHz (no prescaler)
ISR_Start:
EncodersNew = EncPort
TmpB1 = EncodersOld XOR EncodersNew ' compare old with new
' to work out which channels have changed
TmpB2 = TmpB1 << 1 ' make single bit that shows change on A or B phase
TmpB1 = TmpB1 OR TmpB2
EncodersOld = EncodersOld << 1 ' make direction bits by comparing old A with new B
EncodersOld = EncodersOld XOR EncodersNew ' xor old A with new B
IF TmpB1.3 = 1 THEN
IF EncodersOld.3 = 1 THEN
INC Encoder_A_Count
ELSE
DEC Encoder_A_Count
ENDIF
ENDIF
EncodersOld=EncodersNew
'ISR_Exit:
RETURNINT
' =========================================================================
PROGRAM Start
' =========================================================================
Start:
EncodersNew = EncPort
EncodersOld = EncodersNew
Encoder_A_Count = 0
OPTION = $88 ' interrupt, no prescaler
bgn:
Do
If Encoder_A_Count >= EndVal then goto stop 'tells BS2 when to slow down and when to stop a robot
IF Encoder_A_Count >= SlowVal then goto slowdown
loop
stop:
high RC.7
slowdown:
high RC.6
goto bgn
Comments
What exactly does it do ?
What model of encoder are you using ?
Do you have any required pull-up resistors ?
How exactly do you have things connected ?
Does it act differently if you move the encoder slowly ?
You need to help us help you.
Bean.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
www.iElectronicDesigns.com
·
Also note that you will get 4 counts per cycle. So you will get 1600 counts per revolution.
Bean.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
www.iElectronicDesigns.com
·
It appears to missing a few things however. It should have:
EncodersNew = EncPort & %00000011 ' Mask off extra bits
And the calculations look a bit off.
To me it appears that your code is kind of mixed in that it expects some of th bits to be on 0 and 1 while others as bits 2 and 3.
If you are connecting the encoders to ports RA.2 and RA.3 I would used the code in the example program but start out with something like:
EncodersNew = EncPort & &00001100 ' Mask off extra bits
EncodersNew = EncodersNew >> 2 ' Shift over to perform all calculations
Hope this helps,
Robert
Bean.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
www.iElectronicDesigns.com
·
EncodersNew = EncodersNew << 2 ' Shift over to perform all calculations
EncodersNew = EncPort & &00001100 ' Mask off extra bits
There are a lot of ways to do it but it just needs to be consistent throughout the code.
DEVICE SX28, OSCHS3, TURBO, STACKX, OPTIONX
FREQ 50_000_000
ID "ENCODER"
'
' IO Pins
'
EncPort VAR RA ' encoder port
TRIS_Enc VAR TRIS_A
'
' Constants
'
MaxVal CON 100
EndVal con 17000
SlowVal con EndVal-2000
'
' Variables
'
encCheck VAR byte
encOld VAR byte ' previous encoder bits
encNew VAR byte ' new encoder bits
encValue VAR word ' encoder value
tmpB3 VAR Byte
'
INTERRUPT
'
' Runs every 64 uS @ 4 MHz (no prescaler)
ISR_Start:
encNew = EncPort & %00000011 ' get econder bits
tmpB3 = encOld XOR encNew ' test for change
IF tmpB3 > 0 THEN ' change?
encOld = encOld << 1 ' adjust old bits
encOld = encOld XOR encNew ' test direction
IF encOld.1 = 1 THEN
IF encValue < EndVal THEN ' if max, no change
INC encValue ' increase value
ENDIF
ELSE
IF encValue > 0 THEN ' if 0, no change
DEC encValue ' decrease value
ENDIF
ENDIF
encOld = encNew ' save last input
ENDIF
ISR_Exit:
RETURNINT
' =========================================================================
PROGRAM Start
' =========================================================================
'
' Subroutine Declarations
'
'
' Program Code
'
Start:
encNew = EncPort & %00000011 ' read encoder pos
encOld = encNew ' copy
encValue = 0 ' clear value
OPTION = $88 ' interrupt, no prescaler
' =========================================================================
low rc.7
main: ' clear value
Do
If encValue = EndVal then goto stop 'tells BS2 when to slow down and when to stop a robot
IF encValue = SlowVal then goto slowdown
loop
slowdown:
high RC.7
goto main
stop:
low RC.7
end