回答編集履歴

1

話が出力では無く入力だったので書き換え

2020/09/06 02:02

投稿

nac_tnk
nac_tnk

スコア463

test CHANGED
@@ -1,11 +1,133 @@
1
- 一体何が問題なのかが判りません。
2
-
3
- 何れも出するですね?Lチカのスケッチと同じだと思うのですけど?
1
+ <入力の問題だったようので、全面的に書き換えま。>
4
2
 
5
3
 
6
4
 
7
- それもポイントは、Lレベルが1Vちょ→1V弱と減っていっていという部分が問題なのでしょうか?
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
- 単にLレベルが1V程度、という事なら、バスを分圧1Vにして、HIGH出力-High-Zで切り替えれば良いと思います。
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は消してください。