Exact match. Not showing close matches.
PICList
Thread
'[PIC]:Optical Encoder and PICs'
2003\04\17@082107
by
Mccauley, Daniel H
I was wondering if anyone had experience of using an optical encoder (A and
B inputs for quadrature mode) on a PIC microcontroller.
I'd like to use the A and B output of the optical encoder and tied into
PortB and have each pulse (either on A or B) trigger an interrupt.
Any help appreciated. Thanks.
--
http://www.piclist.com hint: PICList Posts must start with ONE topic:
[PIC]:,[SX]:,[AVR]: ->uP ONLY! [EE]:,[OT]: ->Other [BUY]:,[AD]: ->Ads
2003\04\18@004622
by
cdb
|
On Thu, 17 Apr 2003 08:01:48 -0400, Mccauley, Daniel H wrote:
was wondering if anyone had experience of using an optical encoder
(A and
B inputs for quadrature mode) on a PIC microcontroller.
I'd like to use the A and B output of the optical encoder and tied
into
PortB and have each pulse (either on A or B) trigger an interrupt.
I don't with an optical version, but here is some code in 'C' that
you can play around with. See also another incarnation elsewhere in
last weeks archives, where I had a counting problem with my original
code.
//EncoderA_pin on PORTA: 1. B_pin on PORTA: 0
//This checks for the sequence 10->11 for CW pulses and 11->01 for
CCW.
void getenc()
{
if (!bRA0) //enc_B is low
old_enc_state=1; //make flag high
//we get here if both enc_B is now high and old assumed state was
high
if ((bRA0) && (old_enc_state))
{
if (bRA1) //If enc_A is now high we have gone from 10->11 in
pulses
{
enc_state=1;
old_enc_state=0; flag now low so that we have to wait for the
next 11 to come around
}
if((!bRA1) && (old_enc_state))
{
enc_state=-1;
old_enc_state=0;
}
}
else
{
enc_state=0; //here if there was no change in encoder position
}
}
Colin
--
cdb, spam_OUTbodgy1TakeThisOuT
optusnet.com.au on 18.04.2003
I have always been a few Dendrites short of an Axon and believe me it
shows.
Light travels faster than sound. That's why some people appear bright
until they speak!
--
http://www.piclist.com hint: The list server can filter out subtopics
(like ads or off topics) for you. See http://www.piclist.com/#topics
2003\04\18@194449
by
Ted Larson
I am also interested in this problem....although I have a slightly different
problem. I am a newbie to PICS, and I am attempting to design a PIC circut
for reading a shaft encoder attached to a motor, and that has a really fine
grain. I don't have a data sheet on the encoder....but when hooked up to
the scope, I am getting a 28 microsecond pulse width, with the motor turning
at the highest RPM for my application. If I don't want to miss any pulses,
I need to be sampling at a rate of about 36khz (36,000 pulses per second).
I have two motors I would like to monitor with one PIC. What I would like
to do, is have the PIC pull in the shaft data, and keep track of it, and
then deliver it over a serial line when asked for the totals. What would be
the best PIC for doing this? I want to make sure my clocking is fast enough
that there is no chance of missing a pulse.
Thanks,
- Ted
{Original Message removed}
2003\04\18@203238
by
Thomas C. Sefranek
Any PIC with an external Interrupt will do this job.
Don't sample, let the INT pin (With an Interupt service routine) do the job!
*
| __O Thomas C. Sefranek .....WA1RHPKILLspam
@spam@ARRL.NET
|_-\<,_ Amateur Radio Operator: WA1RHP
(*)/ (*) Bicycle mobile on 145.41, 448.625 MHz
hamradio.cmcorp.com/inventory/Inventory.html
http://www.harvardrepeater.org
> {Original Message removed}
2003\04\18@232711
by
Bob Ammerman
|
With careful coding in assembly, this should be quite easy to do on any
20MHz PIC with a built-in UART. Even a lowly 16F628 should be able to do the
job easily.
I would not attempt to do anything with interrupts, but rather do the whole
thing as a polling loop that runs three state machines, one for each motor,
and a third one for managing the UART communications.
I am assuming that you are using a quadrature encoder to detect motion in
both directions. In this case, you have to keep the loop time down to less
than the time between an edge on the A and B inputs, which, at 36000 pulses
per second is about 35 instruction times.
My code would look something like this. All state code is assumed to by on a
single 256 byte page so that PCLATH does not have to be touched.
Code is carefully laid out to maximize performance:
Addresses 0x000..0x0FF - initialization and utility routines
Addresses 0x100..0x13F - code for states for motor 1. Each state uses
exactly 16 words of memory
Addresses 0x140..0x17F - code for states for motor 2. Each state uses
exactly 16 words of memory
Addresses 0x180..0x1FF - code for states for UART
; The state values for motor 1 are: B'00ab0000' where 'ab' are the
previous A and B inputs
; The state values for motor 2 are: B'01ab0000' where 'ab' are the
previous A and B inputs
ABIT = 5 ; The locations of the 'a' and 'b' bits within a state
value.
BBIT = 6
; When running the state machine the new A and B inputs are merged into the
state
; before vectoring to the correct code:
;
; For motor 1: B'10abAB00' where 'ab' are the previous and 'AB' are
the new inputs
; For motor 2: B'11abAB00' where 'ab' are the previous and 'AB' are
the new inputs
;
; This results in 4 instruction words for each input possibility in each
state.
; Run the next state for motor 1
DISPATCH_M1 macro
movf PORTB,W ; [1] get inputs to machine (RB2 and RB3)
andlw 0x0C ; [2]extract
addwf m1_state,W ; [3]merge in current state
movwf PCL ; [4-5]go handle it
endm
; Run the next state for motor 2
DISPATCH_M2 macro
swapf PORTB,W ; [1]get inputs to machine (RB6 and RB7)
andlw 0x0C ; [2]extract desired bits
addwf m2_state,W ; [3]merge in current state
movwf PCL ; [4-5]go handle it
endm
; Run the next state for the UART code
DISPATCH_UART macro
movf uart_state,W ; [1]get the current state
movwf PCL ; [2-3]go to it
; helper code
increment_m1:
...
DISPATCH_M2
decrement_m1:
...
DISPATCH_M2
fault_m1:
...
DISPATCH_M2
org X'80'
; current state is (low,low)
DISPATCH_M2 ;Still (low,low)
bsf state_m1,BITB ; now (low,high)
goto increment_m1
nop
nop
bsf state_m1,BITA ; now (high,low)
goto decreent_m1
nop
nop
bsf state_m1,BITA ; now (high,high)
bsf state_m1,BITB
goto fault_m1 ; both inputs changed at once
nop
; current state is (low,high)
bcf state_m1,BITB ; now (low,low)
goto decrement_m1
nop
nop
DISPATCH_M2 ; Still (low,high)
bsf state_m1,BITA ;now (high,low)
bcf state_m1,BITB
goto fault_m1 ; both inputs changed at once
nop
bsf state_m1,BITA ; now (high,high)
goto incrment_m1
nop
nop
; current state is (high,low)
bcf state_m1,BITA ;now (low,low)
goto increment_m1
nop
nop
bcf state_m1,BITA ;now (low,high)
bsf state_m1,BITB
goto fault_m1 ; both inputs changed at once
nop
DISPATCH_M2 ; still (high,low)
bsf state_m1,BITB ;now (high,high)
goto decrement_m1
nop
nop
; current state is (high,high)
bcf state_m1,BITA ;now (low,low)
bcf state_m1,BITB
goto fault_m1 ; both inputs changed at once
nop
bcf state_m1,BITA ;now (low,high)
goto decrement_m1
nop
nop
bcf state_m1,BITB ;now (high,low)
goto increment_m1
nop
nop
DISPATCH_M2 ; still (high,high)
You'd have to keep the worst case loop time down to less than the minimum
differential betwen two edges.
Bob Ammerman
RAm Systems
--
http://www.piclist.com hint: The list server can filter out subtopics
(like ads or off topics) for you. See http://www.piclist.com/#topics
2003\04\18@233330
by
Bob Ammerman
> Any PIC with an external Interrupt will do this job.
> Don't sample, let the INT pin (With an Interupt service routine) do the
job!
>
> *
> | __O Thomas C. Sefranek WA1RHP
KILLspamARRL.NET
> |_-\<,_ Amateur Radio Operator: WA1RHP
> (*)/ (*) Bicycle mobile on 145.41, 448.625 MHz
>
Not at 36000 per second, especially if this is two quadrature encoders!
Bob Ammerman
RAm Systems
--
http://www.piclist.com hint: The list server can filter out subtopics
(like ads or off topics) for you. See http://www.piclist.com/#topics
2003\04\19@080249
by
Olin Lathrop
> I am also interested in this problem....although I have a slightly
> different problem. I am a newbie to PICS, and I am attempting to design
> a PIC circut for reading a shaft encoder attached to a motor, and that
> has a really fine grain. I don't have a data sheet on the
> encoder....but when hooked up to the scope, I am getting a 28
> microsecond pulse width, with the motor turning at the highest RPM for
> my application.
Is this a single pulse line, or two quadrature lines? In other words, do
you need to figure out the motor direction on the fly, or is that already
known?
In the latter case, what is the minmum pulse period, not just the pulse
width? You only need to catch one edge per cycle, giving you the whole
period for processing instead of just the pulse width. Even if it were
28uS period, that still gives you 280 instructions on an 18 PIC running at
40MHz. That's plenty to track the motor position, but whether that's good
enough depends on what else the PIC has to do and how it has to
communicate the motor position to elsewhere.
> If I don't want to miss any pulses, I need to be
> sampling at a rate of about 36khz (36,000 pulses per second).
I wouldn't "sample" the motor lines. If these are single pulse lines per
motor, then just feed them into 2 of the 3 INT interrupts of a PIC18.
*****************************************************************
Embed Inc, embedded system specialists in Littleton Massachusetts
(978) 742-9014, http://www.embedinc.com
--
http://www.piclist.com hint: The PICList is archived three different
ways. See http://www.piclist.com/#archives for details.
2003\04\19@151636
by
Ted Larson
Thanks Bob! This is super. Love the code sample!
I was thinking about using a 20mhz 16F84A because I got a free one with my
PICStart Plus programmer. I wasn't planning on doing full-blown RS-232. I
was just going to do some simple 1-pin, TTL, serial, signaling. I was going
to send the data to a basic-stamp. Later on, as I get better at this PIC
stuff, I can toss the stamp and save $50. A stamp is just not fast enough
to watch 36k ticks per second, so I figured I could offload the time
senstive stuff to a PIC.
Now...my understanding is that the only major difference between the 16F84
and the 16F628 is less ports, no UART, and no PWM. Am I going to shoot
myself in the foot trying to use the F84 for this?
Thanks,
- Ted
{Original Message removed}
2003\04\19@195142
by
Bob Ammerman
Yeah,
Use the '628 -- The UART will greatly reduce the number of cycles needed to
handle communications. Without it you might not be able to maintain the high
datarate.
Bob Ammerman
RAm Systems
{Original Message removed}
2003\04\20@040611
by
Timothy Box
Hi
I did a DRO project for a friend that used an encoder. I was written for the
18 series PICs using the hi priority interrupts.
Each change of the encoder took about 34 instructions to inc / dec a counter
and provide a + / -, and error flag.
The maths says that at 40 mhz that = 10,000,000 instructions per second / 34
(per change) = over 294,000 encoder changes per second.
Even if you wrote the code in a high level language you should be able to
cope with a "sampling at a rate of about 36khz"
Tim
{Original Message removed}
2003\04\21@040233
by
Nigel Orr
|
pic microcontroller discussion list <> wrote on Saturday, April 19, 2003
8:07 PM:
> Now...my understanding is that the only major difference between the
> 16F84 and the 16F628 is less ports, no UART, and no PWM. Am I going
> to shoot myself in the foot trying to use the F84 for this?
The USART is a BIG time-saver, in development time and in the amount of
time you need to dedicate to bit-banging otherwise.
Probably the biggest other change between the 16f84 and '628 in your
application is that that the '628 has comparator inputs, and you need
to disable them to use the PORTA pins 'normally'. I usually use
movlw 0x15 ;
movwf CMCON ;
(The first line is from memory, check on the datasheet comparator section
to verify that is a setup for all digital I/O!)
You also need to check your __config settings, particularly MCLR enable and
the oscillator selection (the '628 has additional oscillator options,
including
a very useful internal 4MHz RC oscillator)
HTH,
Nigel
--
Nigel Orr, Design Engineer .....nigelKILLspam
.....axoninstruments.co.uk
Axon Instruments Ltd., Wardes Road,Inverurie,Aberdeenshire,UK,AB51 3TT
Tel:+44 1467 622332 Fax:+44 1467 625235
http://www.axoninstruments.co.uk
--
http://www.piclist.com hint: To leave the PICList
EraseMEpiclist-unsubscribe-requestspam_OUT
TakeThisOuTmitvma.mit.edu
>
2003\04\21@084849
by
Mccauley, Daniel H
2003\04\21@093502
by
Bob Ammerman
2003\04\21@115149
by
Olin Lathrop
> Should a basic external interrupt routine work with a single quadrature
> encoder running a maximum
> about 1000 per second???
1000 quadrature cycles per second means 4000 edges per second, or one edge
every 250uS on average. A 20MHz PIC has a 200nS instruction cycle time,
and can therefore do 250uS / 200nS = 1250 instructions per edge. That's
much more than needed to update a counter with the current shaft position,
and will leave most of the processor available to process the result, send
it elsewhere, or whatever.
Note that you don't actually need to take an interrupt on all 4 edges in a
quadrature cycle if you don't need "4x" resolution. You could interrupt
on both edges of one signal, then check the state of the other signal to
determine the direction of the step. This requires 2000 interrupts per
second and gets you "2x" resolution.
There are also dedicated quadrature decoder/counter chips if you need
speed that a microcontroller can't handle.
*****************************************************************
Embed Inc, embedded system specialists in Littleton Massachusetts
(978) 742-9014, http://www.embedinc.com
--
http://www.piclist.com hint: To leave the PICList
TakeThisOuTpiclist-unsubscribe-requestEraseME
spam_OUTmitvma.mit.edu
>
2003\04\21@124856
by
Timothy Box
|
Just though this might save you some work
ENCODER_INT_HANDLER
CLRWDT ; HIT THE
DOG
MOVF PORTB, W ; GET THE
NEW ENCODER DATA
MOVWF NEW_ENCDR ; SAVE IT
RRNCF OLD_ENCDR ; ROTATE OLD
DATA INTO POSITION
XORWF OLD_ENCDR, F ; XOR TO GET
DIRECTION
BTFSC OLD_ENCDR,4 ; WHICH
DIRECTION DID IT GO IN?
BRA CLOCKWISE ; CLOCKWISE
COUNTERCLOCKWISE ; COUNTER
CLOCKWISE
...
....
INT_EXIT
MOVF NEW_ENCDR, W
MOVWF OLD_ENCDR ; SAVE NEW
ENCODER DATA TO OLD DATA
CPFSEQ PORTB
BRA ENCODER_ERROR
BCF INTCON,0 ; CLEAR
CHANGE ON PORT B INTERRUPT FLAG
RETFIE FAST
ENCODER_ERROR
BSF ERROR
BCF INTCON,0 ; CLEAR
CHANGE ON PORT B INTERRUPT FLAG
RETFIE FAST
Ive forgotten were A and B were connected to 4&5 I think. I've not included
the counting code which is fairly easy.
Set up int as change on PORTB (you have to do this or it will not work)
18series only
Tim
I was wondering if anyone had experience of using an optical encoder (A and
B inputs for quadrature mode) on a PIC microcontroller.
I'd like to use the A and B output of the optical encoder and tied into
PortB and have each pulse (either on A or B) trigger an interrupt.
Any help appreciated. Thanks.
--
http://www.piclist.com hint: PICList Posts must start with ONE topic:
[PIC]:,[SX]:,[AVR]: ->uP ONLY! [EE]:,[OT]: ->Other [BUY]:,[AD]: ->Ads
--
http://www.piclist.com hint: To leave the PICList
RemoveMEpiclist-unsubscribe-request
TakeThisOuTmitvma.mit.edu
>
2003\04\21@131209
by
Ted Larson
>> Should a basic external interrupt routine work with a single quadrature
>> encoder running a maximum
>> about 1000 per second???
>
>1000 quadrature cycles per second means 4000 edges per second, or one edge
>every 250uS on average. A 20MHz PIC has a 200nS instruction cycle time,
>and can therefore do 250uS / 200nS = 1250 instructions per edge. That's
>much more than needed to update a counter with the current shaft position,
>and will leave most of the processor available to process the result, send
>it elsewhere, or whatever.
The problem I ran into is that I have 36,000 edges per second, or one
roughly every 28uS...this only gives me 140 instructions per edge. Plus I
want to monitor 2 encoders, so that means I only get 70 instructions to
decode each, plus deal with any other processing I want to do.
- Ted
--
http://www.piclist.com hint: To leave the PICList
piclist-unsubscribe-requestEraseME
.....mitvma.mit.edu
>
2003\04\21@133054
by
David VanHorn
>
>The problem I ran into is that I have 36,000 edges per second, or one
>roughly every 28uS...this only gives me 140 instructions per edge. Plus I
>want to monitor 2 encoders, so that means I only get 70 instructions to
>decode each, plus deal with any other processing I want to do.
Hmm.. A radical might suggest an AVR processor. 64nS typical instruction at 16 MHz, vectored ints.
--
http://www.piclist.com hint: To leave the PICList
EraseMEpiclist-unsubscribe-request
mitvma.mit.edu
>
2003\04\21@152558
by
Ned Konz
|
On Monday 21 April 2003 10:03 am, Ted Larson wrote:
> >> Should a basic external interrupt routine work with a single
> >> quadrature encoder running a maximum
> >> about 1000 per second???
> >
> >1000 quadrature cycles per second means 4000 edges per second, or
> > one edge every 250uS on average. A 20MHz PIC has a 200nS
> > instruction cycle time, and can therefore do 250uS / 200nS = 1250
> > instructions per edge. That's much more than needed to update a
> > counter with the current shaft position, and will leave most of
> > the processor available to process the result, send it elsewhere,
> > or whatever.
>
> The problem I ran into is that I have 36,000 edges per second, or
> one roughly every 28uS...this only gives me 140 instructions per
> edge. Plus I want to monitor 2 encoders, so that means I only get
> 70 instructions to decode each, plus deal with any other processing
> I want to do.
Assuming you're using the 18F parts, you can cut down significantly on
the interrupt overhead for the fast interrupt. There have been some
bugs having to do with mixing fast and normal interrupts, though;
it's probably safer to make everything a fast interrupt.
Plus you can run these up to 40 MHz (assuming you have recent
silicon).
--
Ned Konz
http://bike-nomad.com
GPG key ID: BEEA7EFE
--
http://www.piclist.com hint: To leave the PICList
RemoveMEpiclist-unsubscribe-requestEraseME
EraseMEmitvma.mit.edu
>
2003\04\22@075628
by
Mccauley, Daniel H
Just wanted to thank everyone for their great help and advice regarding
Optical Encoders.
Thanks!
D
--
http://www.piclist.com hint: PICList Posts must start with ONE topic:
[PIC]:,[SX]:,[AVR]: ->uP ONLY! [EE]:,[OT]: ->Other [BUY]:,[AD]: ->Ads
More... (looser matching)
- Last day of these posts
- In 2003
, 2004 only
- Today
- New search...