全年全月8日の投稿[32件](2ページ目)
2023年8月 この範囲を時系列順で読む この範囲をファイルに出力する
LTC のフレーム値の計算で悩む。
ノンドロップフレームなら簡単ですが、29.97fpsドロップフレームではそうもいきません。実時間とタイムコードの値が合うのは1時間ごと、つまり途中は実時間とズレるのです。タイムコードは映像のフレームに時間形式のナンバリングを与える手法であって実時間を表す物ではありませんので仕方ありません。ズレがあるとしてもフレームナンバーをゼロからカウントするのは何も問題ありませんが、不特定の時間値からカウントされる場合に漠然とした疑問があるワケです。
困っていても仕方がないので条件を整理しましょう。
10分単位で考えてみます。
30fpsなら10分で18,000フレームです。29.97fpsドロップフレームは10分の間に18カウントを落としますので17,982フレームです。フレーム長の伸縮比1.001を掛けますと17,999.92となり、時間差は0.08フレームです。秒に直すと0.0026秒くらいの誤差です。そんなに大きな値ではありませんねぇ。見た目にわかる人は皆無ですからあんまり気にしなくてよくね?
となると、基準点(時毎もしくは10分毎)からのフレーム数を出し、このフレーム数からタイムコード値を得ればいいんでないか?大げさな感じもしますが、時間値で計算すると奇妙な繰り下がりが発生して計算が面倒だからです。30fpsの24時間分のフレーム数は 2,592,000 ですから32bitの整数でも十分管理出来ます。時間からフレームの枚数目を得る関数とフレームの枚数目から時間を得る関数を作っておけばどうにでもなりそう。
ここまでやれば、都度の誤差は人が感知出来ないレベルに収まると思います。
#タイムコード
ノンドロップフレームなら簡単ですが、29.97fpsドロップフレームではそうもいきません。実時間とタイムコードの値が合うのは1時間ごと、つまり途中は実時間とズレるのです。タイムコードは映像のフレームに時間形式のナンバリングを与える手法であって実時間を表す物ではありませんので仕方ありません。ズレがあるとしてもフレームナンバーをゼロからカウントするのは何も問題ありませんが、不特定の時間値からカウントされる場合に漠然とした疑問があるワケです。
困っていても仕方がないので条件を整理しましょう。
10分単位で考えてみます。
30fpsなら10分で18,000フレームです。29.97fpsドロップフレームは10分の間に18カウントを落としますので17,982フレームです。フレーム長の伸縮比1.001を掛けますと17,999.92となり、時間差は0.08フレームです。秒に直すと0.0026秒くらいの誤差です。そんなに大きな値ではありませんねぇ。見た目にわかる人は皆無ですからあんまり気にしなくてよくね?
となると、基準点(時毎もしくは10分毎)からのフレーム数を出し、このフレーム数からタイムコード値を得ればいいんでないか?大げさな感じもしますが、時間値で計算すると奇妙な繰り下がりが発生して計算が面倒だからです。30fpsの24時間分のフレーム数は 2,592,000 ですから32bitの整数でも十分管理出来ます。時間からフレームの枚数目を得る関数とフレームの枚数目から時間を得る関数を作っておけばどうにでもなりそう。
ここまでやれば、都度の誤差は人が感知出来ないレベルに収まると思います。
#タイムコード
2023年6月 この範囲を時系列順で読む この範囲をファイルに出力する
オレメモ
windows10(11)でDHCPサーバーからIPアドレスを取り直す。
コマンドプロンプト(管理者権限)
> ipconfig /release
> ipconfig /renew
2回くらいやった方がいい。
#パソコン
windows10(11)でDHCPサーバーからIPアドレスを取り直す。
コマンドプロンプト(管理者権限)
> ipconfig /release
> ipconfig /renew
2回くらいやった方がいい。
#パソコン
2023年4月 この範囲を時系列順で読む この範囲をファイルに出力する
Linux上のC言語でLTCの波形を起こせたらと思ったのですが、処理能力の総量は余裕タップリなものの、Art-Netエンジンを作った際に感じた挙動ムラから想像するに許容範囲を越える波形ムラが起こりそうです。LinuxはOSそのものや他のモジュールに引っ張られて100~300usecくらい待たされることがあるのですが、LTCの波形を起こすのにこの条件はよろしくありません。RTOSを使わないなら普通のことですけどね。
ならばLTCを起こすところにはPICを使ったらいいかな?適材適所?
LinuxからUARTなどでフレーム情報を送ってPICでLTCを生成するのです。2~4フレーム分くらいPICにバッファすればLinux側に動作ムラがあっても安定した波形を出すと思われます。
差動バイフェーズで信号を反転する時間ピッチは25fpsで250usecです。29.97fpsではなく25fpsとしているのは、PALのレートなのでLTC対応の演出機器は100%対応するし、何よりも計算がしやすく誤差も出にくいために当面の試作には良いかなと。250usecは32MHzのPICで2,000命令相当の時間です。これだけあれば大概ことは1フェーズ分実行出来ます。実行周期はTMR1やTMR2による周期割込みを使えばPICのクロック素子相当の精度を得られます。
求める精度は、周期が0.001%未満、差動バイフェーズの立ち上がり立下り精度が5%未満です。無理は無さそうです。
書いてて思ったのですが、こんなLTCジェネレーターをこれまでに作らなかった自分が不思議。
#タイムコード #PIC #電子工作
ならばLTCを起こすところにはPICを使ったらいいかな?適材適所?
LinuxからUARTなどでフレーム情報を送ってPICでLTCを生成するのです。2~4フレーム分くらいPICにバッファすればLinux側に動作ムラがあっても安定した波形を出すと思われます。
差動バイフェーズで信号を反転する時間ピッチは25fpsで250usecです。29.97fpsではなく25fpsとしているのは、PALのレートなのでLTC対応の演出機器は100%対応するし、何よりも計算がしやすく誤差も出にくいために当面の試作には良いかなと。250usecは32MHzのPICで2,000命令相当の時間です。これだけあれば大概ことは1フェーズ分実行出来ます。実行周期はTMR1やTMR2による周期割込みを使えばPICのクロック素子相当の精度を得られます。
求める精度は、周期が0.001%未満、差動バイフェーズの立ち上がり立下り精度が5%未満です。無理は無さそうです。
書いてて思ったのですが、こんなLTCジェネレーターをこれまでに作らなかった自分が不思議。
#タイムコード #PIC #電子工作
ホール管理の増員で操作盤の置物になっているだけなので調べモノをし放題です。
PythonのライブラリをC言語で作る方法の基本はわかりました。このサイトだけでほぼ解決。
製作手順を大まかに書き出すと、
1)関数ライブラリを用意する。
C言語で#includeして使える関数なら汎用でも自作でも何でもいい。
2)「ラッパー関数」を用意する。
C言語の関数をPythonへ引き渡す定義をするソースファイル。Pythonからの呼び出し方と変数の変換方法をC言語で記述します。
3)セットアップファイルを用意する。
セットアップファイルはgccで言うところのMakeFileです。Pythonで記述され、ファイル名はsetup.pyにすることが多いそうです。
4)ビルドする。
セットアップファイルを使ってビルドする。
5)インストールする。
セットアップファイルを使ってインストールする(動作の実際はPythonパッケージ管理のpipへの登録)。
と、なります。
ラッパー関数はC言語とPythonの両方を知らないと記述出来ないので少し難しいですが、セットアップファイルは定型の通り記述するだけです。
#C言語 #Python
PythonのライブラリをC言語で作る方法の基本はわかりました。このサイトだけでほぼ解決。
製作手順を大まかに書き出すと、
1)関数ライブラリを用意する。
C言語で#includeして使える関数なら汎用でも自作でも何でもいい。
2)「ラッパー関数」を用意する。
C言語の関数をPythonへ引き渡す定義をするソースファイル。Pythonからの呼び出し方と変数の変換方法をC言語で記述します。
3)セットアップファイルを用意する。
セットアップファイルはgccで言うところのMakeFileです。Pythonで記述され、ファイル名はsetup.pyにすることが多いそうです。
4)ビルドする。
セットアップファイルを使ってビルドする。
5)インストールする。
セットアップファイルを使ってインストールする(動作の実際はPythonパッケージ管理のpipへの登録)。
と、なります。
ラッパー関数はC言語とPythonの両方を知らないと記述出来ないので少し難しいですが、セットアップファイルは定型の通り記述するだけです。
#C言語 #Python
2023年1月 この範囲を時系列順で読む この範囲をファイルに出力する
ランチャーに行く前にscoketの基本動作の確認かな?
受信したArt-Netパケットをそのまま送信する実験。
これが求める機能の基本ですから確認せんといかん。
#[Art-Net] #C言語
受信したArt-Netパケットをそのまま送信する実験。
これが求める機能の基本ですから確認せんといかん。
#[Art-Net] #C言語
共有メモリの衝突回避ですが、共有メモリの中にハンドシェイク表すフラグを入れたらそれでいいんじゃないかと。
そのフラグが立っていれば極々わずかな時間sleepを繰り返す処理です。
while(flag1 == 1)
{
sleep(0.001);
}
flag2 = 1;
/* 共有メモリ処理 */
flag2 = 0;
みたいなものです。
別プロセスがフラグを0にすればwhileを抜けます。
簡易的なモノですが、フラグを書き換えられるプロセスを一つにしておけばイイんじゃないかと。最も簡単なセマフォはこういうことですし。
子プロセスの停止制御も同様の考え方が使えます。
動作し続けるってことは繰り返し処理です。単なる繰り返しはwhile(1)とかで無限ループすることが多いので、while(flag==1)とかにすればいい。共有メモリ上のフラグが1ならwhileでループし0になったら抜ければいいのです。抜けたら終了処理をしてプロセスを落とすと。子プロセスが完全に終わったことはスタックしておいたプロセスIDを見ればわかります。
この辺りまで決まれば次はランチャーです。
#C言語
そのフラグが立っていれば極々わずかな時間sleepを繰り返す処理です。
while(flag1 == 1)
{
sleep(0.001);
}
flag2 = 1;
/* 共有メモリ処理 */
flag2 = 0;
みたいなものです。
別プロセスがフラグを0にすればwhileを抜けます。
簡易的なモノですが、フラグを書き換えられるプロセスを一つにしておけばイイんじゃないかと。最も簡単なセマフォはこういうことですし。
子プロセスの停止制御も同様の考え方が使えます。
動作し続けるってことは繰り返し処理です。単なる繰り返しはwhile(1)とかで無限ループすることが多いので、while(flag==1)とかにすればいい。共有メモリ上のフラグが1ならwhileでループし0になったら抜ければいいのです。抜けたら終了処理をしてプロセスを落とすと。子プロセスが完全に終わったことはスタックしておいたプロセスIDを見ればわかります。
この辺りまで決まれば次はランチャーです。
#C言語
共有メモリに構造体を配置してみましたが、割と簡単でした。
構造体のタグ(ひな形)をヘッダーファイルに作り、親プロセスと子プロセスにinclude。共有メモリのサイズは構造体のタグから得て設定。共有メモリ上に置く変数を独立したポインタにするとオフセットをそれぞれ計算して与えないといけませんが、構造体なら一括設定出来て便利です。
構造体をポインタにすると表記が独特になりますが、意味合いが明示的となって読みやすいかもしれません。
この辺りには、本文中に出来るだけ定数を直書きしないという方針にも繋がってきます。
次は共有メモリの衝突回避を調べないといけません。
#C言語
構造体のタグ(ひな形)をヘッダーファイルに作り、親プロセスと子プロセスにinclude。共有メモリのサイズは構造体のタグから得て設定。共有メモリ上に置く変数を独立したポインタにするとオフセットをそれぞれ計算して与えないといけませんが、構造体なら一括設定出来て便利です。
構造体をポインタにすると表記が独特になりますが、意味合いが明示的となって読みやすいかもしれません。
この辺りには、本文中に出来るだけ定数を直書きしないという方針にも繋がってきます。
次は共有メモリの衝突回避を調べないといけません。
#C言語
屋外で開催される成人式関連のイベントで電源出しです。
起動してしまえばやることはありません。
本日の課題は共有メモリのテストです。
次のページにあるソースをそのまま使って挙動を確認です。
プロセス間でのメモリ共有
親プロセス「ShareMemTest1」を起動した後、待機時間(20秒)のうちにコンソールで「ShareMemTest2」に共有メモリのIDを与えて起動するというもの。一貫したプログラムではありませんが、やりたいことはプロセス間でのメモリ共有ですからむしろわかりやすい。
ちなみに、コンソールでプログラムを起動する際、末尾に「&」を付けると新規プロセスで実行します。
ここサンプルを使うなら、
<親プロセスを起動>
$ ./ShareMemTest1 &
<起動後表示>
nShareMemID = 23 /* IDは都度変わります */
process1 : nVar1 = 1, nVar2 = 2
・・・ここで20秒Sleepしてます・・・
<子プロセスを起動>
$ ./ShareMemTest2 23 &
<起動後表示>
nShareMemID = 23
process2 : nVar1 = 1, nVar2 = 2
process2 : nVar1 = 2, nVar2 = 2
・・・子プロセスはここで終了・・・
・・・20秒後、親プロセスが再開・・・
process2 : nVar1 = 2, nVar2 = 2
・・・親プロセスも終了・・・
となります。
正に記述にある通り。
$ ipcs -m
や
$ free
を用いるとSharedメモリの状況がわかります。
実際のテストではgetpid()を用いてプロセスIDも表示しながら確認しましたが、確かに別プロセスでした。
共有メモリの容量は、無意味に8MBくらい設定してみましたが何の問題も無し。
親側の設定は、typedefで構造体を定義し、構造体のポインタ変数を作り、構造体のメモリサイズ(sizeof()で取得)をもとに共有メモリを作り、構造体のポインタ変数に共有メモリを割り当てる、といった流れでしょうか。
子側は、typedefで構造体を定義し、構造体のポインタ変数を作り、親から取得したIDから構造体のポインタ変数に共有メモリを割り当てる、といった流れ?
共有メモリ上に変数(構造体)を構築した後は共有メモリを意識する必要は無いと思います。もちろん、衝突回避は常に考えないといけませんけど。
勘違いしていた点ですが、共有メモリのIDは管理用の通し番号であってポインタに設定するアドレスではないことです。C言語では何かにつけてポインタ渡しなのでこれもそうかと思ってしまいました。
共有メモリに構造体を配置することが次の課題ですが、構造体についてもう少し勉強してからです。
#C言語
起動してしまえばやることはありません。
本日の課題は共有メモリのテストです。
次のページにあるソースをそのまま使って挙動を確認です。
プロセス間でのメモリ共有
親プロセス「ShareMemTest1」を起動した後、待機時間(20秒)のうちにコンソールで「ShareMemTest2」に共有メモリのIDを与えて起動するというもの。一貫したプログラムではありませんが、やりたいことはプロセス間でのメモリ共有ですからむしろわかりやすい。
ちなみに、コンソールでプログラムを起動する際、末尾に「&」を付けると新規プロセスで実行します。
ここサンプルを使うなら、
<親プロセスを起動>
$ ./ShareMemTest1 &
<起動後表示>
nShareMemID = 23 /* IDは都度変わります */
process1 : nVar1 = 1, nVar2 = 2
・・・ここで20秒Sleepしてます・・・
<子プロセスを起動>
$ ./ShareMemTest2 23 &
<起動後表示>
nShareMemID = 23
process2 : nVar1 = 1, nVar2 = 2
process2 : nVar1 = 2, nVar2 = 2
・・・子プロセスはここで終了・・・
・・・20秒後、親プロセスが再開・・・
process2 : nVar1 = 2, nVar2 = 2
・・・親プロセスも終了・・・
となります。
正に記述にある通り。
$ ipcs -m
や
$ free
を用いるとSharedメモリの状況がわかります。
実際のテストではgetpid()を用いてプロセスIDも表示しながら確認しましたが、確かに別プロセスでした。
共有メモリの容量は、無意味に8MBくらい設定してみましたが何の問題も無し。
親側の設定は、typedefで構造体を定義し、構造体のポインタ変数を作り、構造体のメモリサイズ(sizeof()で取得)をもとに共有メモリを作り、構造体のポインタ変数に共有メモリを割り当てる、といった流れでしょうか。
子側は、typedefで構造体を定義し、構造体のポインタ変数を作り、親から取得したIDから構造体のポインタ変数に共有メモリを割り当てる、といった流れ?
共有メモリ上に変数(構造体)を構築した後は共有メモリを意識する必要は無いと思います。もちろん、衝突回避は常に考えないといけませんけど。
勘違いしていた点ですが、共有メモリのIDは管理用の通し番号であってポインタに設定するアドレスではないことです。C言語では何かにつけてポインタ渡しなのでこれもそうかと思ってしまいました。
共有メモリに構造体を配置することが次の課題ですが、構造体についてもう少し勉強してからです。
#C言語
2022年9月 この範囲を時系列順で読む この範囲をファイルに出力する
舞台仕事の先輩から譲ってもらったLED星球が不調です。
どうも電源モジュールがおかしい。DC12vのモノですが電圧が出ていません。スイッチング素子の前の平滑コンデンサには電圧が出ているので、スイッチング素子が飛んだか、センシング回路が誤作動している感じです。
そもそもの原因が電源モジュール単体の故障なのか、他の部位の不調によって電源モジュールが故障したのかは不明ですが、正常な別電源に繋いでみないとわかりません。
幸い主回路の基板には破損や焼損は見受けられませんので電源モジュール単体の不調だと思います。
帰宅してチェックです。
こういう故障は原因の特定が難しいことがあります。
部品を交換して動いても現場で使ったらやっぱりダメってことが少なくありません。本丸が別なところにあって微妙な関係性で故障に至っている場合です。
精神的にも辛い修理のパターンですが、こういった事例から学ぶことは多いので、まぁいいかなと。
追記
電源モジュールを交換して治りました。
中華電器から電源モジュールをまとめ買いしておいたのが役に立ったようです。
#照明器具
どうも電源モジュールがおかしい。DC12vのモノですが電圧が出ていません。スイッチング素子の前の平滑コンデンサには電圧が出ているので、スイッチング素子が飛んだか、センシング回路が誤作動している感じです。
そもそもの原因が電源モジュール単体の故障なのか、他の部位の不調によって電源モジュールが故障したのかは不明ですが、正常な別電源に繋いでみないとわかりません。
幸い主回路の基板には破損や焼損は見受けられませんので電源モジュール単体の不調だと思います。
帰宅してチェックです。
こういう故障は原因の特定が難しいことがあります。
部品を交換して動いても現場で使ったらやっぱりダメってことが少なくありません。本丸が別なところにあって微妙な関係性で故障に至っている場合です。
精神的にも辛い修理のパターンですが、こういった事例から学ぶことは多いので、まぁいいかなと。
追記
電源モジュールを交換して治りました。
中華電器から電源モジュールをまとめ買いしておいたのが役に立ったようです。
#照明器具
2022年8月 この範囲を時系列順で読む この範囲をファイルに出力する
LCD Monitor Controller の基板を中国に発注しました。
試してもいない回路を発注するのはどうかって話もありますが、感光基板で自作するには密度があり過ぎますし、間違いがあっても許せる金額だからいいかなと。
そんな品物、PICに与えるクロックを内蔵のRC発振子か外付け発振子で8MHzにしようかと思っていたのですが7.3728MHzにしようかと。
一見半端な数値ですが、PICでRS232系のシリアル通信でありがちなボーレート(例えば9600bps)などを扱うならキリがいいのです。計算上ですがエラー率が0%になります。
目的のLCDモニタは単純なパラレルなので厳密な時間管理は不要だし、I2Cはクロック同期式のスレーブなのでタイミングはマスター任せです。しかし、シリアル通信は非同期なので受信側もボーレートを合わせなければなりません。PICはシステムクロックでボーレートを起こしますので、他に支障を来さない範囲でシリアル通信に都合の良いシステムクロックを使った方がいいのです。
これまでは国内の販売店で7.3728MHzの水晶発振子を見つけられなかったので使っていませんでしたが、試しに中国で探したら普通にあります。1個59円と安いので買っておきました。例によって送料の方が高い。。。
シリアル通信に都合が良いクロックは他にもありますが、この値を使うのはPICの都合です。16系PICのクロックは32MHzが上限で、そのままのクロックを与えてもいいのですが、内蔵の4倍PLLを使えば8MHzを与えることで32MHzで動作します。PLLを使った方が外部ノイズに強いのもありますから、8MHz以下でシリアル通信に都合が良い最大値である7.3728MHzはよろしいのです。
同じ理由で、PICでDMXを扱うなら250kHzの二乗数倍がよろしいのです。
#電子工作
試してもいない回路を発注するのはどうかって話もありますが、感光基板で自作するには密度があり過ぎますし、間違いがあっても許せる金額だからいいかなと。
そんな品物、PICに与えるクロックを内蔵のRC発振子か外付け発振子で8MHzにしようかと思っていたのですが7.3728MHzにしようかと。
一見半端な数値ですが、PICでRS232系のシリアル通信でありがちなボーレート(例えば9600bps)などを扱うならキリがいいのです。計算上ですがエラー率が0%になります。
目的のLCDモニタは単純なパラレルなので厳密な時間管理は不要だし、I2Cはクロック同期式のスレーブなのでタイミングはマスター任せです。しかし、シリアル通信は非同期なので受信側もボーレートを合わせなければなりません。PICはシステムクロックでボーレートを起こしますので、他に支障を来さない範囲でシリアル通信に都合の良いシステムクロックを使った方がいいのです。
これまでは国内の販売店で7.3728MHzの水晶発振子を見つけられなかったので使っていませんでしたが、試しに中国で探したら普通にあります。1個59円と安いので買っておきました。例によって送料の方が高い。。。
シリアル通信に都合が良いクロックは他にもありますが、この値を使うのはPICの都合です。16系PICのクロックは32MHzが上限で、そのままのクロックを与えてもいいのですが、内蔵の4倍PLLを使えば8MHzを与えることで32MHzで動作します。PLLを使った方が外部ノイズに強いのもありますから、8MHz以下でシリアル通信に都合が良い最大値である7.3728MHzはよろしいのです。
同じ理由で、PICでDMXを扱うなら250kHzの二乗数倍がよろしいのです。
#電子工作