ArduinoUNOでロータリエンコーダを2逓倍と4逓倍して読む
前回に引き続き、いまだに重い腰を上げてArduinoのスケッチ例を試してArduinoの使い方を学んでみる。少し正確な角度検出をしたくなったので、Amazon で中華製ロータリーエンコーダを購入してArduinoで回転角度を測れるようにしてみた。今回は波形を2逓倍/4逓倍して読みとり。
ロータリーエンコーダ信号の2逓倍・4逓倍
逓倍とは
逓倍とは、ロータリーエンコーダの信号周期や発振器の周期をx倍すること。これをすることとで、ロータリーエンコーダの分解能を2倍、4倍とすることが出来る。そして、ロータリーエンコーダにはA,B相の2つの信号があるので2逓倍や4逓倍にすることは簡単だ。例えば下図のとおり、A相の立ち上がりエッジだけで読んでいたものを、立ち上がりエッジと立ち下がりエッジの両方で読むことで2逓倍とすることができてる。さらにA相の両方のエッジとB相の両方のエッジで読めば、4倍エッジとなる。
逓倍デメリット
逓倍の説明を読んだだけだと、分解能を簡単に上げることが出来る素晴らしいもののように見えるが当然デメリットもある。代表的なデメリット2つをしたに挙げる。
- ノイズに対して弱くなる。
- デジタル入力割り込み等で読み出すと読み飛ばしやすくなる
- デジタル入力割り込み等で読み出すと接続できるロータリーエンコーダの数が減る
まず、ノイズに対してだが、これは立ち上がりエッジのみでカウントアップしていたものを両方のエッジでカウントアップすると、ノイズが一回入ると2回反応してしまうことになる。また、光学式ではないロータリーエンコーダの場合はチャタリングが発生することがある。その場合は何も対策をしないと、動かした角度と検出した角度が全く違うということになりかねない。一方で、光学式の場合はチャタリングはないが配線に乗ったノイズ等の影響は少なからず受ける。
次に、読み飛ばしやすくなるという点だが、これは前回や今回のArduinoスケッチの場合は信号エッジが来たらCPUが現在の処理を停止→関数を呼び出し→デジタル入力の状態を把握→カウントアップ・ダウン→割り込み発生前の処理に戻るという処理をする。この処理をエッジが来るたびに行う必要があるので、ロータリーエンコーダの信号周波数が一定以上高くなると正確にカウントアップ・ダウンが出来なくなってしまう。
ロータリーエンコーダの数が減るとは、例えば ArduinoUNOではデジタル入力割り込みに対応しているPINは2つしかないので、2逓倍までの場合はロータリーエンコーダを2つ接続して読み出すことが出来るが、4逓倍の場合は1つしか接続できない。
逓倍デメリットに対しての対処
以上、上げたデメリットに対してどのように対処するかというと、一番大事なことは今構築しようとしているシステムに必要なロータリーエンコーダの分解能はどの程度か見極めることだ(単純に逃げる)。
例えば、一回転500分割できれば十分なのに一回転1000パルスのロータリーエンコーダのを使用して、Arduinoで4逓倍すると必要な分解能の4倍となる。この場合は分解能としては要件を満たしているが、ノイズや読み飛ばしというリスクが必要以上に大きくなってしまう。
一方で、測定器などの用途でゆっくりとしか動かないが、エンコーダの分解能の優先度が一番高いという場合。4逓倍して入力回転数を制限することで、システムの要件を満たせるかもしれない。
それでも、4逓倍して高速にしたい場合は、ハードウェア読み込みをした方が良い。
エンコーダの数に関しては2つ繋げたい場合は、より高性能なマイコンボードを使う、ハードウェア読み込みをする、複数のマイコンでそれぞれ読み取り、相互通信する。などの選択肢がある。
例えばArduinoUNOより高性能なArduinoMegaでは入力割り込みとして使えるピンが6つある。また、Arduino Dueではすべてのピンを入力割り込みとして割り当てられるらしい。2000円程度しかArduinoUNOと変わらないので、他の性能差も見るとArduinoUNOを複数買うより性能を高い方を買った方がよさそう。
ハードウェア読み込み
どうしても回転速度が速く分解能が高くないといけないという場合はまず、ハードウェアでカウントするべきだ。ハードウェアカウントにはZEN2014Fなどの専用ICを使う方法と、”位相計数モード”のような機能が搭載されているマイコンを選定する方法だ。
位相計数モードは、デジタル入力割り込みで処理するのではなく周辺機能で設定するだけでCPUに関係なくロータリーエンコーダの信号をカウントする機能で、オーバーフローだけ気にしていれば勝手に読みっているのでソフトウェア設計がラクになる。 ArduinoUNO(ATmega328P)にはその機能が無いはず。RX220などにはあるので、そのようなマイコンを使った方がラクだと思う。
Arduino スケッチ
ロータリーエンコーダの波形を2逓倍して読み取る。
これはA相の立ち上がりエッジ、立ち下がりエッジの両方で割り込みをして、B相とZ相の入力を読んでいる。そのため、前回記事のスケッチよりも高速なロータリーエンコーダの回転ではパルスを読み飛ばしてしまう。
また、Pin3に別のロータリーエンコーダを接続してそれぞれのB相を通常の入力ピンに接続すれば2つまでロータリーエンコーダのカウントを読むことが出来る。
ロータリーエンコーダの波形を4逓倍してよみとる
これはA相の両方のエッジで割り込みをして、B相とZ相の入力を読んでいる。そのため、2逓倍のスケッチよりもさらにロータリーエンコーダはパルスを読み飛ばしてしまうので低速で回転する用途で使う必要がある。