2022年2月 この範囲を時系列順で読む この範囲をファイルに出力する
オレメモです。
パッチマップ(出力側ベース)
・フリーフェーダースロット
・ディレイ:<0>ならスルー、<1-255>ならディレイ
・ユニバース(入力参照)
・スロット(入力参照)
・カーブプロファイル:<0>ならスルー、<1-511>なら以下とする
>カーブプロファイル<1-255>はノンディマーとしてしきい値とする
>カーブプロファイル<256-511>はカーププロファイルマップを参照する
#[Art-Net]
パッチマップ(出力側ベース)
・フリーフェーダースロット
・ディレイ:<0>ならスルー、<1-255>ならディレイ
・ユニバース(入力参照)
・スロット(入力参照)
・カーブプロファイル:<0>ならスルー、<1-511>なら以下とする
>カーブプロファイル<1-255>はノンディマーとしてしきい値とする
>カーブプロファイル<256-511>はカーププロファイルマップを参照する
#[Art-Net]
Art-Netの受信に成功して処理負荷に余裕もあるとなれば落としどころをどうするか!?って話にもなるワケです。最大の望みはディレイ機能とカーブプロファイル機能を持ったパッチマシンですが、欲を出し過ぎたら頓挫します。
さてさて、どこまで行けるのでしょう。
お試しに次ぐお試しでとっ散らかったソースコードを整理整頓し、受信モニタとしてまとめ上げてからの話ですが、受信したArt-Netを送信する試験をしましょう。
ただし、単にリレーするだけでは面白くないし処理負荷の確認にもなりません。受信をデコードし、1対1のパッチ処理をし、エンコードして送信することにします。1対1とはいえマッピングデータ用いた入れ替えをすれば最終形の負荷に近くなると思います。ここまでやれば天井が見えてくるでしょう。
もしRaspberryPiには荷が重いならPCで動かせばいいって話もあります。今のところRaspberryPiというよりDebian上のPython3.7で動く様に作っていますのでPCでも動くと思います。レガシーDMXを搭載せずにいる理由の一つでもあります。
今どきのムービング卓はArt-Netを出しますし、Art-Netのデコーダーは既製品が沢山ありますので、レガシーDMXまで作らなくてもいいかなぁ~なんて思ってます。専用基板を作る初期投資がキツイってのが一番大きいですが・・・
#Python #[Art-Net]
さてさて、どこまで行けるのでしょう。
お試しに次ぐお試しでとっ散らかったソースコードを整理整頓し、受信モニタとしてまとめ上げてからの話ですが、受信したArt-Netを送信する試験をしましょう。
ただし、単にリレーするだけでは面白くないし処理負荷の確認にもなりません。受信をデコードし、1対1のパッチ処理をし、エンコードして送信することにします。1対1とはいえマッピングデータ用いた入れ替えをすれば最終形の負荷に近くなると思います。ここまでやれば天井が見えてくるでしょう。
もしRaspberryPiには荷が重いならPCで動かせばいいって話もあります。今のところRaspberryPiというよりDebian上のPython3.7で動く様に作っていますのでPCでも動くと思います。レガシーDMXを搭載せずにいる理由の一つでもあります。
今どきのムービング卓はArt-Netを出しますし、Art-Netのデコーダーは既製品が沢山ありますので、レガシーDMXまで作らなくてもいいかなぁ~なんて思ってます。専用基板を作る初期投資がキツイってのが一番大きいですが・・・
#Python #[Art-Net]
Art-Netの受信に成功しました。
先達のサンプルコードをコピペしてPort番号を書き換えただけで一発OK。積年の成果が出て良かったのですが、あまりにも簡単だったので肩透かし。
複数のNICを使い分けるsocketの設定は先達情報に何パターンかありますが、Rasbian上のPythonに合うパターンを見つけるのに少し時間がかかったかもしれません。
今は卓のエフェクトエンジンで出力したデータが画面に流れております。4096chのディマーを256bpmの正弦波で動かしています。アホか。
テストデータはMAdot2からですが、SequenceとPhysicalにデータが出ていました。
Sequenceは単純なインクリメント情報、Physicalは卓内のUnivres番号です。
送信を作るときにはこの流儀を真似しましょう。
ただ、MAdot2はOpCode<0x5000>以外のArt-Netパケットも出しており、socketで受信したバイナリが19バイト以上で頭12バイトがb'Art-Net\x00\x00\x50\x00\x0E'であることを最初にチェックしないといけません。当初はバイト長も見ずにb'Art-Net\x00'だけでチェックしていたのでデコード処理でエラーが頻発でした。OpCodeによってデータ長も内容も違うので当然の結果ですが、マルチキャストなら<0x5000>以外のOpCodeは出さないと先入観で思ってしまったようです。よくないですね。
8ユニバースを受信させています。すべてのユニバースをデコード処理までしていますが、思った以上に軽々動いています。
Sequenceをキーに連続性をチェックしましたが読み飛ばしもしていないようです。
今のところは先日作った画面ではなくすべてのパラメータを表示するチェック用の画面に表示していますが、先日作った画面を同時に動かしてもCPU負荷は45%程度です。最大値は400%(100%×4コア)なのでまだ余裕があります。
#Python #[Art-Net]
先達のサンプルコードをコピペしてPort番号を書き換えただけで一発OK。積年の成果が出て良かったのですが、あまりにも簡単だったので肩透かし。
複数のNICを使い分けるsocketの設定は先達情報に何パターンかありますが、Rasbian上のPythonに合うパターンを見つけるのに少し時間がかかったかもしれません。
今は卓のエフェクトエンジンで出力したデータが画面に流れております。4096chのディマーを256bpmの正弦波で動かしています。アホか。
テストデータはMAdot2からですが、SequenceとPhysicalにデータが出ていました。
Sequenceは単純なインクリメント情報、Physicalは卓内のUnivres番号です。
送信を作るときにはこの流儀を真似しましょう。
ただ、MAdot2はOpCode<0x5000>以外のArt-Netパケットも出しており、socketで受信したバイナリが19バイト以上で頭12バイトがb'Art-Net\x00\x00\x50\x00\x0E'であることを最初にチェックしないといけません。当初はバイト長も見ずにb'Art-Net\x00'だけでチェックしていたのでデコード処理でエラーが頻発でした。OpCodeによってデータ長も内容も違うので当然の結果ですが、マルチキャストなら<0x5000>以外のOpCodeは出さないと先入観で思ってしまったようです。よくないですね。
8ユニバースを受信させています。すべてのユニバースをデコード処理までしていますが、思った以上に軽々動いています。
Sequenceをキーに連続性をチェックしましたが読み飛ばしもしていないようです。
今のところは先日作った画面ではなくすべてのパラメータを表示するチェック用の画面に表示していますが、先日作った画面を同時に動かしてもCPU負荷は45%程度です。最大値は400%(100%×4コア)なのでまだ余裕があります。
#Python #[Art-Net]
雪に隠れていた縁石に自家用車のタイヤをやられました。
鋭利に割れていたのでサイドウォールがパックリ。雪は滑るだけが危険要素ぢゃないようです。
サイドウォールは修理が出来ないので交換ですが、冬タイヤはトップシーズンのために割高な物しか手に入らず懐も寒くなりました。
運が悪かったと思うしかありませんが、テンション下がるわー。
開発が順調でテンションが上がっているので丁度いいのかもしれませんけど。
#日常
鋭利に割れていたのでサイドウォールがパックリ。雪は滑るだけが危険要素ぢゃないようです。
サイドウォールは修理が出来ないので交換ですが、冬タイヤはトップシーズンのために割高な物しか手に入らず懐も寒くなりました。
運が悪かったと思うしかありませんが、テンション下がるわー。
開発が順調でテンションが上がっているので丁度いいのかもしれませんけど。
#日常
RaspberryPiを触っていて思うのですが、普通のPCにもRaspberryPi並みのGPIOがあればいいなと。
RaspberryPi仕様のGPIOがベストって意味ではありませんが、PCにもローレベルのインターフェースがあったら制御で便利に使えるのになと。
もちろん存在していますが、あまりにニッチ過ぎて情報が少ないために敷居が高いのです。
主にUSB接続ですが、PCI-eボード1枚にI2C、SPI、USART、GPIOが「これでもか!」ってくらい載ってるのがあったら欲しいかも。
#妄想
RaspberryPi仕様のGPIOがベストって意味ではありませんが、PCにもローレベルのインターフェースがあったら制御で便利に使えるのになと。
もちろん存在していますが、あまりにニッチ過ぎて情報が少ないために敷居が高いのです。
主にUSB接続ですが、PCI-eボード1枚にI2C、SPI、USART、GPIOが「これでもか!」ってくらい載ってるのがあったら欲しいかも。
#妄想
Art-Netの受信データをデコードする処理を書いてみました。
製作環境はRspberryPi4、Rasbian_buster、Python 3.7.3です。
------
import numpy as np
class coding:
def decode(self, artnet_packet):
""" Art-Netのbyte列を要素に分解する """
id = artnet_packet[0:8]
opcode = int.from_bytes(artnet_packet[8:10], 'little')
prover = int.from_bytes(artnet_packet[10:12], 'big')
sequence = int.from_bytes(artnet_packet[12:13], 'little')
physical = int.from_bytes(artnet_packet[13:14], 'little')
subuni = int.from_bytes(artnet_packet[14:15], 'little')
sub = subuni // 16
uni = subuni % 16
net = int.from_bytes(artnet_packet[15:16], 'little')
length = int.from_bytes(artnet_packet[16:18], 'big')
data = np.frombuffer(artnet_packet, dtype=np.uint8, count=length, offset=18)
return (id, opcode, prover, sequence, physical, net, sub, uni, length, data)
if __name__ == '__main__':
an = coding()
id, opcode, prover, sequence, physical, net, sub, uni, length, data_uint8 = an.decode(test_artnet_packet)
※ 行頭の空白には全角を使っています。
------
test_artnet_packetに受信データを入れ、codingのインスタンスanでdecodeを呼び出します。
書いてみたら案外スッキリした物になったので記念に掲載しました。
socketで受信するのはバイナリデータ(Pythonで言うところのバイト列)ですが、これを一発でnumpy.arrayに変換してくれるnumpy.frombufferは便利です。
int.from_bytesもバイト列をエンディアン指定でint数に一発変換してくれて便利です。
私はPICマイコンと協調させて使うことが多いので、こういった機能があると助かります。
上記ですとdataの戻り値がnumpy.uint8ですが、計算するためにはnumpy.uint16の方が良いと思います。
data_uint16 = data.astype(np.uint16)
とかで型変換するといいかもしれません。
#Python #[Art-Net]
製作環境はRspberryPi4、Rasbian_buster、Python 3.7.3です。
------
import numpy as np
class coding:
def decode(self, artnet_packet):
""" Art-Netのbyte列を要素に分解する """
id = artnet_packet[0:8]
opcode = int.from_bytes(artnet_packet[8:10], 'little')
prover = int.from_bytes(artnet_packet[10:12], 'big')
sequence = int.from_bytes(artnet_packet[12:13], 'little')
physical = int.from_bytes(artnet_packet[13:14], 'little')
subuni = int.from_bytes(artnet_packet[14:15], 'little')
sub = subuni // 16
uni = subuni % 16
net = int.from_bytes(artnet_packet[15:16], 'little')
length = int.from_bytes(artnet_packet[16:18], 'big')
data = np.frombuffer(artnet_packet, dtype=np.uint8, count=length, offset=18)
return (id, opcode, prover, sequence, physical, net, sub, uni, length, data)
if __name__ == '__main__':
an = coding()
id, opcode, prover, sequence, physical, net, sub, uni, length, data_uint8 = an.decode(test_artnet_packet)
※ 行頭の空白には全角を使っています。
------
test_artnet_packetに受信データを入れ、codingのインスタンスanでdecodeを呼び出します。
書いてみたら案外スッキリした物になったので記念に掲載しました。
socketで受信するのはバイナリデータ(Pythonで言うところのバイト列)ですが、これを一発でnumpy.arrayに変換してくれるnumpy.frombufferは便利です。
int.from_bytesもバイト列をエンディアン指定でint数に一発変換してくれて便利です。
私はPICマイコンと協調させて使うことが多いので、こういった機能があると助かります。
上記ですとdataの戻り値がnumpy.uint8ですが、計算するためにはnumpy.uint16の方が良いと思います。
data_uint16 = data.astype(np.uint16)
とかで型変換するといいかもしれません。
#Python #[Art-Net]
Art-Netのアプリは画面表示とキー操作まで一応の完成をみました。
キー操作はレスポンスに少しムラがあるので改善したい点です。使えるレベルなので今のところは将来課題としておきますが、ユーザーがご機嫌をうかがいながら使うユーザーインターフェースは大嫌いなのでとても重要です。
余談ですが、売れている卓とそうでもない卓の違いにはこういった点の僅かなストレスの差もあります。卓は手段としての道具ですが、国内メーカーはカタログスペックばかり求めて手に馴染む道具を作ろうとしない。買うのは使う人ではありませんから仕方ないことでもありますが、国産のホール卓がダメな点です。国産で唯一、松村さんの卓にはこういったストレスが少ないのですが・・・。
とまぁ愚痴はおいといて、これで本丸であるArt-Netの受信に取り掛かれます。
単純な受信は別回しするThread内のsocketで受けるだけなので難しくないと思うのですが、パケットのデコードが少し面倒かもしれません。Art-Netのパケットはバイト列ですが、これらをPythonで扱いやすい様に分解して変換しなければなりません。Pythonはバイト型の扱いが少し苦手ですし、パケットにはアスキーテキスト、LSBの2バイト数、MSBの2バイト数、バイト型が混在しているので、よく考えて作らないといけません。実行回数が多い処理なだけに軽さも重要です。
#[Art-Net] #Python
キー操作はレスポンスに少しムラがあるので改善したい点です。使えるレベルなので今のところは将来課題としておきますが、ユーザーがご機嫌をうかがいながら使うユーザーインターフェースは大嫌いなのでとても重要です。
余談ですが、売れている卓とそうでもない卓の違いにはこういった点の僅かなストレスの差もあります。卓は手段としての道具ですが、国内メーカーはカタログスペックばかり求めて手に馴染む道具を作ろうとしない。買うのは使う人ではありませんから仕方ないことでもありますが、国産のホール卓がダメな点です。国産で唯一、松村さんの卓にはこういったストレスが少ないのですが・・・。
とまぁ愚痴はおいといて、これで本丸であるArt-Netの受信に取り掛かれます。
単純な受信は別回しするThread内のsocketで受けるだけなので難しくないと思うのですが、パケットのデコードが少し面倒かもしれません。Art-Netのパケットはバイト列ですが、これらをPythonで扱いやすい様に分解して変換しなければなりません。Pythonはバイト型の扱いが少し苦手ですし、パケットにはアスキーテキスト、LSBの2バイト数、MSBの2バイト数、バイト型が混在しているので、よく考えて作らないといけません。実行回数が多い処理なだけに軽さも重要です。
#[Art-Net] #Python
ありがちな1液式の塗料は1週間以上放置しないと現場で使えませんが、ポリエステル樹脂は2日もあれば完全硬化して使えます。扱いが面倒なところや少なくない制限もありますが、現場投入までの工程としてはむしろ使いやすいかもしれません。
そんなポリエステル樹脂を塗布した客席テーブルは今日から現場に出向です。自分は行きませんが、在籍園児が数百人いる幼稚園のお遊戯会で部下が一週間ほど使います。客席に卓を仮設するので客席テーブルの本業であります。使い勝手の確認はもとより、荷重をかけ続ける状況なのでロードテストにはうってつけです。
この幼稚園は若園長が好き者で、スモーク炊いてムービング使って有名アイドルのアリーナコンサートよろしくゴリゴリにしたいとか。過去映像を見ましたが、明かりは頑張ってイイ感じに作ってますが、園児たちが自由過ぎてアンバランスなのか面白いのかよーわからん。お遊戯会でここまでしてどうする!?ってのが本音ですが、園児たちの思い出になって親御さんが楽しんでくれるなら仕事としては成立。
ということで、ダメなところと傷みやすいところがもっともっと見えてくるといいかな。
#ガチ工作
そんなポリエステル樹脂を塗布した客席テーブルは今日から現場に出向です。自分は行きませんが、在籍園児が数百人いる幼稚園のお遊戯会で部下が一週間ほど使います。客席に卓を仮設するので客席テーブルの本業であります。使い勝手の確認はもとより、荷重をかけ続ける状況なのでロードテストにはうってつけです。
この幼稚園は若園長が好き者で、スモーク炊いてムービング使って有名アイドルのアリーナコンサートよろしくゴリゴリにしたいとか。過去映像を見ましたが、明かりは頑張ってイイ感じに作ってますが、園児たちが自由過ぎてアンバランスなのか面白いのかよーわからん。お遊戯会でここまでしてどうする!?ってのが本音ですが、園児たちの思い出になって親御さんが楽しんでくれるなら仕事としては成立。
ということで、ダメなところと傷みやすいところがもっともっと見えてくるといいかな。
#ガチ工作
PythonのThreadとQueueの使い方はだいたい理解しました。
0.005秒のsleepで動作周期を持たせたThreadで512個の整数を延々と加算してqueue.putに出力し、本処理では0.001秒のsleepで動作周期を持たせたqueue.get_nowaitで取り出しながら0.1秒毎に表示を更新しています。処理負荷が小さくメモリ使用量も安定していてスムーズです。本処理での時間軸の管理はアセンブラっぽいカウンタ処理ですが、厳密な処理周期は不要なのでsignalを使うほどでもありません。
Threadを使うメリットは高速化だと書く人が多いですが、私にとっては、処理によって違う要求時間を仕分け出来て、ポーリングだけど割り込みっぽいことが出来ることです。画面の更新はそれほど頻繁でなくていいけど、毎秒44回更新されるDMXの信号の処理は遅れたくないのですが、シングルスレッドでこの辺りを制御するのは案外面倒なのです。
気を付ける点はQueueのputやgetのタイミングです。Queueは変数ではなくFIFO特性のスタックなことが肝ですが、C言語のスタックやポインタにセマフォが混ざった構成なので、C言語のこのあたりを知ってないと理解しにくいかも。PythonにC言語っぽい作法が残っているのが不思議ですが・・・
ThreadとQueueを使ってキーボードの入力も作り直します。
#RaspberryPi #Python
0.005秒のsleepで動作周期を持たせたThreadで512個の整数を延々と加算してqueue.putに出力し、本処理では0.001秒のsleepで動作周期を持たせたqueue.get_nowaitで取り出しながら0.1秒毎に表示を更新しています。処理負荷が小さくメモリ使用量も安定していてスムーズです。本処理での時間軸の管理はアセンブラっぽいカウンタ処理ですが、厳密な処理周期は不要なのでsignalを使うほどでもありません。
Threadを使うメリットは高速化だと書く人が多いですが、私にとっては、処理によって違う要求時間を仕分け出来て、ポーリングだけど割り込みっぽいことが出来ることです。画面の更新はそれほど頻繁でなくていいけど、毎秒44回更新されるDMXの信号の処理は遅れたくないのですが、シングルスレッドでこの辺りを制御するのは案外面倒なのです。
気を付ける点はQueueのputやgetのタイミングです。Queueは変数ではなくFIFO特性のスタックなことが肝ですが、C言語のスタックやポインタにセマフォが混ざった構成なので、C言語のこのあたりを知ってないと理解しにくいかも。PythonにC言語っぽい作法が残っているのが不思議ですが・・・
ThreadとQueueを使ってキーボードの入力も作り直します。
#RaspberryPi #Python
RaspberryPiにRTC(リアル・タイム・クロックを取り付けてみました。
RaspberryPiは無電源だと時計が動きませんので、起動すると前回終了した時刻から時計がカウントされます。
これでは気持ちが悪いし、ファイルの更新時刻がおかしくなると開発作業ではトラブルのもとです。
リンクの商品以外にもRTCはいろいろありますが、この製品は小型でGPIOに挿すだけで使えて何かとよいと思います。安価だし。
設定方法はこのサイトがわかりやすいと思います。/boot/config.txtを更新した後に再起動を忘れずに。
#RaspberryPi
RaspberryPiは無電源だと時計が動きませんので、起動すると前回終了した時刻から時計がカウントされます。
これでは気持ちが悪いし、ファイルの更新時刻がおかしくなると開発作業ではトラブルのもとです。
リンクの商品以外にもRTCはいろいろありますが、この製品は小型でGPIOに挿すだけで使えて何かとよいと思います。安価だし。
設定方法はこのサイトがわかりやすいと思います。/boot/config.txtを更新した後に再起動を忘れずに。
#RaspberryPi
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