全年1月31日の投稿[6件]
2025年 この範囲を時系列順で読む この範囲をファイルに出力する
Antari F1-FAZER の排煙器の焦げカス除去に「ジクロロメタン」を使うのはどうだろう。3Dプリンタの製作物の表面処理で使ってますが、セルロース、エステル、油脂、樹脂を溶かす性質があるそうな。スモークリキッドの焦げカスも溶かしてくれないだろうか。発煙器は高温になるので内部に樹脂やゴムの部品は無いものと予想していますが、そうならジクロロメタンで侵されることは無いハズです。
気をつけなければならないのは毒物であることです。吸引すると呼吸器系に良くないそうな。
どのように施工するか考えてみましょう。
追記
ジクロロメタンで溶けないOリングやパッキンはフッ素樹脂(PTFE)だそうな。ステンレス製の調理用注射器を用い、パッキンをフッ素樹脂製に変えればよいのかな?
#器具の修理
気をつけなければならないのは毒物であることです。吸引すると呼吸器系に良くないそうな。
どのように施工するか考えてみましょう。
追記
ジクロロメタンで溶けないOリングやパッキンはフッ素樹脂(PTFE)だそうな。ステンレス製の調理用注射器を用い、パッキンをフッ素樹脂製に変えればよいのかな?
#器具の修理
2023年 この範囲を時系列順で読む この範囲をファイルに出力する
てなわけで、socketの実験に入る下準備が整いました。Pythonで出来たことですからC言語(gcc)で出来ないことではないでしょう。
Art-Netエンジンを構成するにはFIFOというか循環配列というかリングキャッシュというかQueueも勉強しないとけません。例えば1024個の配列を作ったとして、これがリング状に繋がったイメージで使います。1024で折り返すカウンタを使って配列の基点位置を表すだけですが、カウンタの計算モジュールだけでもライブラリ化しないと面倒かなと。
これはDelayで必要な機能です。一定の時間間隔でDMXのデータを保存し続ければ配列サイズが許す範囲で過去情報を取り出せます。つまりDelayになります。受信毎の保存でないことが肝ですが、往年のテープエコーと要領は同じです。
C言語はボチボチ書けるようになってきましたし、先達の情報も読み取れるようになってきました。パッチマシンとしての完成は先としても、この閑散期にArt-Netエンジンだけでも完成させたいです。
あとは、コマンド入力と処理の方法も考えないといけません。
ルールマップに基づいた入力制限とか、入力されたコマンドや数値のスタック方法とか、それの表示とかです。入力値はコマンドと数値の文字列で処理関数に渡すつもりですが、それをどの様に解析して実行するかも案外難しい。
#[Art-Net] #C言語
Art-Netエンジンを構成するにはFIFOというか循環配列というかリングキャッシュというかQueueも勉強しないとけません。例えば1024個の配列を作ったとして、これがリング状に繋がったイメージで使います。1024で折り返すカウンタを使って配列の基点位置を表すだけですが、カウンタの計算モジュールだけでもライブラリ化しないと面倒かなと。
これはDelayで必要な機能です。一定の時間間隔でDMXのデータを保存し続ければ配列サイズが許す範囲で過去情報を取り出せます。つまりDelayになります。受信毎の保存でないことが肝ですが、往年のテープエコーと要領は同じです。
C言語はボチボチ書けるようになってきましたし、先達の情報も読み取れるようになってきました。パッチマシンとしての完成は先としても、この閑散期にArt-Netエンジンだけでも完成させたいです。
あとは、コマンド入力と処理の方法も考えないといけません。
ルールマップに基づいた入力制限とか、入力されたコマンドや数値のスタック方法とか、それの表示とかです。入力値はコマンドと数値の文字列で処理関数に渡すつもりですが、それをどの様に解析して実行するかも案外難しい。
#[Art-Net] #C言語
キー入力の処理を書き直してみました。
ファンクションキーやカーソルキーなどの複数バイトでキーコードを出すキーも扱えます。shiftやAltなどの装飾キーは拾えませんケド。
入力の待ち時間はありません。get_inkey()はすぐ戻ってきます。戻り値はキーコードの長さを表しますが、0なら入力が無かったと判別出来ます。
得られるのは標準入力からのASCIIコードです。read()はキャッシュを読むだけでタイミング次第では取得値に複数のキーコードが混じることがありますが、これをキー単体のコードとして仕分けています。キャッシュの一番前のキーコードだけを取り出す単純な仕分けで、想定外のキーコードは読み飛ばしていますが十分でした。
キーコードで何かをするにはswitch文やif文でそのコードを仕分ける必要があります。
正常に動かすなら、100msec(1/10秒)毎以下でget_inkey()を読みに行く必要があります。
定数設定とプロトタイプ宣言をヘッダーファイルに書けばincludeしてライブラリとして使えます。mainはコメント化して使った方がいいですけど。
Raspberry Pi 4B / Rasbian11_32bit(blueseye) / OS標準gcc
/* ---------------------------------
リアルタイムにキー入力をチェックする
--------------------------------- */
/* getcharはキー入力のキャッシュが空だと入力があるまで待つ。
キャッシュが無いなら無いでそのまま抜けたいが、タイムアウトを設定しても
抜けない。環境に寄るのかもしれないが、ioctl.hを用いることで
タイムアウトが実現できた。
get_inkeyの呼び出しは100msec(1/10秒)毎以下で繰り返し行うこと。短い方がいい。
*/
/* ライブラリ読み込み */
#include <stdio.h>
#include <sys/ioctl.h>
#include <termios.h>
#include <unistd.h>
#include <time.h>
/* 定数設定 */
#define SET 1 // ioctl.readのモードをRawにするフラグ
#define RESET 0 // ipctl.readのモードをCanonicalに戻すフラグ
#define LENGTH_STACK 32 // キー入力のスタック長 状況によるが、長めにしないと取り出しが半端になる
#define ESC 0x1B // ASCIIコード ESC
#define BRACKET 0x5B // ASCIIコード [
/* プロトタイプ宣言 */
int get_inkey( char *get_char ) ; // キー入力を取得する関数
// 戻り値 // -1=エラー、0>=取得したキーコードの長さ
// char *get_char // 取得したキーコードを返すポインタ
int set_inkey( int mode_flag ) ; // キー入力のモードを設定する関数
// int mode_flag // モードの設定フラグ 1(SET)=Rawモードにする / 0(CLR)=モードを戻す
/* テスト用main */
int main(void) {
int i ; // for文用カウンタ
char get_char[ LENGTH_STACK ] ; // 入力されたキーコードを保存する変数
int ret_inkey ; // get_inkeyからの戻り値を保存する変数
/* コンソールの設定を初期化 */
set_inkey( SET ) ;
/* 無限ループで入力したキーを表示する */
for(;;) {
usleep( 1e5 ) ;
ret_inkey = get_inkey( get_char ) ; // get_inkeyから文字取得
/* get_inkeyの戻り値を処理 */
if( ret_inkey == -1 ) break ; // 戻り値が-1ならエラーなのでループから抜けて終了
if( get_char[0] == 0x0A ) break ; // エンターキーが押されたならループを抜けて終了
/* 入力された文字を出力する */
if( ret_inkey > 0) {
for( i = 0; i < ret_inkey; i++ ) {
if( get_char[i] >= 0x20 && get_char[i] <= 0x7E ) { // 入力された文字を出力する・・・表示可能な文字
printf( " %c<%02X>", get_char[i], get_char[i] ) ;
} else if( get_char[i] >= 0x00 && get_char[i] <= 0xFF ) { // 入力された文字を出力する・・・表示不可能な文字
printf( " <%02X>", get_char[i] ) ;
}
}
printf( "\n" ) ;
}
fflush( stdout ) ; // 画面表示のスタックを吐き出す
}
/* 正常終了 */
printf( "\n" ) ; // 念のための改行
set_inkey( RESET ) ; // コンソールの設定を元に戻す
return 0 ;
}
/* キー入力を取得する */
int get_inkey( char *get_char) {
// char *get_char // キーコードを返すためのchar配列のポインタ
int i ; // for用変数
char in_char[ LENGTH_STACK ] = { 0x00 }; // 入力されたキーを取得
int read_length ; // read()戻り値 キーコードのバイト数
int put_length = 0 ; // 戻り値 キーコードのバイト数
/* get_charの初期化 */
for( i = 0; i < LENGTH_STACK; i++ ) { // すべての値を0x00にする
get_char[ i ] = 0x00 ;
}
/* キー入力を読み取る */
read_length = read( 0, &in_char, LENGTH_STACK ) ; // read_lengthに取得バイト数、in_charにキーコードを得る
/* 取得値の仕分け */
if( read_length < 0 ) { // 取得エラーなのでエラーを返して終了
return -1 ;
} else if( read_length == 0 ) { // キーコードを得られなかったのでゼロを返す
return 0 ;
} else if( read_length == 1 // 取得が1バイトか先頭バイトがESC(0x1B)以外なら先頭バイトを返す
|| in_char[ 0 ] != ESC ) {
get_char[ 0 ] = in_char[ 0 ] ; // 値コピー
return 1 ;
} else if( read_length > 2 // 3バイト以上で先頭2バイトが0x1B(ESC)、0x5B([)なら
&& in_char[ 0 ] == ESC // ファンクションキーまたはカーソルキー
&& in_char[ 1 ] == BRACKET ) {
get_char[ 0 ] = ESC ; // 0バイト目
get_char[ 1 ] = BRACKET ; // 1バイト目
put_length = 2; // 戻り値設定
for( i = 2; i < read_length; i++ ) { // 2バイト目以降をコピー
if( in_char[ i ] == ESC ) break ; // 末尾にESCがあれば終了
get_char[ i ] = in_char[ i ] ; // 値コピー
put_length++ ; // 戻り値インクリメント
}
return put_length ; // 戻り値送って終了
}
return 0 ;
}
/* キー入力のモードを設定する */
int set_inkey( int mode_flag ) {
static struct termio tty_backup ; // 変更前の設定を保持
static struct termio tty_change ; // 変更後の設定を保持
/* モードを設定する */
if( mode_flag == SET ) {
ioctl( 0, TCGETA, &tty_backup ) ; // 現在の設定を読み出し
tty_change = tty_backup ; // 現在設定のスタック
tty_change.c_lflag &= ~( ECHO | ICANON ) ; // エコーを止め、RAW モードへ変更
tty_change.c_cc[ VMIN ]= 0 ; // 0文字入力された時点で入力を受け取る
tty_change.c_cc[ VTIME ] = 0.01 ; // 何も入力がない場合、1msec待つ (1 = 1/10sec)
ioctl( 0, TCSETAF, &tty_change ) ; // ここで設定を反映
/* モードを戻す */
} else if( mode_flag == 0 ) {
ioctl( 0, TCSETAF, &tty_backup ) ; // スタックしていた設定に戻す
}
return 0;
}
※ このブログシステムでは#や[が機能文字扱いなので、上記ではこれらを全角文字で書いています。
#C言語
ファンクションキーやカーソルキーなどの複数バイトでキーコードを出すキーも扱えます。shiftやAltなどの装飾キーは拾えませんケド。
入力の待ち時間はありません。get_inkey()はすぐ戻ってきます。戻り値はキーコードの長さを表しますが、0なら入力が無かったと判別出来ます。
得られるのは標準入力からのASCIIコードです。read()はキャッシュを読むだけでタイミング次第では取得値に複数のキーコードが混じることがありますが、これをキー単体のコードとして仕分けています。キャッシュの一番前のキーコードだけを取り出す単純な仕分けで、想定外のキーコードは読み飛ばしていますが十分でした。
キーコードで何かをするにはswitch文やif文でそのコードを仕分ける必要があります。
正常に動かすなら、100msec(1/10秒)毎以下でget_inkey()を読みに行く必要があります。
定数設定とプロトタイプ宣言をヘッダーファイルに書けばincludeしてライブラリとして使えます。mainはコメント化して使った方がいいですけど。
Raspberry Pi 4B / Rasbian11_32bit(blueseye) / OS標準gcc
/* ---------------------------------
リアルタイムにキー入力をチェックする
--------------------------------- */
/* getcharはキー入力のキャッシュが空だと入力があるまで待つ。
キャッシュが無いなら無いでそのまま抜けたいが、タイムアウトを設定しても
抜けない。環境に寄るのかもしれないが、ioctl.hを用いることで
タイムアウトが実現できた。
get_inkeyの呼び出しは100msec(1/10秒)毎以下で繰り返し行うこと。短い方がいい。
*/
/* ライブラリ読み込み */
#include <stdio.h>
#include <sys/ioctl.h>
#include <termios.h>
#include <unistd.h>
#include <time.h>
/* 定数設定 */
#define SET 1 // ioctl.readのモードをRawにするフラグ
#define RESET 0 // ipctl.readのモードをCanonicalに戻すフラグ
#define LENGTH_STACK 32 // キー入力のスタック長 状況によるが、長めにしないと取り出しが半端になる
#define ESC 0x1B // ASCIIコード ESC
#define BRACKET 0x5B // ASCIIコード [
/* プロトタイプ宣言 */
int get_inkey( char *get_char ) ; // キー入力を取得する関数
// 戻り値 // -1=エラー、0>=取得したキーコードの長さ
// char *get_char // 取得したキーコードを返すポインタ
int set_inkey( int mode_flag ) ; // キー入力のモードを設定する関数
// int mode_flag // モードの設定フラグ 1(SET)=Rawモードにする / 0(CLR)=モードを戻す
/* テスト用main */
int main(void) {
int i ; // for文用カウンタ
char get_char[ LENGTH_STACK ] ; // 入力されたキーコードを保存する変数
int ret_inkey ; // get_inkeyからの戻り値を保存する変数
/* コンソールの設定を初期化 */
set_inkey( SET ) ;
/* 無限ループで入力したキーを表示する */
for(;;) {
usleep( 1e5 ) ;
ret_inkey = get_inkey( get_char ) ; // get_inkeyから文字取得
/* get_inkeyの戻り値を処理 */
if( ret_inkey == -1 ) break ; // 戻り値が-1ならエラーなのでループから抜けて終了
if( get_char[0] == 0x0A ) break ; // エンターキーが押されたならループを抜けて終了
/* 入力された文字を出力する */
if( ret_inkey > 0) {
for( i = 0; i < ret_inkey; i++ ) {
if( get_char[i] >= 0x20 && get_char[i] <= 0x7E ) { // 入力された文字を出力する・・・表示可能な文字
printf( " %c<%02X>", get_char[i], get_char[i] ) ;
} else if( get_char[i] >= 0x00 && get_char[i] <= 0xFF ) { // 入力された文字を出力する・・・表示不可能な文字
printf( " <%02X>", get_char[i] ) ;
}
}
printf( "\n" ) ;
}
fflush( stdout ) ; // 画面表示のスタックを吐き出す
}
/* 正常終了 */
printf( "\n" ) ; // 念のための改行
set_inkey( RESET ) ; // コンソールの設定を元に戻す
return 0 ;
}
/* キー入力を取得する */
int get_inkey( char *get_char) {
// char *get_char // キーコードを返すためのchar配列のポインタ
int i ; // for用変数
char in_char[ LENGTH_STACK ] = { 0x00 }; // 入力されたキーを取得
int read_length ; // read()戻り値 キーコードのバイト数
int put_length = 0 ; // 戻り値 キーコードのバイト数
/* get_charの初期化 */
for( i = 0; i < LENGTH_STACK; i++ ) { // すべての値を0x00にする
get_char[ i ] = 0x00 ;
}
/* キー入力を読み取る */
read_length = read( 0, &in_char, LENGTH_STACK ) ; // read_lengthに取得バイト数、in_charにキーコードを得る
/* 取得値の仕分け */
if( read_length < 0 ) { // 取得エラーなのでエラーを返して終了
return -1 ;
} else if( read_length == 0 ) { // キーコードを得られなかったのでゼロを返す
return 0 ;
} else if( read_length == 1 // 取得が1バイトか先頭バイトがESC(0x1B)以外なら先頭バイトを返す
|| in_char[ 0 ] != ESC ) {
get_char[ 0 ] = in_char[ 0 ] ; // 値コピー
return 1 ;
} else if( read_length > 2 // 3バイト以上で先頭2バイトが0x1B(ESC)、0x5B([)なら
&& in_char[ 0 ] == ESC // ファンクションキーまたはカーソルキー
&& in_char[ 1 ] == BRACKET ) {
get_char[ 0 ] = ESC ; // 0バイト目
get_char[ 1 ] = BRACKET ; // 1バイト目
put_length = 2; // 戻り値設定
for( i = 2; i < read_length; i++ ) { // 2バイト目以降をコピー
if( in_char[ i ] == ESC ) break ; // 末尾にESCがあれば終了
get_char[ i ] = in_char[ i ] ; // 値コピー
put_length++ ; // 戻り値インクリメント
}
return put_length ; // 戻り値送って終了
}
return 0 ;
}
/* キー入力のモードを設定する */
int set_inkey( int mode_flag ) {
static struct termio tty_backup ; // 変更前の設定を保持
static struct termio tty_change ; // 変更後の設定を保持
/* モードを設定する */
if( mode_flag == SET ) {
ioctl( 0, TCGETA, &tty_backup ) ; // 現在の設定を読み出し
tty_change = tty_backup ; // 現在設定のスタック
tty_change.c_lflag &= ~( ECHO | ICANON ) ; // エコーを止め、RAW モードへ変更
tty_change.c_cc[ VMIN ]= 0 ; // 0文字入力された時点で入力を受け取る
tty_change.c_cc[ VTIME ] = 0.01 ; // 何も入力がない場合、1msec待つ (1 = 1/10sec)
ioctl( 0, TCSETAF, &tty_change ) ; // ここで設定を反映
/* モードを戻す */
} else if( mode_flag == 0 ) {
ioctl( 0, TCSETAF, &tty_backup ) ; // スタックしていた設定に戻す
}
return 0;
}
※ このブログシステムでは#や[が機能文字扱いなので、上記ではこれらを全角文字で書いています。
#C言語
2022年 この範囲を時系列順で読む この範囲をファイルに出力する
Art-Netを扱うためにはNICのアドレスを設定しなければなりません。
手計算した値をOSに手打ち設定をしてもいいのですが、どうせなら自動設定にしたい。NICのMACアドレスとArt-NetのOEMコードがわかれば人が判断する要素は無く計算も単純なのですから。
アプリケーションはPythonで書くつもりですが、OSの自動設定はbashスクリプトで書くのが自分流です。なぜなら、PythonでOS設定を変更すると結局はbashコマンドを発行するのですから同じ事です。なんでもかんでも高級言語を使えばいいってもんでもないんです。
やることは、MACアドレスを文字列で取得し、必要な部分を切り出し、一部の文字列を数値に変換して計算し、IPアドレス起こしてコマンド文字列を作って実行するだけです。Linux(UNIX)は標準コマンドだけでこういったスクリプトを簡単に作れます。
わたしはググってコピペするだけですけどね。
#[Art-Net] #[RaspberryPi]
手計算した値をOSに手打ち設定をしてもいいのですが、どうせなら自動設定にしたい。NICのMACアドレスとArt-NetのOEMコードがわかれば人が判断する要素は無く計算も単純なのですから。
アプリケーションはPythonで書くつもりですが、OSの自動設定はbashスクリプトで書くのが自分流です。なぜなら、PythonでOS設定を変更すると結局はbashコマンドを発行するのですから同じ事です。なんでもかんでも高級言語を使えばいいってもんでもないんです。
やることは、MACアドレスを文字列で取得し、必要な部分を切り出し、一部の文字列を数値に変換して計算し、IPアドレス起こしてコマンド文字列を作って実行するだけです。Linux(UNIX)は標準コマンドだけでこういったスクリプトを簡単に作れます。
わたしはググってコピペするだけですけどね。
#[Art-Net] #[RaspberryPi]
本業も工作も取り急ぎの課題が無い状況です。精神的に追われる感覚が無いのは久しぶりです。
Art-NetをRaspberryPiで扱う研究の準備は進めていますが、気持ちとしてはユッタリしております。
ヒマってことは稼ぎが無いことでもあるので、あまり良い状況でもないのですが・・・
Art-Netを扱うRaspberryPiでは同一ゼグメントのIPアドレスを振った2つ以上のNICを別ゾーンとして扱うことが肝になります。入力のArt-Netと出力のArt-Netを1つのRaspberryPiで扱うには必要条件です。
この状態はサーバーやネットワークを複雑に組むと発生し得ることなので可能だと思うのですが、私が適切な設定やプログラミングを出来るかは別問題なので、その研究というか勉強をするワケです。
となると、実験用に複数のRaspberryPiが必要です。
1台は公式7吋モニタで組んだ方が後々の表示作りで都合が良いと思いますが、他はモニタを持たずにSSHでアクセス出来れば済むので、数台をまとめられる箱もあるといいですね。
この様な箱は既製品にもあるにはありますが、RaspberryPiを束に出来るだけで、電源が考慮されいないだけでなく組んでしまうとGIPOに触りにくい状態になります。これじゃダメです。
作るのも面倒なので改めて探してはみますが、キレイにカットしてキレイに塗装した1枚板に必要な物を取り付ければそれでもいいのかな?とも思っております。
#[Art-Net] #[RaspberryPi]
Art-NetをRaspberryPiで扱う研究の準備は進めていますが、気持ちとしてはユッタリしております。
ヒマってことは稼ぎが無いことでもあるので、あまり良い状況でもないのですが・・・
Art-Netを扱うRaspberryPiでは同一ゼグメントのIPアドレスを振った2つ以上のNICを別ゾーンとして扱うことが肝になります。入力のArt-Netと出力のArt-Netを1つのRaspberryPiで扱うには必要条件です。
この状態はサーバーやネットワークを複雑に組むと発生し得ることなので可能だと思うのですが、私が適切な設定やプログラミングを出来るかは別問題なので、その研究というか勉強をするワケです。
となると、実験用に複数のRaspberryPiが必要です。
1台は公式7吋モニタで組んだ方が後々の表示作りで都合が良いと思いますが、他はモニタを持たずにSSHでアクセス出来れば済むので、数台をまとめられる箱もあるといいですね。
この様な箱は既製品にもあるにはありますが、RaspberryPiを束に出来るだけで、電源が考慮されいないだけでなく組んでしまうとGIPOに触りにくい状態になります。これじゃダメです。
作るのも面倒なので改めて探してはみますが、キレイにカットしてキレイに塗装した1枚板に必要な物を取り付ければそれでもいいのかな?とも思っております。
#[Art-Net] #[RaspberryPi]