|
|
View previous topic :: View next topic |
Author |
Message |
Josh Davis Guest
|
20 Click 3 pin Rotary Encoder on port b pins 2, 3 |
Posted: Sun Nov 30, 2003 11:14 pm |
|
|
Hi All. Im using a small Rotary Encoder as a means for a human i/o
I have got my code working but notice that If I twist the Encoder Shaft
pretty fast , I will miss some counts. The encoder is not running any
interrupt as to get to where the code is called the user first has to press
a button on rb.0
Here is a snip of the main routine im using. Basicaly it detects the state of
pins 2, 3 on port b and depending on there state increments, decrements
a variable... Kind of like having 2 switches to do the same job.
It then puts the data on line 2 of a 20X2 chr lcd display.
If any of you have a better way of doing this or perhaps a dedicated encoder routine that might handle what Im trying to do better It would be
most welcome.
My pic is a 16f83 running at 4Mhz
Thanks . Josh.
void encoder(){ // enc1, enc2 are encoder. center pin is ground
LCD_Cmd( CLEAR_DISP );
Lcd_cmd( LCD_LINE1 );
LCD_PutChar("Select TX Freq <- ->");
Lcd_cmd( LCD_LINE2 );
printf(LCD_PutChar, "FREQ: = %Lu Mhz", freq);//Display inital frequency
while (true){ //Loop until break encountered
if (enc2==0)
if (enc2==0) //Test to see if SW2 Went Low. If it did decrement Freq Variable
{
--freq;
if( freq < 200 ) // Bound Lower Freq to no less than 200
freq = 200;
Lcd_cmd( LCD_LINE2 );
printf(LCD_PutChar, "FREQ: = %Lu Mhz", freq);
}
if (enc1==0)
long_delay();
if (enc1==0) //Test to see if SW1 Went Low. If it did increment Freq variable
{
++freq;
if( freq > 250 ) //Bound upper freq to no more than 250
freq = 250;
Lcd_cmd( LCD_LINE2 );
printf(LCD_PutChar, "FREQ: = %Lu Mhz", freq);
}
if (toggle==0)
long_delay(); // de-bounce
if (toggle==0)
break; //If Toggle went Low Return to case3
{
}
}
} |
|
|
david smith
Joined: 28 Oct 2003 Posts: 4 Location: California
|
|
Posted: Sun Nov 30, 2003 11:52 pm |
|
|
I was working with this a few months ago, using a mechanical rotary switch. After a bunch of time attempting to debounce unsuccessfully, I realized that the two inputs (A,B) are related to the mechanical detent position. In short, swapping the pins made the non-changing one at the right state WRT the transition detent. My routine follows. It inc/dec T1 by the current step size and displays on LCD. Hope it helps
void scanSwitch(){
// ROTARY ENCODER scanner
// better if B transitions are read since B edge is at detent position
// read to vars A,B first; update at end. very smooth now.
// both work when A edges and B levels are checked.
int8 deltaN, k;
int1 A,B;
deltaN = 1; // Number to incr/decr by each loop
while(1){
delay_ms(1);
A = swT2_dn;
B = swT1_dn;
if ((A < Aprev)) { // look at rising edge; check state of B;
if (B == 0 ) {T1 -= deltaN; }
else {T1 += deltaN; }
if (T1 < 0) T1 = Tmax; if (T1>Tmax) T1 = 0; // constrain range (0 - Tmax)
k = 0;
updateDisp(1); // update display line 2
}
if(k++ > 100){
k=0;
updateDisp(0);
writedata(); // write newest values to EEprom
}
Aprev = A;
} // end while
} |
|
|
Josh Davis Guest
|
|
Posted: Mon Dec 01, 2003 7:07 am |
|
|
Hi David.
I have a question about your code snip.
What is Aprev ?. Im thinking its an int variable
also the
A = swT2_dn;
B = swT1_dn;
are swT1_dn and swT2_dn labels for your switches then your setting int
a and b equal to these so you have 2 variables to use for sampling if the
switches or clicks from the encoder went high or low...
for example before main might look like this.
#BIT swT2_DN = port_b.1
#BIT swT1_DN = port_b.2
void main(void){
Thanks again... Josh. |
|
|
david smith
Joined: 28 Oct 2003 Posts: 4 Location: California
|
|
Posted: Mon Dec 01, 2003 1:26 pm |
|
|
Since I extracted and edited the routine, I neglected to show variables.
// global stuff...
#BIT swT1_up = PORTB.4
#BIT swT1_dn = PORTC.0
signed int16 D, T1, T2, T3, Dmax, Tmax, Tdist;
int1 Aprev; // holds previous value of A
(You may email me privately for further info.) |
|
|
|
|
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
|