2023年9月 この範囲を時系列順で読む この範囲をファイルに出力する
Python での Open DMX USB の制御は8時間経過でも正常に動いている様子。
不定期に一瞬の不整合が起きているとしても確認の方法がありません。とりあえずこんなもんでいいのかな?
この後は Class 化と Thread 化をします。Thread 間通信は Queue ではなく 共有メモリを使いましょう。共有メモリは Tuple を FIFO で使うような便利なことは出来ませんが、今回は数値の配列を一方向で渡すだけですので、速度が期待できる共有メモリがいいでしょう。
下記は Thread ではなく Prosess の例題ですが、共有メモリのさわりが分かりやすい。
「Pythonでプロセス間の値の共有」
#Python #器具の製作
不定期に一瞬の不整合が起きているとしても確認の方法がありません。とりあえずこんなもんでいいのかな?
この後は Class 化と Thread 化をします。Thread 間通信は Queue ではなく 共有メモリを使いましょう。共有メモリは Tuple を FIFO で使うような便利なことは出来ませんが、今回は数値の配列を一方向で渡すだけですので、速度が期待できる共有メモリがいいでしょう。
下記は Thread ではなく Prosess の例題ですが、共有メモリのさわりが分かりやすい。
「Pythonでプロセス間の値の共有」
#Python #器具の製作
Python で Open DMX USB を動かすことに成功しました。
setbreakon と setbreakoff の挙動は予想の通りでした。
以下がテストソースです。
slot1 と slot512 を 0 から255 までカウントして終了します。
### Open DMX USB test ###
import ftd2xx as ftd
import time
if __name__ == '__main__' :
baudrate = 250000
word_length = 8
stop_bit = 2
parity = 0
purge_tx = 2
try :
d = ftd.open( 0 ) # Open first FTDI device
d.setBaudRate( baudrate )
d.setDataCharacteristics( word_length, stop_bit, parity )
d.purge( purge_tx )
channelVals = bytearray( [ 0 ] * 513 )
channelVals[ 0 ] = 0 # start code
for i in range( 256 ) :
try :
channelVals[ 1 ] = i
channelVals[ 512 ] = i
channelbytes = bytes( channelVals )
# Send Slot
cstart = time.perf_counter_ns( )
d.write( channelbytes )
while time.perf_counter_ns( ) - cstart < 22800000 :
pass
# Break Time
d.setBreakOn( )
cstart = time.perf_counter_ns( )
while time.perf_counter_ns( ) - cstart < 192000 :
pass
# Mark After Break
d.setBreakOff( )
cstart = time.perf_counter_ns( )
while time.perf_counter_ns( ) - cstart < 12000 :
pass
# Press Ctl+C to Exit
except KeyboardInterrupt :
break
d.close( )
except :
print( 'No Device' )
time.sleep() は求める精度に足りないので time.perf_counter_ns() を用いています。
0 から 255 のカウントが5.9秒強で終わるので 43fps くらい。ほぼ規格最大値です。
本当にコレでいいのかわからんけど、モヤモヤしてたのがスッキリした。
#Python #器具の製作
setbreakon と setbreakoff の挙動は予想の通りでした。
以下がテストソースです。
slot1 と slot512 を 0 から255 までカウントして終了します。
### Open DMX USB test ###
import ftd2xx as ftd
import time
if __name__ == '__main__' :
baudrate = 250000
word_length = 8
stop_bit = 2
parity = 0
purge_tx = 2
try :
d = ftd.open( 0 ) # Open first FTDI device
d.setBaudRate( baudrate )
d.setDataCharacteristics( word_length, stop_bit, parity )
d.purge( purge_tx )
channelVals = bytearray( [ 0 ] * 513 )
channelVals[ 0 ] = 0 # start code
for i in range( 256 ) :
try :
channelVals[ 1 ] = i
channelVals[ 512 ] = i
channelbytes = bytes( channelVals )
# Send Slot
cstart = time.perf_counter_ns( )
d.write( channelbytes )
while time.perf_counter_ns( ) - cstart < 22800000 :
pass
# Break Time
d.setBreakOn( )
cstart = time.perf_counter_ns( )
while time.perf_counter_ns( ) - cstart < 192000 :
pass
# Mark After Break
d.setBreakOff( )
cstart = time.perf_counter_ns( )
while time.perf_counter_ns( ) - cstart < 12000 :
pass
# Press Ctl+C to Exit
except KeyboardInterrupt :
break
d.close( )
except :
print( 'No Device' )
time.sleep() は求める精度に足りないので time.perf_counter_ns() を用いています。
0 から 255 のカウントが5.9秒強で終わるので 43fps くらい。ほぼ規格最大値です。
本当にコレでいいのかわからんけど、モヤモヤしてたのがスッキリした。
#Python #器具の製作
Open DMX USB の BreakTime について考えていたところ PIC の BreakTime についてもアイデアが出ました。
拡張ミッドレンジPIC16系の EUSART には Break 機能があります。ただし、11bit分の L を出力して StopBit(H) を出すまでが一連の動作なので2回繰り返しても DMX512 の BreakTime にはなりません。今は I/O ピンをプルダウンしておき、入出力設定(TRIS)を Input(Hi-Z) にしてから捨て送信をすることで BreakTime を作っています。
本題です。DMX512 の BreakTime は 最小 88usec ですから 250kbps なら 22bit 分の連続した L を出力すれば成立します。PIC16系の EUSART の Break が DMX512 の BreakTime に使えないのはこれが理由ですが、BaudRate を変更した Break を出力したらよくね?ってのが今回のアイデアです。手段を問わず、L 送信が 88usec 以上ならいいのです。私の理解が間違っていなけば、アイドル時なら BaudRate をバイト送信毎に変更しても EUSART は正しく動くハズです。単純計算なら BaudRate を半分にすれば規格値が出ます。現状でも BaudRate の調整だけで 1/50 くらいには出来ますから十分な BreakTime を作れると思われます。もちろん、BaudRate を 1/3 以下にして Break ではなく 0x00 を通常出力しても同じことです。こちらの方が汎用性が高いかも。受信も併用する構成ではNGですけどね。
この方法が成立すればプルダウン抵抗は不要です。たった一つの抵抗ですが、部品を減らすことは絶対の正義ですので検討する価値はありそうです。
#PIC #器具の製作
拡張ミッドレンジPIC16系の EUSART には Break 機能があります。ただし、11bit分の L を出力して StopBit(H) を出すまでが一連の動作なので2回繰り返しても DMX512 の BreakTime にはなりません。今は I/O ピンをプルダウンしておき、入出力設定(TRIS)を Input(Hi-Z) にしてから捨て送信をすることで BreakTime を作っています。
本題です。DMX512 の BreakTime は 最小 88usec ですから 250kbps なら 22bit 分の連続した L を出力すれば成立します。PIC16系の EUSART の Break が DMX512 の BreakTime に使えないのはこれが理由ですが、BaudRate を変更した Break を出力したらよくね?ってのが今回のアイデアです。手段を問わず、L 送信が 88usec 以上ならいいのです。私の理解が間違っていなけば、アイドル時なら BaudRate をバイト送信毎に変更しても EUSART は正しく動くハズです。単純計算なら BaudRate を半分にすれば規格値が出ます。現状でも BaudRate の調整だけで 1/50 くらいには出来ますから十分な BreakTime を作れると思われます。もちろん、BaudRate を 1/3 以下にして Break ではなく 0x00 を通常出力しても同じことです。こちらの方が汎用性が高いかも。受信も併用する構成ではNGですけどね。
この方法が成立すればプルダウン抵抗は不要です。たった一つの抵抗ですが、部品を減らすことは絶対の正義ですので検討する価値はありそうです。
#PIC #器具の製作
オレメモです。
Open DMX USB が期待通りに動かないのは BreakTime が正しく出ていないのが原因かと予想しています。
FTD2xx には setbreakon と setbreakoff がありますのでこれを使うのが肝だと思われますが、これらのコマンドを実行するだけでは求める BreakTime に至らないのだろうと思われます。
違うライブラリを用いたソースコードでは Break を有効化するコマンドが2回と Break 無効化するコマンドが続きで書いてありましたので FTD2xx では Break に関するコマンドを発行すると1バイト分の送信が行われるのかな?と思っていました。2バイト分ですと BreakTime の最小時間と等しいですからね。
検証しないとわかりませんが、setbreakon と setbreakoff は FT232RL の動作モードを変える( setbreakon を実行すると待機状態が L となる / setbreakoff を実行すると待機状態が H に戻る)だけで Break の時間を確保するものではないってのが現在の予想です。テストプログラムでは setbreakon を2回、setbreakoff を1回実行していましたが、setbreakon と setbreakoff の間に空送信か待ち時間を入れてみようと思います。まずは time.sleep( 0.001 ) (Windowsだと15msec前後になる)を差し込むことから始めて setbreakon の状態で空送信をしたらどうなるかです。
#Python #器具の製作
Open DMX USB が期待通りに動かないのは BreakTime が正しく出ていないのが原因かと予想しています。
FTD2xx には setbreakon と setbreakoff がありますのでこれを使うのが肝だと思われますが、これらのコマンドを実行するだけでは求める BreakTime に至らないのだろうと思われます。
違うライブラリを用いたソースコードでは Break を有効化するコマンドが2回と Break 無効化するコマンドが続きで書いてありましたので FTD2xx では Break に関するコマンドを発行すると1バイト分の送信が行われるのかな?と思っていました。2バイト分ですと BreakTime の最小時間と等しいですからね。
検証しないとわかりませんが、setbreakon と setbreakoff は FT232RL の動作モードを変える( setbreakon を実行すると待機状態が L となる / setbreakoff を実行すると待機状態が H に戻る)だけで Break の時間を確保するものではないってのが現在の予想です。テストプログラムでは setbreakon を2回、setbreakoff を1回実行していましたが、setbreakon と setbreakoff の間に空送信か待ち時間を入れてみようと思います。まずは time.sleep( 0.001 ) (Windowsだと15msec前後になる)を差し込むことから始めて setbreakon の状態で空送信をしたらどうなるかです。
#Python #器具の製作
「ftd2xx.py」を使って Open DMX USB から DMX512 が出るか試してみました。
うまくいかない・・・。
値は表示されますが、テストプログラムでは値を変化させているのにそれが出ません。Break Time あたりに問題があるように思いますが、オシロスコープかロジアナで信号波形を見ないとわかりません。
波形を見るにはテスト環境を整えないといけませんので空き時間にちょっとお試しってワケにはいきません。しばらくお預けです。
そんでも、値は一応表示されるのであまり遠くないところにいるような気がします。
頑張って読み解くしかない本家の資料
「D2XX Programmer's Guide」
#Python #器具の製作
うまくいかない・・・。
値は表示されますが、テストプログラムでは値を変化させているのにそれが出ません。Break Time あたりに問題があるように思いますが、オシロスコープかロジアナで信号波形を見ないとわかりません。
波形を見るにはテスト環境を整えないといけませんので空き時間にちょっとお試しってワケにはいきません。しばらくお預けです。
そんでも、値は一応表示されるのであまり遠くないところにいるような気がします。
頑張って読み解くしかない本家の資料
「D2XX Programmer's Guide」
#Python #器具の製作
「ftd2xx.py」ですが、Open DMX USB を認識しました。
テストで使ったのは次のコード
### ftd2xx test ###
import ftd2xx as ftd
if __name__ == '__main__' :
try :
d = ftd.open( 0 ) # Open first FTDI device
d.setDataCharacteristics
print( d.getDeviceInfo( ) )
d.close( )
except :
print( 'No Device' )
exit( )
### 実行結果 ###
{'type': 5, 'id': 67330049, 'description': b'FT232R USB UART', 'serial': b'B000T33S'}
実行結果は期待値を得ています。「ftd2xx.dll」を通じて FT232RL とやり取りが出来ていると思われますので、Open DMX USB として動かせそうな気がします。
今後は「ftd2xx.dll」の解説書とソースコード読みながら解明していきましょう。
#器具の製作 #Python
テストで使ったのは次のコード
### ftd2xx test ###
import ftd2xx as ftd
if __name__ == '__main__' :
try :
d = ftd.open( 0 ) # Open first FTDI device
d.setDataCharacteristics
print( d.getDeviceInfo( ) )
d.close( )
except :
print( 'No Device' )
exit( )
### 実行結果 ###
{'type': 5, 'id': 67330049, 'description': b'FT232R USB UART', 'serial': b'B000T33S'}
実行結果は期待値を得ています。「ftd2xx.dll」を通じて FT232RL とやり取りが出来ていると思われますので、Open DMX USB として動かせそうな気がします。
今後は「ftd2xx.dll」の解説書とソースコード読みながら解明していきましょう。
#器具の製作 #Python
以下を参考に少し試してみました。
「Programming FTDI devices in Python: Part 1」
Open DMX USB や FT232RL が実装されたデバイスが手元にありませんので何ともですが、pip で ftd2xx をインストールするとVSCode ではそれらしい関数の候補が出ます。候補が出るということはアクセスできる可能性が高いという事です。
> pip install ftd2xx
pywin32 もインストールされます。
「ftd2xx」のサイト見ますと、「ftd2xx は、ctypes を使用した FTDI の D2XX DLL の単純な Python ラッパーです。」とあります。
システムコールを直球で使えるってことだと思われます。
「jlbrogdon/dmx_controller」
ここで使われている関数とは呼び出す文言が違いますが、VSCode で表示される関数の候補にはそれと思われる関数が存在しています。
明日以降になりますが FT232RL が実装されたデバイスを繋げた状態で色々テストしてみましょう。
今考えているアイデアでいけるなら Open DMX USB の制御が Python で完結します。
これはいいかも
「Ftd2xxドライバー説明」
本家の資料では理解出来なかったことが分かりやすく書いてあります。欲しかった資料そのものです。
「ftd2xx.py」
「xiangruili/RTBox_py」
これらの資料で行けそうな予感がムクムク。
ENTTEC 純正の Open DMX USB と DMXチェッカーを事務所に置いてきたことを後悔。
すでに帰宅して呑んでいるので取りに行けませんので明日以降ですね。
それにしても、敷居が高いと思っていた DLL をここまで簡単に使えるとは予想外です。
ドライバに対する DLL があれば、少なくともC/C++なら簡単にアクセスが可能で、それを単純なラッパーにしてしまえば Python からストレスなくアクセス出来てしまうのです。
この辺りの手段は手にしたいですねぇ~。
#Python #器具の製作
「Programming FTDI devices in Python: Part 1」
Open DMX USB や FT232RL が実装されたデバイスが手元にありませんので何ともですが、pip で ftd2xx をインストールするとVSCode ではそれらしい関数の候補が出ます。候補が出るということはアクセスできる可能性が高いという事です。
> pip install ftd2xx
pywin32 もインストールされます。
「ftd2xx」のサイト見ますと、「ftd2xx は、ctypes を使用した FTDI の D2XX DLL の単純な Python ラッパーです。」とあります。
システムコールを直球で使えるってことだと思われます。
「jlbrogdon/dmx_controller」
ここで使われている関数とは呼び出す文言が違いますが、VSCode で表示される関数の候補にはそれと思われる関数が存在しています。
明日以降になりますが FT232RL が実装されたデバイスを繋げた状態で色々テストしてみましょう。
今考えているアイデアでいけるなら Open DMX USB の制御が Python で完結します。
これはいいかも
「Ftd2xxドライバー説明」
本家の資料では理解出来なかったことが分かりやすく書いてあります。欲しかった資料そのものです。
「ftd2xx.py」
「xiangruili/RTBox_py」
これらの資料で行けそうな予感がムクムク。
ENTTEC 純正の Open DMX USB と DMXチェッカーを事務所に置いてきたことを後悔。
すでに帰宅して呑んでいるので取りに行けませんので明日以降ですね。
それにしても、敷居が高いと思っていた DLL をここまで簡単に使えるとは予想外です。
ドライバに対する DLL があれば、少なくともC/C++なら簡単にアクセスが可能で、それを単純なラッパーにしてしまえば Python からストレスなくアクセス出来てしまうのです。
この辺りの手段は手にしたいですねぇ~。
#Python #器具の製作
Open DMX USB を扱うには FTD2XX.dll をコールするのが肝らしい。
チンプンカンプンな領域なのでこれから勉強ですが、次のサイトがヒントになりそう。
「PythonからDLLを使う」
「Python から DLL を利用する」
「C++で書いたコードをPythonで動かすには【pybind11】」
以下も参考になりそう。
「USBを使って制御できるリレーモジュールをpythonで動かしてみる」
「Programming FTDI devices in Python: Part 1」
上記の記事と以下を合わせるといけるのかな?
「jlbrogdon/dmx_controller」
#Python
チンプンカンプンな領域なのでこれから勉強ですが、次のサイトがヒントになりそう。
「PythonからDLLを使う」
「Python から DLL を利用する」
「C++で書いたコードをPythonで動かすには【pybind11】」
以下も参考になりそう。
「USBを使って制御できるリレーモジュールをpythonで動かしてみる」
「Programming FTDI devices in Python: Part 1」
上記の記事と以下を合わせるといけるのかな?
「jlbrogdon/dmx_controller」
#Python
ENTTEC 純正の Open DMX USB を入手しました。
しかし、先日調べたネタではデバイスの認識すらしません。README.md を読み返したところRaspberryPi用でした。動かなくても仕方ない。
調べ直したところGitHubに次の様なモノがありました。
「PyOpenDmxUsb」
README.md を読む限り、Windows 上の Python で Open DMX USB を扱う代物のようです。
使い方が少し難しいようですが、調べてみる価値はありそうです。
追記
「PyOpenDmxUsb」
は予想外に簡単でした。
1)pip で pywin32 をインストール
> pip install pywin32
2)GitHub からダウンロードしたファイルを メインの Python ソースがあるフォルダにまとめる。
・フォルダ「PyOpenDmxUsb-master」内の「C#」フォルダにある「DMXServer.exe」。
・フォルダ「PyOpenDmxUsb-master」内の「Python」フォルダにある「DMXClient.py」。
あとは、サンプルプログラムを参考にソースを書きます。
from DMXClient import DMXClient
import time
dmxClient = DMXClient("PODU")
dmxClient.connect()
while True :
for i in range( 256 ) :
try :
dmxClient.write([1, i, 2, i])
time.sleep( 0.1 )
except KeyboardInterrupt:
dmxClient.close()
break
break
DMX の アドレス001とアドレス002をカウントしていくだけの動作を確認出来ました。
コマンドコンソールか PowerShell から DMXServer.exe を起動してから上記の Python コードを実行します。
> .\DMXServer -n PODU
この後、別コマンドコンソールから Python コードを実行します。
DMXServer.exe を起動してから本プログラムを実行する手順が少し面倒だし Python らしくない。
出来ることなら Python モジュールとして import して使えるようにしたいと思います。
DMXServer.exeのC#ソースが付属しているので、これを参考に Python モジュールを作れたらいいのかな?
#器具の製作
しかし、先日調べたネタではデバイスの認識すらしません。README.md を読み返したところRaspberryPi用でした。動かなくても仕方ない。
調べ直したところGitHubに次の様なモノがありました。
「PyOpenDmxUsb」
README.md を読む限り、Windows 上の Python で Open DMX USB を扱う代物のようです。
使い方が少し難しいようですが、調べてみる価値はありそうです。
追記
「PyOpenDmxUsb」
は予想外に簡単でした。
1)pip で pywin32 をインストール
> pip install pywin32
2)GitHub からダウンロードしたファイルを メインの Python ソースがあるフォルダにまとめる。
・フォルダ「PyOpenDmxUsb-master」内の「C#」フォルダにある「DMXServer.exe」。
・フォルダ「PyOpenDmxUsb-master」内の「Python」フォルダにある「DMXClient.py」。
あとは、サンプルプログラムを参考にソースを書きます。
from DMXClient import DMXClient
import time
dmxClient = DMXClient("PODU")
dmxClient.connect()
while True :
for i in range( 256 ) :
try :
dmxClient.write([1, i, 2, i])
time.sleep( 0.1 )
except KeyboardInterrupt:
dmxClient.close()
break
break
DMX の アドレス001とアドレス002をカウントしていくだけの動作を確認出来ました。
コマンドコンソールか PowerShell から DMXServer.exe を起動してから上記の Python コードを実行します。
> .\DMXServer -n PODU
この後、別コマンドコンソールから Python コードを実行します。
DMXServer.exe を起動してから本プログラムを実行する手順が少し面倒だし Python らしくない。
出来ることなら Python モジュールとして import して使えるようにしたいと思います。
DMXServer.exeのC#ソースが付属しているので、これを参考に Python モジュールを作れたらいいのかな?
#器具の製作
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131