回答編集履歴
1
話が出力では無く入力だったので書き換え
test
CHANGED
@@ -1,11 +1,133 @@
|
|
1
|
-
一体何が問題なのかが判りません。
|
2
|
-
|
3
|
-
|
1
|
+
<入力の問題だったようなので、全面的に書き換えます。>
|
4
2
|
|
5
3
|
|
6
4
|
|
7
|
-
|
5
|
+
基本的に、「簡単」とは言わないけど、1つずつ必要な処理を書いていけば出来る事だと思います。
|
8
6
|
|
9
|
-
|
7
|
+
ただし、目的がLED1個を角度○~△の間だけ点灯なら、何も考えずに書いていけばいい事ですけど、
|
10
8
|
|
9
|
+
目的によってはそうはいきません。バーサライタなんかだとほぼ裏方です。
|
10
|
+
|
11
|
+
つまり、loop関数は表示(LED操作)の為に残して、外部割り込みやタイマーを使って、現在の角度を取得できるように構成させる必要?というか、そうした方がやり易かったりします。
|
12
|
+
|
13
|
+
単にint degree_get()のような関数を作って、現在の角度を取得するように構成させます。
|
14
|
+
|
15
|
+
|
16
|
+
|
17
|
+
※thkanaさんのスケッチへのレスを見る限り、そのスケッチに付け足して何かを作るのはまだ無理のように感じました。
|
18
|
+
|
19
|
+
|
20
|
+
|
21
|
+
|
22
|
+
|
23
|
+
出来るだけ簡単に角度を取得できる工夫も必要です。角度の取得に時間がかかっていれば表示はその影響を受けます。
|
24
|
+
|
25
|
+
この程度の事は数us程度の誤差(遅れ/作業時間)で済ませたい所です。
|
26
|
+
|
27
|
+
|
28
|
+
|
29
|
+
簡単に言えば、まずやりたい事全体で考える事です。そして、どのようにするのが良いシステムになるのか
|
30
|
+
|
31
|
+
(どのように無駄のないものにするか)、を考えてください。
|
32
|
+
|
33
|
+
|
34
|
+
|
35
|
+
羽根(パルス)の数も、4(3)つあれば、それだけ識別に手間取りますし、間違いも起こります。
|
36
|
+
|
37
|
+
これは1つにすべきです。
|
38
|
+
|
39
|
+
|
40
|
+
|
41
|
+
|
42
|
+
|
11
|
-
|
43
|
+
↓は、やはり羽根1つでのサンプルです。degree_get()をすればその時の角度(degree)*100で取得します。
|
44
|
+
|
45
|
+
後はセンサーの設置位置に合わせて適当にオフセットを付ければ良いです。
|
46
|
+
|
47
|
+
ループ関数は何もしていない(↓はテスト用の表示が入っている)ので、自由に使えます。
|
48
|
+
|
49
|
+
|
50
|
+
|
51
|
+
```Arduino
|
52
|
+
|
53
|
+
volatile word period;
|
54
|
+
|
55
|
+
|
56
|
+
|
57
|
+
void pulse_read() {
|
58
|
+
|
59
|
+
period=TCNT1;
|
60
|
+
|
61
|
+
TCNT1=0;
|
62
|
+
|
63
|
+
}
|
64
|
+
|
65
|
+
|
66
|
+
|
67
|
+
ISR (TIMER1_OVF_vect) {//低速、停止時に0にする為
|
68
|
+
|
69
|
+
period=0;
|
70
|
+
|
71
|
+
}
|
72
|
+
|
73
|
+
|
74
|
+
|
75
|
+
word degree_get() {//角度*100を返す
|
76
|
+
|
77
|
+
if(period==0)return 0;
|
78
|
+
|
79
|
+
return 36000UL*TCNT1/period;
|
80
|
+
|
81
|
+
}
|
82
|
+
|
83
|
+
|
84
|
+
|
85
|
+
void setup() {
|
86
|
+
|
87
|
+
Serial.begin(9600) ;
|
88
|
+
|
89
|
+
TCCR1A=0;
|
90
|
+
|
91
|
+
TCCR1B=2; //1/8=0.5us/countでタイマー1を回す
|
92
|
+
|
93
|
+
TIMSK1=1;//無回転等の判別用。まぁ無くてもOK
|
94
|
+
|
95
|
+
attachInterrupt(0, pulse_read, RISING);//センサーD2ピン
|
96
|
+
|
97
|
+
tone(4,125);//8ms ※テスト信号。これをD2に入れる
|
98
|
+
|
99
|
+
}
|
100
|
+
|
101
|
+
|
102
|
+
|
103
|
+
void loop() {
|
104
|
+
|
105
|
+
Serial.print(period);
|
106
|
+
|
107
|
+
Serial.print(" ");
|
108
|
+
|
109
|
+
Serial.println(degree_get());
|
110
|
+
|
111
|
+
|
112
|
+
|
113
|
+
delay(300);
|
114
|
+
|
115
|
+
}
|
116
|
+
|
117
|
+
```
|
118
|
+
|
119
|
+
|
120
|
+
|
121
|
+
プログラム的には超簡単です。(レジスタ操作は別として)
|
122
|
+
|
123
|
+
解説すれば、外部割り込みで、パルスの上昇で割り込み(pulse_read関数)をかけています。(原点)
|
124
|
+
|
125
|
+
また、タイマー1(TCNT1)をストップウォッチのように使っています。
|
126
|
+
|
127
|
+
割り込み時にタイマ値を読み取りリセットします。そのタイマー値は回転周期(period)です。
|
128
|
+
|
129
|
+
degree_get関数は回転周期と現在のタイマ値から割合を出し、36000をかけて戻しています。
|
130
|
+
|
131
|
+
|
132
|
+
|
133
|
+
※実際にはtoneやSerialは消してください。
|