At 00:25 6/10/99 +0200, you wrote: >Hej a b. Tack fšr ditt meddelande 13:44 1999-10-05 -0700 enligt nedan: >>Hello Picers..., >> >>Can anybody tell me how to read out a Rotary encoder with a pic (16f84)?? > >There was recently a thread about this! >Subject "Quadrature incremental pot decoding on PIC" >Search the Piclist archive... I forgot where it is... > >.. Is there an up to date piclist archive? >Where? > > >goto table method: >(Probably have (IMHO) the shortest max process time, but not smallest code) > >First get two phase bits into the same byte as the old ones, by rotating them left into the storebyte position 0 and 1. The phase bits from previous time this routine was called is now in bit 2 and 3, and the now new bits will be used as old next time. (Also, earlier input states is now in bit 4:5 and 6:7, but whatfor?) : Total 8 cycles >Then use theese four bits to telll what have happened: > movf storebyte, W ;1 cycle > andlw b'1111' ;1 cycle > addwf PCL ,f ;2 cycles + 2 cycles for the goto selected in table > ;Change Old New > goto isrBchange_NO ; 0 0 0 0 > goto isrBchange_UP ; 0 0 0 1 > goto isrBchange_DN ; 0 0 1 0 > goto isrBchange_ERR ; 0 0 1 1 > > goto isrBchange_DN ; 0 1 0 0 > goto isrBchange_NO ; 0 1 0 1 > goto isrBchange_ERR ; 0 1 1 0 > goto isrBchange_UP ; 0 1 1 1 > > goto isrBchange_UP ; 1 0 0 0 > goto isrBchange_ERR ; 1 0 0 1 > goto isrBchange_NO ; 1 0 1 0 > goto isrBchange_DN ; 1 0 1 1 > > goto isrBchange_ERR ; 1 1 0 0 > goto isrBchange_DN ; 1 1 0 1 > goto isrBchange_UP ; 1 1 1 0 > goto isrBchange_NO ; 1 1 1 1 > > >Timing is total 14 cycles, isosynchronous, including goto appropriate routine (count up/down/error/nochange) > >Then make ypur own routines, i.e >isrBchange_DN for counting down your variable, etc > >The decode routine can be driven by interrupt on change on port B, or you can call it regularly to poll signals if interrupt on change is not available. > >Regards >/Morgan > This routine has the problem in that all possible changes of state for the same direction produce a GOTO to the same routine, the function still needs to know when a full cycle has been completed i.e. One full revolution, this may be done by running a counter. Also the routine must see all chages of state else an error is encounted. On a quadrature cycle only looking for a complete rotation, the software only needs to check one line. I hae included a high level respone to this, the code produced is not very efficent and you can clean it up to make it faster, just done so that people can see what I am on about unsigned char uc_Quadrature_check (unsigned char uc_do_what) { /* ---------------------------------------------------------------------------- --------- WARNING Non portable function, remove bit vars Quadrature encoder check for full cycle ---------------------------------------------------------------------------- --------- */ static unsignedbit last_sine; /*bit values*/ static unsignedbit last_cosine unsigned char i; i = PORTB; /*read and hold, not realy required but makes th ings nice*/ if (i& kuc_SINE_MASK) sine = 1; else sine = 0; if (i& kuc_COSINE_MASK) cosine = 1; else cosine = 0; /*I understand that there are other ways to do t his, but written like*/ /*this for clarity*/ if (uc_do_what == kuc_RESET) /*Reset the static variables so that we can remove*/ { /*the init routine from the comp iler*/ last_sine = sine /*This may be removed if int is used, please note*/ last_cosine = cosine; /*that the first cycle will be incorrect in such case*/ return (kuc_NO_CHANGE); /*as it may not match the encoder, but this is to be*/ } /*expected*/ If (sine != last_sine) /*Not good code produced by this compare */ { switch (sine) { case 0: if (last_cosine) i = quadrature_down() break; case 1: if (last_cosine) i = quadrature_up() break; default: i = kuc_NO_CHANGE; break; } last_sine = sine; last_cosine = cosine; return (i); } return (kuc_NO_CHANGE); } Dennis