teratail header banner
teratail header banner
質問するログイン新規登録

回答編集履歴

1

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

2020/09/06 02:02

投稿

nac_tnk
nac_tnk

スコア512

answer CHANGED
@@ -1,6 +1,67 @@
1
- 一体何が問題なのかが判りません。
2
- 何れも出するですよね?Lチカのスケッチと同じと思うのですけど?
1
+ <入力の問題ったよので、全面的に書き換えま。>
3
2
 
3
+ 基本的に、「簡単」とは言わないけど、1つずつ必要な処理を書いていけば出来る事だと思います。
4
+ ただし、目的がLED1個を角度○~△の間だけ点灯なら、何も考えずに書いていけばいい事ですけど、
5
+ 目的によってはそうはいきません。バーサライタなんかだとほぼ裏方です。
6
+ つまり、loop関数は表示(LED操作)の為に残して、外部割り込みやタイマーを使って、現在の角度を取得できるように構成させる必要?というか、そうした方がやり易かったりします。
4
- それともポイントは、Lレベルが1Vちょい→1V弱と減っていっているという部分が問題なでしょか?
7
+ 単にint degree_get()のような関数を作って、現在角度を取得するよに構成させます。
8
+
9
+ ※thkanaさんのスケッチへのレスを見る限り、そのスケッチに付け足して何かを作るのはまだ無理のように感じました。
10
+
11
+
12
+ 出来るだけ簡単に角度を取得できる工夫も必要です。角度の取得に時間がかかっていれば表示はその影響を受けます。
13
+ この程度の事は数us程度の誤差(遅れ/作業時間)で済ませたい所です。
14
+
15
+ 簡単に言えば、まずやりたい事全体で考える事です。そして、どのようにするのが良いシステムになるのか
16
+ (どのように無駄のないものにするか)、を考えてください。
17
+
18
+ 羽根(パルス)の数も、4(3)つあれば、それだけ識別に手間取りますし、間違いも起こります。
19
+ これは1つにすべきです。
20
+
21
+
22
+ ↓は、やはり羽根1つでのサンプルです。degree_get()をすればその時の角度(degree)*100で取得します。
23
+ 後はセンサーの設置位置に合わせて適当にオフセットを付ければ良いです。
5
- その辺り書き間違いなのか、本当にやりた事なか判断せん説明を明確にして下さい。
24
+ ループ関数何もしていない(↓はテスト用表示が入ってる)ので、自由に使え
25
+
26
+ ```Arduino
27
+ volatile word period;
28
+
29
+ void pulse_read() {
30
+ period=TCNT1;
31
+ TCNT1=0;
32
+ }
33
+
34
+ ISR (TIMER1_OVF_vect) {//低速、停止時に0にする為
35
+ period=0;
36
+ }
37
+
38
+ word degree_get() {//角度*100を返す
39
+ if(period==0)return 0;
40
+ return 36000UL*TCNT1/period;
41
+ }
42
+
43
+ void setup() {
44
+ Serial.begin(9600) ;
45
+ TCCR1A=0;
46
+ TCCR1B=2; //1/8=0.5us/countでタイマー1を回す
47
+ TIMSK1=1;//無回転等の判別用。まぁ無くてもOK
6
- 単にLレベルが1V程度、という事なら、バスを分圧で1Vにして、HIGH出力-High-Zで切り替えれば良いと思います。
48
+ attachInterrupt(0, pulse_read, RISING);//センサーD2ピン
49
+ tone(4,125);//8ms ※テスト信号。これをD2に入れる
50
+ }
51
+
52
+ void loop() {
53
+ Serial.print(period);
54
+ Serial.print(" ");
55
+ Serial.println(degree_get());
56
+
57
+ delay(300);
58
+ }
59
+ ```
60
+
61
+ プログラム的には超簡単です。(レジスタ操作は別として)
62
+ 解説すれば、外部割り込みで、パルスの上昇で割り込み(pulse_read関数)をかけています。(原点)
63
+ また、タイマー1(TCNT1)をストップウォッチのように使っています。
64
+ 割り込み時にタイマ値を読み取りリセットします。そのタイマー値は回転周期(period)です。
65
+ degree_get関数は回転周期と現在のタイマ値から割合を出し、36000をかけて戻しています。
66
+
67
+ ※実際にはtoneやSerialは消してください。