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----- From: Bob Ammerman [mailto:rammerman@ADELPHIA.NET] Sent: Friday, April 18, 2003 8:24 PM To: PICLIST@MITVMA.MIT.EDU Subject: Re: [PIC]:Optical Encoder and PICs 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 -- http://www.piclist.com hint: The PICList is archived three different ways. See http://www.piclist.com/#archives for details.