CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

rotary encoder

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
rikotech8



Joined: 10 Dec 2011
Posts: 376
Location: Sofiq,Bulgariq

View user's profile Send private message

rotary encoder
PostPosted: Wed Apr 11, 2012 6:53 am     Reply with quote

This is a rotary encoder. I want to use this device for increasing and decreasing value hardware, for example volume control.

Any suggestions ?

Thx in advance! Excuse my bad english!
Ttelmah



Joined: 11 Mar 2010
Posts: 19537

View user's profile Send private message

PostPosted: Wed Apr 11, 2012 8:50 am     Reply with quote

Do a search here for 'quadrature encoder'. Use 'search for all terms'. Many examples.
There are slightly different answers according to a number of factors:
1) Do you want to encode just the individual edges, or all four sub-states?.
2) How fast is the shaft going to spin?.
3) How many lines/rev is the encoder?.
4) What PIC?.

Some of the more complex PIC's have a 'QEI' module that does this directly.
For high speed, on the more basic PIC's, a little external decoding can be added and the CCP modules can then be used to read the counts. Microchip has an application note on this.
At slower speed, basic polling can be used.
For reasonably high speed, carefully 'tweaked' interrupt code, using the interrupt-on-change, can support rates up to perhaps 1/100th the CPU clock rate.

Best Wishes
johnl



Joined: 30 Sep 2003
Posts: 120

View user's profile Send private message

PostPosted: Wed Apr 11, 2012 9:46 am     Reply with quote

Here's a code snippet that's at the beginning of an infinite loop. I hope this will give you an idea.

Code:

n = input(PHASE_A);
if ((Last_phaseA == FALSE) && (n == TRUE))
    {
    if (input(PHASE_B) == FALSE)                  
         Pos = (Pos+1)%FONT_HI_DEX; // (CW rotation)
    else                  
         Pos = (Pos+FONT_HI_DEX-1)%FONT_HI_DEX; // (CCW)
    }
Last_phaseA = n;   
user_letter = Pos;
RHA



Joined: 25 Apr 2006
Posts: 31
Location: Germany

View user's profile Send private message

PostPosted: Wed Apr 11, 2012 11:18 pm     Reply with quote

I always use code like this (for 2 motors with encoder) :
Code:
//******************************************************************************************************
//******************************************************************************************************

#define ENC_NC      0b00010000         // Encoder - no Change
#define ENC_LEFT   0b00100000         // Encoder - one position to left
#define ENC_RIGHT   0b01000000         // Encoder - one position to right
#define ENC_JUMP   0b10000000         // Encoder - Jump (changes 2 positions) ERROR!

int CONST ENC_STATUS[16] = { ENC_NC   , ENC_RIGHT, ENC_LEFT , ENC_JUMP,
                       ENC_LEFT , ENC_NC   , ENC_JUMP , ENC_RIGHT,
                       ENC_RIGHT, ENC_JUMP , ENC_NC   , ENC_LEFT,
                       ENC_JUMP , ENC_LEFT , ENC_RIGHT, ENC_NC };


int8   M1_ENC_STAT;                              //  State Encoder M1
#bit   M1_ENC_STAT_A_ACT   =   M1_ENC_STAT.0            //   Actual signal A
#bit   M1_ENC_STAT_B_ACT   =   M1_ENC_STAT.1            //   Actual signal B
#bit   M1_ENC_STAT_A_OLD   =   M1_ENC_STAT.2            //   Last   signal A
#bit   M1_ENC_STAT_B_OLD   =   M1_ENC_STAT.3            //   Last   signal B
#bit   M1_ENC_STAT_STILL   =   M1_ENC_STAT.4            //   No change in signals
#bit   M1_ENC_STAT_LEFT   =   M1_ENC_STAT.5            //   1 step to left
#bit   M1_ENC_STAT_RIGHT   =   M1_ENC_STAT.6            //   1 step to right
#bit   M1_ENC_STAT_ERROR   =   M1_ENC_STAT.7            //   ERROR

