2023年9月16日の投稿[3件]
共有メモリを使う場合、読み書きが衝突しないように配慮しなければなりません。
今回は情報が一方向ですから比較的簡単ですが、よく考えないとトラブルのもとです。
一番簡単なのは、DMX512 の値の配列の共有メモリと読み書きフラグの共有メモリを使う方法です。読み書きフラグは送り側がセットし受け側がクリアします。送り側はフラグがクリアならば共有メモリに書き込んでフラグをセットし、受け側はフラグがセットしてあれば共有メモリから読み込んでフラグをクリアします。
双方の待ちを考慮しないとといけませんが、送り側が受け側のフェーズ時間の数倍でチェックをすれば遅延は1フレームです。何よりも Queue に比べ処理時間が短く情報の渋滞も起き難いことを優先しましょう。
#Python #器具の製作
今回は情報が一方向ですから比較的簡単ですが、よく考えないとトラブルのもとです。
一番簡単なのは、DMX512 の値の配列の共有メモリと読み書きフラグの共有メモリを使う方法です。読み書きフラグは送り側がセットし受け側がクリアします。送り側はフラグがクリアならば共有メモリに書き込んでフラグをセットし、受け側はフラグがセットしてあれば共有メモリから読み込んでフラグをクリアします。
双方の待ちを考慮しないとといけませんが、送り側が受け側のフェーズ時間の数倍でチェックをすれば遅延は1フレームです。何よりも Queue に比べ処理時間が短く情報の渋滞も起き難いことを優先しましょう。
#Python #器具の製作
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 #器具の製作