以上简单的示例是为了讲明白旋转编码器在旋转过程中发生了什么,根据发生的具体物理事件中的某个完整周期事件实现旋转检测。在实际的应用中,我们可以将其作为一个头文件使用,并优化相关的变量名称,增加代码的可读性。
以下代码是我在ESP32上通过Arduino编写的相关代码,可供参靠,同时增加了旋转编码器上按键的示例,包含单击、长按,经过实际操作,发现编码器的按钮不适合双击和三连击。如果需要,可自行参靠长按的检测实现双击检测。
#define EC11_A_PIN 0
#define EC11_B_PIN 1
#define BUTTON_PIN 2
bool R_Encoder_Left_Flag =false ; //定义用于旋转编码器的左旋标志变量
bool R_Encoder_Right_Flag =false ; //定义用于旋转编码器的右旋标志变量
#define EC11_LEFT_ACTIVE (-1) //定义变量R_Encoder_Active的向左旋转取值
#define EC11_RIGHT_ACTIVE (1) //定义变量R_Encoder_Active的向右旋转取值
int R_Encoder_Active =0 ; //定义用于旋转编码器的激活状态,如果为真认为发生了有效旋转,如果为-1则左旋,如果为1则右旋 <-----
bool Button_Flag =false ; //定义用于按键的标志变量
bool Button_Active =false ; //定义用于按键的激活状态,如果为真(1)则认为发生了有效按键事件 <-----
bool Button_Falling_Flag =false; //标记按键被按下
unsigned long buttonPressStartTime =0; //用于记录按键被按下的时间点,在主函数中如果被按下还没抬起,可以读取当时的时间减去该标记时间,即可知道是否发生了长按事件 <-------
void ButtonHandleInterrupt(void)
{
if( digitalRead(BUTTON_PIN) == LOW ) //如果是下降沿,即为按键被按下
{
Button_Flag = true;
buttonPressStartTime = millis();
Button_Falling_Flag = true;
}
else if( (digitalRead(BUTTON_PIN) == HIGH) && (Button_Flag == true) ) //如果是上升沿,按键被抬起
{
if(millis()-buttonPressStartTime<1000)
Button_Active = true;
Button_Flag = false;
}
}
/*
在A:B上每次旋转发生了两组不同的电平跳变组合(L1->H0)、(L0->H1),其中
L表示A的下降沿,H表示A的上升沿,1表示此刻B为高电平,0表示此刻B为低电平
*/
void EC11HandleInterrupt(void)
{
if ( digitalRead(EC11_A_PIN) == LOW )
{
if( digitalRead(EC11_B_PIN) == HIGH )
{
R_Encoder_Left_Flag =true;
}
else
{
R_Encoder_Right_Flag =true;
}
}
else
{
if( (digitalRead(EC11_B_PIN) == LOW) && (R_Encoder_Left_Flag ==1) )
{
R_Encoder_Left_Flag = false;
R_Encoder_Active =EC11_LEFT_ACTIVE;
}
else if( (digitalRead(EC11_B_PIN) == HIGH) && (R_Encoder_Right_Flag ==1) )
{
R_Encoder_Right_Flag = false;
R_Encoder_Active =EC11_RIGHT_ACTIVE;
}
}
}
void EC11_Init(void)
{
pinMode(EC11_A_PIN , INPUT_PULLUP);
pinMode(EC11_B_PIN , INPUT_PULLUP);
pinMode(BUTTON_PIN , INPUT_PULLUP);
attachInterrupt(BUTTON_PIN,ButtonHandleInterrupt,CHANGE);
attachInterrupt(EC11_A_PIN, EC11HandleInterrupt, CHANGE);
}
文件EC11_V3.ino
#include 'EC11.h'
//定义开发板载LED
#define LED4 12
#define LED5 13
int Mode = 0 ; //定义模式变量,用于标识出不同的模式
int val =0; //测试打印用变量
void setup()
{
Serial.begin(115200);
Serial1.begin(115200);
Serial1.println('SERIAL-l');
pinMode(LED4 , OUTPUT);
pinMode(LED5 , OUTPUT);
EC11_Init();
Serial.println('--------------');
}
void loop()
{//检测是否发生了单击按键事件,即按下又松开
if(Button_Active == true)
{
Button_Active = false;
Mode++;
if(Mode > 3) Mode = 0;
Serial.print('MODE:');Serial.println(Mode);
digitalWrite(LED4,!digitalRead(LED4));
}
if(R_Encoder_Active !=0)
{
val=val+R_Encoder_Active;
R_Encoder_Active =0;
digitalWrite(LED5,!digitalRead(LED5));
Serial.print('Val= ');Serial.println(val);
}
//检测是否发生了长按事件
if(Button_Falling_Flag == true)
{
if(millis()-buttonPressStartTime>1000)
{
while( digitalRead(BUTTON_PIN) == LOW )
{
val++;Serial.print('Val= ');Serial.println(val);
delay(100);
}
Button_Falling_Flag = false;
}
}
}
联系客服