int8   M2_ENC_STAT;                              //  State Encoder M2
#bit   M2_ENC_STAT_A_ACT   =   M2_ENC_STAT.0            //   Actual signal A
#bit   M2_ENC_STAT_B_ACT   =   M2_ENC_STAT.1            //   Actual signal B
#bit   M2_ENC_STAT_A_OLD   =   M2_ENC_STAT.2            //   Last   signal A
#bit   M2_ENC_STAT_B_OLD   =   M2_ENC_STAT.3            //   Last   signal B
#bit   M2_ENC_STAT_STILL   =   M2_ENC_STAT.4            //   No change in signals
#bit   M2_ENC_STAT_LEFT   =   M2_ENC_STAT.5            //   1 step to left
#bit   M2_ENC_STAT_RIGHT   =   M2_ENC_STAT.6            //   1 step to right
#bit   M2_ENC_STAT_ERROR   =   M2_ENC_STAT.7            //   ERROR

//********************************************************************************************************

void   encoder_init() {                           //   Initialize Encoder

      M1_ENC_POS      =   0;                        //   Clear Positions
      M2_ENC_POS      =   0;                        //
      M1_ENC_STAT      =   0;                        //   Clear state
      M2_ENC_STAT      =   0;                        //
      M1_ENC_STAT_A_ACT   =   input(M1_ENCODER_A);      //   Readout actual signals
      M1_ENC_STAT_B_ACT   =   input(M1_ENCODER_B);      //
      M2_ENC_STAT_A_ACT   =   input(M2_ENCODER_A);      //
      M2_ENC_STAT_B_ACT   =   input(M2_ENCODER_B);      //
}
//********************************************************************************************************
//** Keep this part as short as possible because it is called in an Timer-Interrupt

void   encoder() {                                 //   Readout encoder

      M1_ENC_STAT_A_OLD   =   M1_ENC_STAT_A_ACT;         //   Copy last signal to buffer
      M1_ENC_STAT_B_OLD   =   M1_ENC_STAT_B_ACT;         //
      M2_ENC_STAT_A_OLD   =   M2_ENC_STAT_A_ACT;         //
      M2_ENC_STAT_B_OLD   =   M2_ENC_STAT_B_ACT;         //

      M1_ENC_STAT_A_ACT   =   input(M1_ENCODER_A);      //   Readout actual signals
      M1_ENC_STAT_B_ACT   =   input(M1_ENCODER_B);      //
      M2_ENC_STAT_A_ACT   =   input(M2_ENCODER_A);      //
      M2_ENC_STAT_B_ACT   =   input(M2_ENCODER_B);      //

      M1_ENC_STAT   =   ((M1_ENC_STAT & 0x8f) | (ENC_STATUS[(M1_ENC_STAT & 0x0f)]));   //   Get state
      M2_ENC_STAT   =   ((M2_ENC_STAT & 0x8f) | (ENC_STATUS[(M2_ENC_STAT & 0x0f)]));   //

      if      (M1_ENC_STAT_LEFT)   --M1_ENC_POS;
      else if   (M1_ENC_STAT_RIGHT)   ++M1_ENC_POS;

      if      (M2_ENC_STAT_LEFT)   --M2_ENC_POS;
      else if   (M2_ENC_STAT_RIGHT)   ++M2_ENC_POS;

}


Each encoder uses one byte for his state (Mx_ENC_STAT). In this byte there are the last encoder state (2 Bits), the new encoder state (2 Bits) and the information of the state (4 Bits - No change, Left, Right, Error). The Sub encoder() has to be called in a timer interrupt. For good results the frequency of calling the sub has to be min. 3-4 times higher than the maximum frequency of the encoder.


Last edited by RHA on Mon Jun 18, 2012 11:19 pm; edited 1 time in total
necati



Joined: 12 Sep 2003
Posts: 37
Location: istanbul

View user's profile Send private message

rotary encoder
PostPosted: Wed Apr 11, 2012 11:38 pm     Reply with quote

http://320volt.com/pic16f628-74hc595-sayici-ccs-c/
rikotech8



Joined: 10 Dec 2011
Posts: 376
Location: Sofiq,Bulgariq

View user's profile Send private message

PostPosted: Wed Apr 18, 2012 12:57 pm     Reply with quote

Thank you!
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group