Using the Encoder Sample
SailerMan
Posts: 337
I used the encoder sample and attached it to Two US Digital· Optical Encoders.. Everything works as expected with the following code which is the sample code that came with the SX/B Software.. I striped the LCD Code and the non Essentials and made it work for two seperate encoders.. I some what understand the code, but was wondering if there was a way to make this code more efficient.· Take a Look.. Oh yeah I am out putting the Encoder counts to a 74HC595.
Thanks for anyhelp.
And then What I am looking for is to be able to read this information from a Stamp or Propeller.. What would be the best way. Serial Output??
Regards,
Eric
DEVICE SX28, OSC4MHZ, TURBO, STACKX, OPTIONX FREQ 4_000_000,4_480_000 ID "ENCODER"
EncPort VAR RA ' encoder port TRIS_Enc VAR TRIS_A
MaxVal CON 255
'encCheck VAR Byte Encoder_A_Old VAR Byte Encoder_A_New VAR Byte Encoder_A_Count VAR byte Encoder_B_Old VAR Byte Encoder_B_New VAR Byte Encoder_B_Count VAR byte
tmpB1 VAR Byte tmpB2 VAR Byte tmpB3 VAR Byte
' ========================================================================= INTERRUPT ' =========================================================================
' Runs every 64 uS @ 4 MHz (no prescaler)
ISR_Start: Encoder_A_New = EncPort & %00001100 TmpB3 = Encoder_A_Old XOR Encoder_A_New IF tmpB3 > 0 THEN Encoder_A_Old = Encoder_A_Old << 1 Encoder_A_Old = Encoder_A_Old XOR Encoder_A_New IF Encoder_A_Old.3 = 1 THEN INC Encoder_A_Count ELSE DEC Encoder_A_Count ENDIF Encoder_A_Old = Encoder_A_New ENDIF Encoder_B_New = EncPort & %00000011 TmpB3 = Encoder_B_Old XOR Encoder_B_New ' ========================================================================= IF tmpB3 > 0 THEN Encoder_B_Old = Encoder_B_Old << 1 Encoder_B_Old = Encoder_B_Old XOR Encoder_B_New IF Encoder_B_Old.1 = 1 THEN INC Encoder_B_Count ELSE DEC Encoder_B_Count ENDIF Encoder_B_Old = Encoder_B_New ENDIF 'ISR_Exit: RETURNINT
' ========================================================================= PROGRAM Start ' =========================================================================
Start: Encoder_A_New = EncPort & %00001100 Encoder_A_Old = Encoder_A_New Encoder_A_Count = 0 Encoder_B_New = EncPort & %00000011 Encoder_B_Old = Encoder_B_New ' copy Encoder_B_Count = 0 OPTION = $88 ' interrupt, no prescaler
Main: DO ShiftOut RC.7,RC.6,1,Encoder_A_Count Pulsout RC.0,1 ShiftOut RC.7,RC.6,1,Encoder_B_Count Pulsout RC.0,1 LOOP
END
Thanks for anyhelp.
And then What I am looking for is to be able to read this information from a Stamp or Propeller.. What would be the best way. Serial Output??
Regards,
Eric
Comments
The best way is to forget the 74HC595, and keep it all inside the SX or Propeller. Why would you need to send it out, only to retrieve it again ??
Cheers,
Peter (pjv)
Post Edited (SailerMan) : 10/5/2006 12:12:38 PM GMT
This saves a couple bytes, at the cost of·using a second temp in the interrupt. Since you have both encoders on the same port, there is no reason you can't save both channels in one oldbyte and save space.· You can also do the shifting and xoring of both channels at the same time, since you only look at one bit of the results to determine direction.
This also lends itself to extension to 4 channels on one 8 bit port, by adding the appropriate bit tests for additional channels.· Or make the thing a loop with a bit mask to test the change and direction bits·and increment or decrement the positions in an array.
[/code][/size]
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
MRC
Thanks for any help.
Eric
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
MRC
Post Edited (Michael Chadwick) : 10/6/2006 5:42:11 PM GMT
Nice explanation, but I believe bits 3 and 2 of the "XOR" line in the first sequence you posted are reversed.
Cheers,
Peter (pjv)
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
MRC
I ran into variable space limits.
Is there any way to process that many encoders with a single sx? I am I running into territory that would be eaiser if I went with a PROPELLER?
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Meh. Nothing here, move along.
The SX can easily read 6 encoders. Not a problem. Not an issue. Piece of cake. The fact that you tried to modify some existing code and ran into problems in no way changes the ability of the SX to do the job.
I have no idea how you modified the code since no code was posted, but it's quite likely an erroneous or inefficient modification that is causing you problems.
Thanks,
PeterM
The problem I ran into is that when all is said and done, you have too many variables.
I thought about some method of data storage, but don't see how that is different from declaring variables.
I might be able to eliminate 6 variables, but I don't see any way to do more.
I think the problem is, I need to maintain a WORD cound for every encoder.
thats six word variables. on Top of everything else.
Right now its set up for 3 encoders. If I add 1 more byte variable I am over my ram.
My fear isn't that it can't be done, unless done in a way that removes the simplicity of sxb.
I would prefer to keep it fairly simple. And am not going to bother with assembly.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Meh. Nothing here, move along.
I’m using a mechanical encoder and battling with debouncing the input. This approach will solve the problem. I was using a complex If-ElseIf routine with a flag but occasionally the encoder will count 1 byte backwards when turned clockwise (and visa versa). The problem is that while the contact bounce is usually under 100ns, it’s occasionally over 30ms (30X). Set the debounce for 50ms and you can’t spin the encoder fast, set the debounce for 10ms and the miss-counting occasionally occurs.
If I use this routine, contact bounce won’t matter and I’ll get much faster code.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