Searching \ for '[PIC]:Optical Encoder and PICs' in subject line. ()
Make payments with PayPal - it's fast, free and secure! Help us get a faster server
FAQ page: techref.massmind.org/techref/microchip/ios.htm?key=encoder
Search entire site for: 'Optical Encoder and PICs'.

Exact match. Not showing close matches.
PICList Thread
'[PIC]:Optical Encoder and PICs'
2003\04\17@082107 by Mccauley, Daniel H

flavicon
face
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

flavicon
face
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_OUTbodgy1TakeThisOuTspamoptusnet.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

flavicon
face
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

face picon face
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   .....WA1RHPKILLspamspam@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

picon face
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

picon face
> 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   WA1RHPspamKILLspamARRL.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

face picon face
> 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

flavicon
face
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

picon face
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

flavicon
face
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

flavicon
face
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                 .....nigelKILLspamspam.....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_OUTspamTakeThisOuTmitvma.mit.edu>

2003\04\21@084849 by Mccauley, Daniel H

flavicon
face
Should a basic external interrupt routine work with a single quadrature
encoder running a maximum
about 1000 per second???

Thanks
D


{Quote hidden}

--
http://www.piclist.com hint: To leave the PICList
@spam@piclist-unsubscribe-requestKILLspamspammitvma.mit.edu>

2003\04\21@093502 by Bob Ammerman

picon face
One encoder at 1000 counts per second should be easy in an interrupt driven
mode.

Bob Ammerman
RAm Systems

----- Original Message -----
From: "Mccauley, Daniel H" <KILLspamdaniel.h.mccauleyKILLspamspamLMCO.COM>
To: <RemoveMEPICLISTTakeThisOuTspamMITVMA.MIT.EDU>
Sent: Monday, April 21, 2003 8:48 AM
Subject: Re: [PIC]:Optical Encoder and PICs


> Should a basic external interrupt routine work with a single quadrature
> encoder running a maximum
> about 1000 per second???
>
> Thanks
> D

--
http://www.piclist.com hint: To leave the PICList
spamBeGonepiclist-unsubscribe-requestspamBeGonespammitvma.mit.edu>

2003\04\21@115149 by Olin Lathrop

face picon face
> 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-requestEraseMEspamspam_OUTmitvma.mit.edu>

2003\04\21@124856 by Timothy Box

flavicon
face
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-requestspamTakeThisOuTmitvma.mit.edu>

2003\04\21@131209 by Ted Larson

flavicon
face
>> 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-requestEraseMEspam.....mitvma.mit.edu>

2003\04\21@133054 by David VanHorn

flavicon
face
>
>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-requestspammitvma.mit.edu>

2003\04\21@152558 by Ned Konz

flavicon
face
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-requestEraseMEspamEraseMEmitvma.mit.edu>

2003\04\22@075628 by Mccauley, Daniel H

flavicon
face
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...