Project:Arduino Rotary Encoder Menu System

From Nottinghack Wiki
Revision as of 12:25, 27 July 2012 by Msemtd (talk | contribs)
Jump to navigation Jump to search

I have recovered a number of ALPS rotary encoders from discarded industrial CRT monitors. I'm working on building a user interface menu system that makes use of the rotary encoders as the sole input technique.

Rotary Encoder Test Sketch With Interrupts (non-PWM)

 1 #define PIN_ENC1 2
 2 #define PIN_ENC2 3
 3 #define PIN_EBTN 4
 4 #define PIN_LED1 13
 5 static boolean moving=false;
 6 volatile unsigned int encValue = 0;
 7 unsigned int encValueTracking = 1;
 8 boolean enc1 = false;              
 9 boolean enc2 = false;
10 
11 // Here I'm messing around with button press durations - we could go to town here!
12 enum pressDuration { reallyQuickPress, shortPress, normalPress, longPress, veryLongPress };
13 long presses[] = { 40, 150, 300, 800, 1400 };
14 char* pressText[]={"really quick press!", "short press", "normal press", "long press", "very looooooooong press"};
15 
16 void setup() 
17 {
18   pinMode(PIN_ENC1, INPUT); 
19   pinMode(PIN_ENC2, INPUT); 
20   pinMode(PIN_EBTN, INPUT);
21   pinMode(PIN_LED1, OUTPUT);
22   digitalWrite(PIN_ENC1, HIGH);
23   digitalWrite(PIN_ENC2, HIGH);
24   digitalWrite(PIN_EBTN, HIGH);
25   Serial.begin(9600);
26   menuIntro();
27   attachInterrupt(0, intrEncChange1, CHANGE);
28   attachInterrupt(1, intrEncChange2, CHANGE);
29 }
30 
31 void intrEncChange1()
32 {
33   if(moving) 
34     delay(1);
35   if(digitalRead(PIN_ENC1) == enc1)
36     return;
37   enc1 = !enc1;
38   if(enc1 && !enc2) 
39     encValue += 1;
40   moving = false;
41 }
42 
43 void intrEncChange2()
44 {
45   if(moving) 
46     delay(1);
47   if(digitalRead(PIN_ENC2) == enc2)
48     return; 
49   enc2 = !enc2;
50   if(enc2 && !enc1) 
51     encValue -= 1;
52   moving = false;
53 }
54 
55 void loop() 
56 { 
57   static unsigned long btnHeld = 0;
58   moving = true;
59   if(encValueTracking != encValue){
60     Serial.print("encValue: ");
61     Serial.println(encValue, DEC);
62     encValueTracking = encValue;
63   }
64   // Upon button press...
65   if((digitalRead(PIN_EBTN) == LOW) && !btnHeld){
66     btnHeld = millis();
67     digitalWrite(PIN_LED1, HIGH);
68     Serial.print("pressed selecting: ");
69     Serial.println(encValue, DEC);
70   }
71   // Upon button release...
72   if((digitalRead(PIN_EBTN) == HIGH) && btnHeld){
73     long t = millis();
74     t -= btnHeld;
75     digitalWrite(PIN_LED1, LOW);
76     int dur = veryLongPress;
77     for(int i = 0; i<= veryLongPress; i++){
78       if(t > presses[i])
79          continue;
80       dur = i;
81       break;
82     }
83     
84     Serial.print("released selecting: ");
85     Serial.print(encValue, DEC);    
86     Serial.print(" (after ");
87     Serial.print(t, DEC);
88     Serial.print(" ms = ");
89     Serial.print(pressText[dur]);
90     Serial.println(")");
91     btnHeld = 0;
92   }
93 }
94 
95 void menuIntro()
96 {
97   Serial.println("Encoder Menu - blah, blah, blah");
98 }

multiple encoders

Try out http://code.google.com/p/adaencoder/ and PinChangeInt library (http://code.google.com/p/arduino-pinchangeint/) see...

http://arduino.cc/playground/Main/RotaryEncoders#Example14

See if it can cope with two encoders at rapid rate usage.