グレイコード

グレイコード(Gray code)とは、2進数の表現で、隣り合う値でビットの変化が1ビットしかないようにしたものです。

たとえば、4桁の2進数(バイナリコード)で考えると、
10進数の「7」から「8」に変化する場合、2進数では「0111」から「1000」となり、
4桁すべてのビットが0から1または、1から0へと変化します。

電気(電子)回路では、2進数の「0」、「1」を電圧の高い状態「H」と低い状態「L」で扱います。
入力回路は、「H」と「L」を検出する速度が異なります。
(Turn on time および Turn off time が異なる)

上記の「7」から「8」に変化する場合、入力回路の遅延により、
最悪「1111」または「0000」の値として読み込む可能性があります。
10進数の「15」または「0」となってしまいます。

ロータリエンコーダ(回転位置検出センサ)で、回転する軸の角度を検出する場合、
軸の角度の変化するタイミングで、誤った値として取り込むことになります。

そこで、一般的には、グレイコードを使用します。
グレイコードの場合、隣り合う数値で、ビットの変化が1ビットしかないので、
入力回路の遅延により、誤って読みこんでも、
隣り合う数値での誤差になるだけです。

グレイコード

グレイコードを2進数(バイナリコード)に変換するには、次のように考えます。

グレイコードの最上位ビットは、そのままバイナリコードの最上位ビットとします。
グレイコードの下位ビットが「1」の場合、バイナリコードの上位ビットを反転した値を下位ビットとします。
グレイコードの下位ビットが「0」の場合、バイナリコードの上位ビットをそのまま下位ビットとします。
以下同様に最下位ビットまで処理します。

プログラマブルコントローラ(PLC)のラダー回路で表現すると、
4桁のグレイコードの場合、下図の通りです。
ここでG3〜G0はグレイコード、B3〜B0はバイナリコードの各ビットです。
(シーケンサーは、和製英語です。英語では、Programmable Logic Controllerです。)

桁数が多くなった場合は、同様に拡張してください。

一般的なPLCの場合は、プログラムのスキャンは、左から右のあと上から下へと読み込まれますが、
(株)安川電機様のPLCでは、ひとつのセグメント内でプログラムのスキャンが上から下のあと左から右へと読み込まれます。
この場合は、各ビットごとに、セグメントを分けてください。ひとつのセグメントにまとめてしまうと、正しく変換できません。

グレイコードからバイナリへの変換回路

ロータリエンコーダで角度検出する場合、76余りグレイコード(Excess 76 gray code)が用いられます。
角度(0〜359°)を2進数で表現しようとすると9ビット(0〜511)必要になります。

ここで、値を「ゼロ」からスタートするのではなく、「76」からスタートするようにしたものです。
「0〜359」を「76〜435」として表現します。

76からスタートすると、「179°」のとき、
76+179=255となり、
2進数で「011111111」
グレイで「010000000」

「180°」のとき、76+180=256となり、
2進数で「100000000」
グレイで「110000000」

つまり、180°を境に最上位ビットが反転したコードで読み取れます。

また、「359°」から「0°」に変わるときは、
359+76=435
2進数で「110110011」
グレイで「101101010」

0+76=76
2進数で「001001100」
グレイで「001101010」

ここでも、1ビットの変化しかありません。

読み込んだ数値を、角度として使用するには、
グレイコードを2進数に変換したあとに、「76」を引けばよいだけです。

ロータリエンコーダとPLCの接続についてはこちらも参照ください。

バイナリコードをグレイコードに変換するには、次のように考えます。

バイナリコードの最上位ビットは、そのままグレイコードの最上位ビットとします。
次の下位ビットは、バイナリコードの上位ビットと下位ビットの排他的論理和(Exclusive OR)をとります。
以下同様に最下位ビットまで処理します。

プログラマブルコントローラのラダー回路で表現すると、
4桁のバイナリコードの場合、下図の通りです。

バイナリからグレイコードへの変換回路