ESP32 读取旋转编码器

1、旋转编码器原理
image
1.1、以A输入为时钟,边沿中断检测A输入的上升边沿,同时在中断回调函数判断B的电平状态
①正转CW:A上升沿,B低电平;
②反转CWW:A上升沿,B高电平;
1.2、中间按键直接使用电平或者电平中断检测;

2、旋钮编码器读取
①顺时针旋转:三色灯根据编码器数据增加而变化
②逆时针旋转:三色灯根据编码器数据减少而变化
③中间按键:熄灭RGB三色灯

#define R_PIN 19
#define G_PIN 20
#define B_PIN 21

#define ENCODER_A_PIN 12
#define ENCODER_B_PIN 13
#define ENCODER_SW_PIN 14

unsigned char encoder_cnt = 0;
unsigned char cnt_last_state = 0;

void rgb_turn_off(void){
  digitalWrite(R_PIN, LOW);
  digitalWrite(B_PIN, LOW);
  digitalWrite(G_PIN, LOW);
}

void rgb_change(unsigned char val){
  unsigned int i =val;
  switch(i){
    case 1:
      digitalWrite(R_PIN, HIGH);
      digitalWrite(B_PIN, LOW);
      digitalWrite(G_PIN, LOW);
      break;
    case 2:
      digitalWrite(R_PIN, HIGH);
      digitalWrite(B_PIN, LOW);
      digitalWrite(G_PIN, HIGH);
      break;
    case 3:
      digitalWrite(R_PIN, HIGH);
      digitalWrite(B_PIN, HIGH);
      digitalWrite(G_PIN, LOW);
      break;
    case 4:
      digitalWrite(R_PIN, HIGH);
      digitalWrite(B_PIN, HIGH);
      digitalWrite(G_PIN, HIGH);
      break;
    case 5:
      digitalWrite(R_PIN, LOW);
      digitalWrite(B_PIN, LOW);
      digitalWrite(G_PIN, HIGH);
      break;
    case 6:
      digitalWrite(R_PIN, LOW);
      digitalWrite(B_PIN, HIGH);
      digitalWrite(G_PIN, HIGH);
      break;
    case 7:
      digitalWrite(R_PIN, LOW);
      digitalWrite(B_PIN, HIGH);
      digitalWrite(G_PIN, LOW);
      break;
    default:
      digitalWrite(R_PIN, LOW);
      digitalWrite(B_PIN, LOW);
      digitalWrite(G_PIN, LOW);
      break;
  }
}

void Interrupt_read_encoder(void) {
  int dt_val = 0;
  dt_val = digitalRead(ENCODER_B_PIN);
  if(dt_val == LOW){
    Serial.println("Rotated CW >>");
    if(encoder_cnt >= 7){
      encoder_cnt = 7;
    }else{
      encoder_cnt ++;
    }
  }
  if(dt_val == HIGH){
    Serial.println("Rotated CCW <<");
   if(encoder_cnt == 0){
      encoder_cnt = 0;
    }else{
      encoder_cnt --;
    }
  }
}

void setup() {
  Serial.begin(115200);
  
  pinMode(R_PIN, OUTPUT);
  pinMode(G_PIN, OUTPUT);
  pinMode(B_PIN, OUTPUT);
  rgb_turn_off();

  pinMode(ENCODER_A_PIN, INPUT);
  pinMode(ENCODER_B_PIN, INPUT);
  pinMode(ENCODER_SW_PIN, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(ENCODER_A_PIN), Interrupt_read_encoder, RISING);
  Serial.print("RBG runing...\r\n");
}

void loop() {
  
  noInterrupts();
  if(cnt_last_state != encoder_cnt){
    cnt_last_state = encoder_cnt;
    rgb_change(encoder_cnt);
    Serial.printf("encoder_cnt=%d.\r\n", encoder_cnt);
  }
  interrupts();
  
  if(digitalRead(ENCODER_SW_PIN) == LOW){
    delay(100);
    if(digitalRead(ENCODER_SW_PIN) == LOW){
      Serial.println("sw chick...\r\n");
      rgb_turn_off();
      encoder_cnt = 0;
    }
  }
}

2、执行仿真效果
https://wokwi.com/projects/442778436089219073)
image

posted @ 2025-09-22 18:06  zbl1118  阅读(54)  评论(0)    收藏  举报