2008年10月16日木曜日

io.dll で Printer Port の読み込み

前に Python windows で ctypes と io.dll をつかって LPT Port に書き込みましたが、まだデータを読み込んでいませんでしたので、読み込んでみます。環境設定などは、前の記事を見てください。
読み込み自体はうまく行くのですが、表示を期待する形にするのにすこし手間がかかります。

プリンタポートの無い ノートパソコンでは実行しないでください。
プリンターポートのアドレス( 例では0x378)は、parmon.exe などを使って調べて、自分のパソコンのアドレスに合わせてください。
  1. ctypes をインポート
  2. io.dll の IsDriverInstalled という関数の答(1Bit の1か0)をもらって表示します。
  3. プリンターポートに 16進数で 55 の値を io.dll の PortOut 関数で書き込みます。
  4. 自分で書き込んだデータを io.dll の PortIn 関数で読み出します(8ビット)。
自分で「こう表示されるのだろう」と思う値と違う数が表示されるので、ちょっと途惑いますが、落ち着いて考えれば分かりますので、自分が期待する通りの表示になるように対策しましょう。

2.の問題は、1ビットのデータ、「1」の上位が全て 1詰めされて 数値上は -1。
8桁16進表示にすれば FFFFFFFF と 出るかと思うと、そこにも -1。
最下位ビットだけを ビット演算 And で取り出すとやっと思った結果に。

4.の問題は、8ビットだけのデータが欲しいのに上位に不要なデータが入ってるので思わぬ結果に。
16進表示にしても上位にどこから来たのか分からないデータが
16進表示の下二桁だけ表示すればいいかと思いましたが、またおかしい結果に
真面目に8ビットだけ and でマスクしてやっと希望の形になりました。

これは .dll が返す値のフォーマットと Python が受け取る(期待する)フォーマットの食い違いのせいです。本来 argなんとか、で極力合わせて使うべきなのでしょうが、つい(自分にとって)簡単な方向に流れがちで反省しています。将来の課題です。 argなんとか。。。

あぁ、ソースの折り返しがうまく出来てませんね。コピペして見てください。


#
# Win32 (XP)
# Python 2.5
# io.dll c:\windows\system32
#

from ctypes import *


a = 0 # initialize for test
a = windll.io.IsDriverInstalled()
print 'IsDriverInstalled ( decimal ) = ',a
print 'IsDriverInstalled ( 8 digits hex ?) = %(d)08X ' %{'d' :a}
print 'IsDriverInstalled ( 1 digit hex, masked ) = %(d)01X '%{'d' :a & 0x1}


port = 0x378
data_wr = 0x55
windll.io.PortOut(port,data_wr)
print 'PortOut ( 8 digits hex ) = %(d)08X ' %{'d' :data_wr}


data_rd = 0 # initialize for test
data_rd = windll.io.PortIn(port)
print 'PortIn ( decimal ) = ',data_rd
print 'PortIn ( 8 digits hex ) = %(d)08X ' %{'d' :data_rd}
print 'PortIn ( 2 digits hex ?) = %(d)02X ' %{'d' :data_rd}
print 'PortIn ( 2 digits hex, masked ) = %(d)02X '%{'d' :data_rd & 0xFF}

0 件のコメント: