差别
这里会显示出您选择的修订版和当前版本之间的差别。
两侧同时换到之前的修订记录 前一修订版 后一修订版 | 前一修订版 | ||
arduino_rotary_encoder [2022/02/05 13:45] gongyusu |
arduino_rotary_encoder [2022/02/05 13:53] (当前版本) gongyusu [2. 参考技术资料] |
||
---|---|---|---|
行 4: | 行 4: | ||
* {{ :circuit-schematic-v2.jpg |}} | * {{ :circuit-schematic-v2.jpg |}} | ||
* {{ :close-view-v2.jpg |}} | * {{ :close-view-v2.jpg |}} | ||
- | * {{ :filtered-signal-v2 |}} | + | * {{ :filtered-signal-v2.jpg |}} |
* {{ :top-view-v2.jpg |}} | * {{ :top-view-v2.jpg |}} | ||
+ | |||
+ | |||
+ | ### 2. 代码示例 | ||
+ | 初始化管脚以及中断服务程序 | ||
+ | |||
+ | <code c> | ||
+ | #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; | ||
+ | } | ||
+ | } | ||
+ | |||
+ | } | ||
+ | |||
+ | </code> | ||
+ | |||
+ | |||
### 2. 参考技术资料 | ### 2. 参考技术资料 | ||
* [[https://microcontrollerslab.com/rotary-encoder-arduino-tutorial/|Rotary Encoder Module with Arduino]] | * [[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]] |