arduino DUEは全てのデジタルピンで割り込みが可能なので、質問中の’タイマー割り込み’ではなく、エンコーダの信号のA相、B相がソース上のPIN A
及びPIN B
と仮定して、回答致します。
また割り込みの定義ではCHANGE
になっていますが、立ち上がり、立下り、変化が割り込みの起因になりますが、ソースの通りCHANGE
とします。
その前に注意点ですが、OMRONのこの型番のエンコーダーは動作電圧が5V。しかしDUEでは3.3Vです。これもレベル変換回路が有るものと仮定します。
ソース上割り込みは起因が'1'ですのでpin1?と思いますが、割り込みは変化するA相、B相ですから、これらの割り込みを受け取り、またどのように変化したか?で判断します。
その為にはソースの中ではpt
で状態遷移を見ていると思いますが、確度を上げるには前の値とするべきでは?
よってA相のPin AとB相のPin Bの前回値(初期状態では読み込み値)を保持すべきでしょう。
それと一周を判断するZ相は参照の範囲ではないと仮定します。
これらの仮定から机上ですが、サンプルソースは以下のようになると考えます。
arduino
1#define rot_pinA 2
2#define rot pinB 3
3
4long rot_count = 0; // 一周を300countとして状態が4ステップなので1200ステップに拡張。
5int direction = 0;
6int parse;
7
8void setup()
9{
10 int current_a;
11 int current_b;
12
13 Serial.begin(9600);
14 pinMode(pinA,INPUT);
15 pinMode(pinB,INPUT);
16
17 current_a = digitalRead(pinA);
18 current_b = digitalRead(pinB);
19
20 if(( current_a == 0 ) && ( current_b == 0 )) // A,Bとも0
21 {
22 parse = 0;
23 }
24 if(( current_a == 1 ) && ( current_b == 0 )) // A=1 B = 0 CCW
25 {
26 parse = 1;
27 }
28 if(( current_a == 1 ) && ( current_b == 1 )) // A,Bとも0
29 {
30 parse = 2;
31 }
32 if(( current_a == 0 ) && ( current_b == 1 )) // A,Bとも0
33 {
34 parse = 3;
35 }
36
37 attachInterrupt(pinA,rotary_changedPin,CHANGE);
38 attachInterrupt(pinB,rotary_changedPin,CHANGE);
39}
40
41void loop()
42{
43 //シリアルコンソールに現在の値を出力。
44 Serial.println(rot_count);
45 delayMicroseconds(1000);
46}
47
48//pinの割り込み処理
49void rotary_changedPin()
50{
51 int now_a;
52 int now_b;
53 now_a = digitalRead(pinA);
54 now_b = digitalRead(pinB);
55
56 if( parse == 0 )
57 {
58 if(( now_a == 1 ) && (now_b == 0 )) // reverse=CCW
59 {
60 rot_count--;
61 direction = 0; //CCW
62 parse = 3;
63 return;
64 } else if (( now_a == 0 ) && ( now_b == 1)) //foward = CW
65 {
66 rot_count++;
67 direction = 1; //CW
68 parse = 1;
69 return;
70 } else {
71 // fatal error
72 }
73 }
74 if( parse == 1 )
75 {
76 if(( now_a == 0 ) && (now_b == 0 )) // reverse = CCW
77 {
78 rot_count--;
79 direction= 0; //CCW
80 parse = 3;
81 return;
82 } else if (( now_a == 1 ) && ( now_b == 1)) //foward = CW
83 {
84 rot_count++;
85 direction = 1; // CW
86 parse = 2;
87 return;
88 } else {
89 // fatal error
90 }
91 }
92 if( parse == 2 )
93 {
94 if(( now_a == 1 ) && (now_b == 0 )) // reverse = CCW
95 {
96 rot_count--;
97 direction= 0; //CCW
98 parse = 1;
99 return;
100 } else if (( now_a == 0 ) && ( now_b == 1)) //foward = CW
101 {
102 rot_count++;
103 direction = 1; // CW
104 parse = 3;
105 return;
106 } else {
107 // fatal error
108 }
109 }
110 if( parse == 3 )
111 {
112 if(( now_a == 1 ) && (now_b == 1 )) // reverse = CCW
113 {
114 rot_count--;
115 direction= 0; //CCW
116 parse = 2;
117 return;
118 } else if (( now_a == 0 ) && ( now_b == 0)) //foward = CW
119 {
120 rot_count++;
121 direction = 1; // CW
122 parse = 0;
123 return;
124 } else {
125 // fatal error
126 }
127 }
128}
こんな感じですかね?