## 用Arduino控制旋转编码器 ### 1. 电路连接 * {{ :circuit-schematic-v2.jpg |}} * {{ :close-view-v2.jpg |}} * {{ :filtered-signal-v2.jpg |}} * {{ :top-view-v2.jpg |}} ### 2. 代码示例 初始化管脚以及中断服务程序 #include #include #include volatile byte seqA = 0; volatile byte seqB = 0; volatile byte cnt1 = 0; volatile byte cnt2 = 0; volatile boolean right = false; volatile boolean left = false; volatile boolean button = false; boolean backlight = true; byte menuitem = 1; byte page = 1; Adafruit_PCD8544 display = Adafruit_PCD8544(13, 12,11, 8, 10); void setup() { pinMode(A0, INPUT); pinMode(A1, INPUT); pinMode(A2, INPUT); // Enable internal pull-up resistors digitalWrite(A0, HIGH); digitalWrite(A1, HIGH); digitalWrite(A2, HIGH); // Turn on LCD backlight pinMode(9, OUTPUT); digitalWrite(9, HIGH); PCICR = 0b00000010; // 1. PCIE1: Pin Change Interrupt Enable 1 PCMSK1 = 0b00000111; // Enable Pin Change Interrupt for A0, A1, A2 // Initialize LCD display.setRotation(2); // Set LDC orientation display.begin(60); // Set LCD contrast display.clearDisplay(); // Clear display display.display(); // Apply changes sei(); } void loop() { // Create Menu Pages if (page==1) { display.setTextSize(1); display.clearDisplay(); display.setTextColor(BLACK, WHITE); display.setCursor(15, 0); display.print("MAIN MENU"); display.drawFastHLine(0,10,83,BLACK); display.setCursor(0, 15); if (menuitem==1) { display.setTextColor(WHITE, BLACK);} else {display.setTextColor(BLACK, WHITE);} display.print(">Contrast: 99%"); display.setCursor(0, 25); if (menuitem==2) { display.setTextColor(WHITE, BLACK);} else {display.setTextColor(BLACK, WHITE);} display.print(">Test Encoder"); if (menuitem==3) { display.setTextColor(WHITE, BLACK);} else {display.setTextColor(BLACK, WHITE);} display.setCursor(0, 35); display.print(">Backlight:"); if (backlight) {display.print("ON");} else {display.print("OFF");} display.display();} else if (page==2) { display.setTextSize(1); display.clearDisplay(); display.setTextColor(BLACK, WHITE); display.setCursor(15, 0); display.print("ENC. TEST"); display.drawFastHLine(0,10,83,BLACK); display.setCursor(5, 15); display.print("LEFT RIGHT"); display.setTextSize(2); display.setCursor(5, 25); display.print(cnt1); display.setCursor(55, 25); display.print(cnt2); display.setTextSize(2); display.display(); } // Take action if a new command received from the encoder if (left) { left = false; menuitem--; if (menuitem==0) {menuitem=3;} } if (right) { right = false; menuitem++; if (menuitem==4) {menuitem=1;} } if (button) { button = false; if (page == 1 && menuitem==3) { digitalWrite(9, LOW); if (backlight) {backlight = false; digitalWrite(9, LOW);} else {backlight = true; digitalWrite(9, HIGH);} } else if (page == 1 && menuitem==2) { page=2; cnt1=0; cnt2=0; } else if (page == 2) { page=1; } } } ISR (PCINT1_vect) { // If interrupt is triggered by the button if (!digitalRead(A0)) { button = true;} // Else if interrupt is triggered by encoder signals else { // Read A and B signals boolean A_val = digitalRead(A1); boolean B_val = digitalRead(A2); // Record the A and B signals in seperate sequences seqA <<= 1; seqA |= A_val; seqB <<= 1; seqB |= B_val; // Mask the MSB four bits seqA &= 0b00001111; seqB &= 0b00001111; // Compare the recorded sequence with the expected sequence if (seqA == 0b00001001 && seqB == 0b00000011) { cnt1++; left = true; } if (seqA == 0b00000011 && seqB == 0b00001001) { cnt2++; right = true; } } } ### 2. 参考技术资料 * [[https://microcontrollerslab.com/rotary-encoder-arduino-tutorial/|Rotary Encoder Module with Arduino]] * [[https://www.electronicshub.org/arduino-rotary-encoder/|Rotary Encoder With Arduino – Know it all]]