|
|
View previous topic :: View next topic |
Author |
Message |
rikotech8
Joined: 10 Dec 2011 Posts: 376 Location: Sofiq,Bulgariq
|
rotary encoder |
Posted: Wed Apr 11, 2012 6:53 am |
|
|
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: 19535
|
|
Posted: Wed Apr 11, 2012 8:50 am |
|
|
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
|
|
Posted: Wed Apr 11, 2012 9:46 am |
|
|
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
|
|
Posted: Wed Apr 11, 2012 11:18 pm |
|
|
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
|
|
|
rikotech8
Joined: 10 Dec 2011 Posts: 376 Location: Sofiq,Bulgariq
|
|
Posted: Wed Apr 18, 2012 12:57 pm |
|
|
Thank you! |
|
|
|
|
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
|