前回購入して回路構成や動作などを解析した、遮断型赤外線センサモジュール(下図)を使って、パンチカードリーダを作ってみたいと思います。
前回記事では、簡単なパンチカードの仕様を策定した所で終わっていましたので、今回はパンチカードの工作(手作り)から開始します。
早速、実験用のパンチカードを手作りして行きたいと思います。
紙に穴を開ける必要があるので、紙の資料をファイルに閉じるために使う「穴あけパンチ器」を使います。
2穴ファイル(穴の直径は約5mm)に綴じるため、普通の穴あけパンチ器は同時に2個の穴が開く様になっています。パンチカードとしては1個ずつ穴あけする必要があるので、穴あけパンチ器に紙を斜めに差し込んで使います。穴あけパンチ器を使う都合上、穴は紙の端っこにしか開けられない事にも注意が必要です。
遮断型赤外線センサのLED→フォトトランジスタ対が対向しているのは、コの字型をしたセンサ本体の比較的先端なので、パンチカードをスライドさせる時に、紙に穴を開けた列と高さを合わせないと、読み取ることができません。
使用する遮断型赤外線センサの物理的特徴に合わせて工作する必要があると言う事です。
手持ちの遮断型赤外線センサでは、紙の端から約7mmの位置に、LED→フォトトランジスタの対向軸がありました。つまり、紙の端っこから、7mmの位置を中心として、直径5mmのパンチ穴を規則的に並べる、と言う、結構精密な工作が要求されます。
穴あけパンチ器で穴を開けるので、当初は普通のコピー用紙などを使おうと目論んでいました。
ところが!
遮断型赤外線センサのLED→フォトトランジスタ間にコピー用紙を挟んだところ、赤外線を遮断することができませんでしたm(1@〜@)m。
コピー用紙では薄すぎて、赤外線が透過してしまったのです。
これではダメ。
コピー用紙を2つ折り→4つ折り→…として、厚さを増やして試して行きましたが、むなしく透過し続け、漸く8つ折りにしたところで遮断することができました。
※実は、8つ折りでも、赤外線が透過してしまう場合がありました。しかし、これ以上紙を重ねてしまうと、小型の穴あけパンチ器では穴を開けられなくなってしまうため、8つ折りでごまかしながら実験することとしました。例えば、センサに対して紙を斜めにセットすると、赤外線の反射量が増加して、透過し難くなることを利用します(フレネルの式)。
上図は、実験動画から切り出した、遮断型赤外線センサに手作りのパンチカードを挟んだ状態の写真です。CMOSセンサカメラを内蔵した、スマホなどのカメラで撮影すると、人間の目には見えない赤外線の発光を確認することができます。
丸で囲んだ部分に、紙の向こう側で光る、薄紫色のIR LED発光が確認できます。8つ折りのパンチカードでも、薄らと透過していることが判りますね。
なお、赤外線が透過しない紙の厚さ(枚数)は、以下の要素で変動します。
赤外線LEDの発光強度に関して補足すると、LEDに流す順方向電流の大きさによって、発光強度は異なります。順方向電流Ifについては、LEDと直列に設置した電流制限抵抗R、電源電圧V、LEDの順方向電圧Vfを使って、以下の関係が成立します。
V−Vf=If×R
ご使用になる遮断型赤外線センサの回路定数(R、Vf)と、供給する電源電圧(V)で変動するので、各自確かめて調整してください。
なお今回は、出来合いのセンサモジュールを購入してしまったので調整できないのですが、単体のセンサ素子を購入してきて周辺回路を手作りする場合、赤外線LEDの電流制限抵抗を大きく設定して電流を絞ると、赤外線強度が低下して、薄い紙でも透過できない様にして使う事は可能かもしれません。
こちらの目標仕様に従うと、ビット値0と1では、1の符号の方が長くなると指摘してありました。一般的な穴あけパンチ器の場合、穴の直径は約5mmです。穴の直径5mmが、開口部(○)の直径Lとなるので、符号長は以下の通りです。
コピー用紙に着目すると、一般的な規格の場合、大きさは以下の通りです。
なので、最長16cmのコードを作成するためには、A5サイズの短辺では足りず、少なくともA5サイズの長辺ほどの長さが必要だと解ります(B5サイズなら、短辺でも可)。手作りのパンチカードになるので、少し余裕をもって作成できる様、A4サイズのコピー用紙を使い、短辺側(21.1cm)を8つ折りにして厚さを確保の上、使う事に決めました。
色々と制約が多くて実用的ではないけれど、遮断型赤外線センサモジュールの試用・試行が目的なので、今回一回だけ実験できれば良しとして見てくださいm(1__)m。
実験に備えて、パンチカードを工作しておきましょう。
ここでは、データ=0x75のパンチカードを工作します。目標仕様に従うと、フレームデータは、0b_0_0111_0101_1_1=0x1d7ですので、以下表の通りに工作すれば良いことが判ります。
データ 0x75 |
スタ ート |
データ(ビット) |
パリ ティ |
スト ップ |
終端 | |||||||
7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | |||||
ビット値 | 0 | 0 | 1 | 1 | 1 | 0 | 1 | 0 | 1 | 1 | 1 | − |
パンチ穴 | ○− | ○− | ○−− | ○−− | ○−− | ○− | ○−− | ○− | ○−− | ○−− | ○−− | ○ |
長さ[mm] | 10 | 10 | 15 | 15 | 15 | 10 | 15 | 10 | 15 | 15 | 15 | Σ150 |
上表から工作した実際のパンチカードを以下図に示します。
機械的に開けた穴と違い、定規で距離を測りながら手作業で開けた穴なので、多少(?)のばらつきがあるのが見て取れますね。そもそも、スキャンするのも人の手で実行する事になるので、そこにも歪みが発生します。
→ コード全体をスキャンする間、一定の速度でパンチカードをスライドし続けることができるか?と言う課題もある、と言う事です。
ちゃんと読み出せるかどうか?については、後ほど実験で確かめてみましょう。同様にもう一つ、データ=0x9c(フレーム=0b_0_1001_1100_0_1=0x271)のカードも作って備え、先へ進みます(下表)。
データ 0x9c |
スタ ート |
データ(ビット) |
パリ ティ |
スト ップ |
終端 | |||||||
7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | |||||
ビット値 | 0 | 1 | 0 | 0 | 1 | 1 | 1 | 0 | 0 | 0 | 1 | − |
パンチ穴 | ○− | ○−− | ○− | ○− | ○−− | ○−− | ○−− | ○− | ○− | ○− | ○−− | ○ |
長さ[mm] | 10 | 15 | 10 | 10 | 15 | 15 | 15 | 10 | 10 | 10 | 15 | Σ140 |
ソフトウェアの方は、普通にdigitalRead()関数で汎用I/Oポートをサンプリングしながら、0/1データを復号するだけの事ですので、詳細は省略します。完成したプログラムを以下にリンクしておきますので、ご確認ください。
完成プログラム:pcard_reader.ino
Arduino UNOへコンパイル&書き込みすると、シリアルモニタから以下のコマンドを受け付ける様になっています。
シリアルモニタコマンド仕様:
工作したパンチカードを読み取って見る前に、【capt】コマンドを使って予備実験をしてみたところ、相対的に、開口部の方が閉口部よりも長く計測される傾向にあることが判りました。
開口部の長さLo≒閉口部の長さLc×(1.1〜1.2)と、10〜20[%]ほど長めに計測されます。恐らく、LEDの光が拡散したり、回折、反射するなどして、長めに計測されるのだと推測しました。
よって、Loの平均値Lo(AVE)を求めた後で、以下の様に補正して使う事としました。
Lo(AVE)’=Lo(AVE)×pcr_CORV÷100
お使いの環境によっては、プログラム先頭付近の定数pcr_CORVで調整してください。
const int pcr_CORV=85; // pcr: punch width correction value [%]
補正しない場合は、pcr_CORV=100です。
Arduino UNOと、遮断型赤外線センサモジュール、アクティブブザーを、以下表に従って接続してください。
アクティブブザー | 接続 | Arduino UNO | 接続 | 遮断型赤外線センサ |
5V | → | VCC | ||
GND | ⇔ | GND | ||
D2 | ← | OUT | ||
+端子 | ← | D12 | ||
−端子 | ← | D9 |
※アクティブブザーは、UNOのピンソケットに直挿しできる端子を選択してあります。D9端子には、常にLOWレベルが出力されていて、GNDの代わりとして機能させています。
以下図に実験中の様子を示します。
シリアルモニタを開いて、実験を進めて行きましょう。
実験サンプル:【 】内はシリアルモニタからの送信データ
【scan】
OK+ Start scan
OK+ data=0x75
OK: scan(0x1d7)
まず、準備として、【scan】コマンドを実行する前に、パンチカードの閉口部をセンサの間に挟んでください。【scan】コマンドを実行したら、パンチカードをスライドさせて、コード全体をスキャンさせます。
プログラムでは、以下の時間的制約が存在していますので、留意してください。
逆に言うとpcr_msec_SCAN[ms]の余裕があるので、その時間を目いっぱい使って、ゆっくりスキャンした方が読み取り精度の向上が期待できます。と言って人間の動作は、一定の速度で遅く動かすことは苦手なので、逆に、ある程度速く動かした方が速度を一定に保てる、かも、知れませんね……。
何パタンか試して、読み取り確度の高くなる動かし方を探ってみてください。
エラー無く読み出せた場合は「OK:」、エラーが発生した場合は「ERR:」応答が返ります。
実験サンプル:【 】内はシリアルモニタからの送信データ
【scan】
OK+ Start scan
OK+ data=0x9c
OK: scan(0x271)
他のパンチカードも読み込んでみました。
前節の実験サンプルでは都合上、成功例だけを示しましたが、うまく読み取れないことも、しばしばです。
「符号長を短くしたい」という気持ちが先に立ってしまい、仕様上、0/1を符号化する閉口部の長さに十分なクリアランスが無いため、誤読み取りが多発する傾向にあります。
実用化を目指したものではなく、遮断型赤外線センサの動作確認の一環なので、大目に見てください。
もし何等か、実用的に使う意図があるのであれば、もう少し符号化仕様を考え直した方が良いでしょう……。
最後に、パンチカードを読み取っている様子を動画でご確認ください。
別な目的で購入した遮断型赤外線センサの動作確認を目的とした試行として、パンチカードリーダを作成してみました。遮断型赤外線センサモジュールの使い方を試す、という目的を果たすことができたと思います。