-Terppa-
Joined: 08 Jan 2018 Posts: 59 Location: Finland
|
Simple rotary encoder potentiometer reader |
Posted: Sun Feb 16, 2020 4:19 am |
|
|
Here is simple rotary encoder potentiometer reader. It not requires any interrupts. Only need pull-up resistors but internal pull-ups is ok if available.
Using this library is very simple put rotary_encoder1() in your main while() or timer interrupt. If you are use timer interrupt you must remove fprint section in rotary_encoder1() function.
rotary_encoder_lib.h
Code: |
/*
software rotary encoder decoder
by:termostaatti 120220
not requires any interrupt
not even filter capacitors!
tested:
18f46k80/64Mhz
IO- require:
pull-ups requires if rotary encoder connected
normal schmitt trigger input.
#define ROTUP1 (!input(PIN_B4))
#define ROTDWN1 (!input(PIN_B0))
//rotary encoder pin test:
#define STATUSLED1 PIN_B2
#define STATUSLED2 PIN_B3
*/
#define DEBOUNCETIME 0 //uS
unsigned int16 rot_status1=0;
unsigned int8 rot_sts_new=0;
unsigned int8 rot_sts_old=0;
unsigned int8 rot_idx=0;
char rottbl_1[3];
void rotary_encoder1(void);
void clear_rot_table(void);
void pinout_test(void);
//
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void rotary_encoder1(void)
{
//phase detect:
if(ROTUP1==1&&ROTDWN1==0)rot_sts_new=1;
if(ROTUP1&&ROTDWN1)rot_sts_new=3;
if(ROTUP1==0&&ROTDWN1==1)rot_sts_new=2;
//any movements?
if(rot_sts_old!=rot_sts_new)
{
rot_sts_old=rot_sts_new;
rottbl_1[rot_idx++]=rot_sts_new;
//phase detect menu(debug):
// fprintf(HW_CONSOLE,"\n\r%u,%u,%u ",rottbl_1[0],rottbl_1[1],rottbl_1[2]);
//phase count:
if(rot_idx==3)rot_idx=0;
delay_us(DEBOUNCETIME);
//that middle point is actually phase but as you can see
//table content depends which rotation speed is use.
// | |very slow half rotate
//213,132,321,210
// |
if(rottbl_1[0]==2&&rottbl_1[1]==1&&rottbl_1[2]==3 ||rottbl_1[0]==1&&rottbl_1[1]==3&&rottbl_1[2]==2 ||rottbl_1[0]==3&&rottbl_1[1]==2&&rottbl_1[1] ||rottbl_1[0]==2&&rottbl_1[1]==1&&rottbl_1[0])
{
clear_rot_table();
--rot_status1;
fprintf(HW_CONSOLE,"\n\r%lu",rot_status1);
}
//that middle point is actually phase but as you can see
//table content depends which rotation speed is use.
// | |very slow half rotate
//312,231,123,310
// |
if(rottbl_1[0]==3&&rottbl_1[1]==1&&rottbl_1[2]==2 ||rottbl_1[0]==2&&rottbl_1[1]==3&&rottbl_1[2]==1 ||rottbl_1[0]==1&&rottbl_1[1]==2&&rottbl_1[2]==3 ||rottbl_1[0]==3&&rottbl_1[1]==1&&rottbl_1[2]==0)
{
clear_rot_table();
++rot_status1;
fprintf(HW_CONSOLE,"\n\r%lu",rot_status1);
}
}
}
//
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void clear_rot_table(void)
{
rot_idx=0;
for(byte ii=0;ii<3;ii++)rottbl_1[ii]=0;
}
//test rotary encoder pins(debug):
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void pinout_test(void)
{
if(ROTUP1)high(STATUSLED2);
else low(STATUSLED2);
if(ROTDWN1)high(STATUSLED1);
else low(STATUSLED1);
}
|
|
|