全年全月31日の投稿(時系列順)[20件]
2021年10月 この範囲を新しい順で読む この範囲をファイルに出力する
今日(昨日?)も現場に出る前の空き時間に客席テーブルを進めました。穴埋めです。
今の天板では3種類目の脚ですから余計な穴だらけ。3種類は機構が全く違うので穴位置が同じワケなし。
更なる改良が出たら新しい天板を作りますが、今のこれはαバージョン4.2(0.0.42)、もしくは格上げしてβバージョン0.1(0.1.0)として使っていこうと思います。
リリースバージョン1.0(1.0.0)は何時になることやら・・・
穴埋めにはコニシのEセットを使っています。エポキシ接着剤です。
消えて無くなった以前のブログに書きましたが、穴埋めにはパテより実用的。接着剤なので食いつきは良いですし硬度もある。
作業してて気づいたのですが、キチンと混ざると(反応が始まると?)匂いがわずかに変わるようです。2液がシッカリ混ざっていないと効果を発揮しませんので目安になる気がします。
#ガチ工作
今の天板では3種類目の脚ですから余計な穴だらけ。3種類は機構が全く違うので穴位置が同じワケなし。
更なる改良が出たら新しい天板を作りますが、今のこれはαバージョン4.2(0.0.42)、もしくは格上げしてβバージョン0.1(0.1.0)として使っていこうと思います。
リリースバージョン1.0(1.0.0)は何時になることやら・・・
穴埋めにはコニシのEセットを使っています。エポキシ接着剤です。
消えて無くなった以前のブログに書きましたが、穴埋めにはパテより実用的。接着剤なので食いつきは良いですし硬度もある。
作業してて気づいたのですが、キチンと混ざると(反応が始まると?)匂いがわずかに変わるようです。2液がシッカリ混ざっていないと効果を発揮しませんので目安になる気がします。
#ガチ工作
2022年1月 この範囲を新しい順で読む この範囲をファイルに出力する
本業も工作も取り急ぎの課題が無い状況です。精神的に追われる感覚が無いのは久しぶりです。
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]
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]
2022年3月 この範囲を新しい順で読む この範囲をファイルに出力する
何をすればいいかが見えている修理は楽ですが、どこがおかしくてどうすればいいのかがわからない修理は気疲れします。
昨日から手を付けているウォッシュタイプのムービングですが、今のところですけど、ICのハンダ付が原因だったように思われます。
今まで正常に動いていたのですから付いてはいるのですが、盛り方が悪くハンダに髭が出ていて、そこに汚れが溜まって短絡とは言えない微妙な接触が発生して隣の端子に漏れ電流が流れてしまったようです。ピンが細くて間隔も狭いICですから肉眼で見ただけではわかりませんが、試しにアルコールを吹きかけて歯ブラシで擦ったところ一時回復。再起動で再発したのでハンダ吸収線でなぞったら今のところ発症せずです。
明日はミニ顕微鏡で確認し、ヤバそうなのがあれば針の様に先端が細いハンダゴテで整えてみます。
プロファイル系のはリニアブッシュを交換して一応の回復。
#照明器具 #本業
昨日から手を付けているウォッシュタイプのムービングですが、今のところですけど、ICのハンダ付が原因だったように思われます。
今まで正常に動いていたのですから付いてはいるのですが、盛り方が悪くハンダに髭が出ていて、そこに汚れが溜まって短絡とは言えない微妙な接触が発生して隣の端子に漏れ電流が流れてしまったようです。ピンが細くて間隔も狭いICですから肉眼で見ただけではわかりませんが、試しにアルコールを吹きかけて歯ブラシで擦ったところ一時回復。再起動で再発したのでハンダ吸収線でなぞったら今のところ発症せずです。
明日はミニ顕微鏡で確認し、ヤバそうなのがあれば針の様に先端が細いハンダゴテで整えてみます。
プロファイル系のはリニアブッシュを交換して一応の回復。
#照明器具 #本業
2022年5月 この範囲を新しい順で読む この範囲をファイルに出力する
間数マーカーver4.3が1台組めました。
重箱の隅を突く様な目で見るなら改善したい点はありますが現場で使えるレベルです。
電池の持ちを確認していますが、目標値である単三電池1個で12時間はクリア。現場的にはOKでしょう。
乾電池は特性的にエネループなどの容量の大きな充電池がよさそうです。なぜなら、アルカリ電池などの1次電池は一定の割合で電圧が下がっていきますが、エネループは使用開始直後に一定値まで下がってからは切れる直前まで電圧がほとんど下がりませんので、一定の光量で発光し続けることが期待できるからです。
発光面には不満が残りますが使えるレベルです。φ3mmの砲弾型LED2個からの光を厚み5mmの透明樹脂板を通して130×65mmの面に誤差±20%くらいの輝度で散らしていますが、これ以上は導光機構を金型から起こさないと難しいと思います。これ以上時間とお金をかけて精彩を求めても使用感は違わないと思われるので落としどころでしょう。
試作は終わりとし、1個30時間かかるプリントをチマチマやっていきます。
追記
消える瞬間は見ていませんが、13時間経過で点いており、14時間経過で消灯していました。
電池のコンディションもありますので、公称値を8割の10時間とします。
推奨電池はPanasonicのeneloop(エネループ・単三電池型・1.2v1900mAh)です。
販売は予定しておりません。
3Dプリンタの稼働コストを500円/時としていますが、30時間では15,000円です。電気代とフィラメントの消費量からするとこんなもんです。
内部の部品原価は3,000円くらい。発光部を構成する専用基板や樹脂部品がそれなりにします。
組み立ても何気に面倒なので開発費を含む手間賃やらで10,000円は欲しい。
合計28,000円/台(笑
自分だったら買わない価格です。
アチコチにモックアップを見せて価格イメージ聞いたところ3,000~5,000円でした。自分もそう思います。
試作品の価格は量産品の10倍でも安い部類ですが、量産化の初期費用や在庫を抱える気はないので、作るなら毎回試作価格になってしまいます。
これでは売る側にも買う側にもメリットがありませんので、自分が使う分だけ作ることにしました。
#舞台の小物
重箱の隅を突く様な目で見るなら改善したい点はありますが現場で使えるレベルです。
電池の持ちを確認していますが、目標値である単三電池1個で12時間はクリア。現場的にはOKでしょう。
乾電池は特性的にエネループなどの容量の大きな充電池がよさそうです。なぜなら、アルカリ電池などの1次電池は一定の割合で電圧が下がっていきますが、エネループは使用開始直後に一定値まで下がってからは切れる直前まで電圧がほとんど下がりませんので、一定の光量で発光し続けることが期待できるからです。
発光面には不満が残りますが使えるレベルです。φ3mmの砲弾型LED2個からの光を厚み5mmの透明樹脂板を通して130×65mmの面に誤差±20%くらいの輝度で散らしていますが、これ以上は導光機構を金型から起こさないと難しいと思います。これ以上時間とお金をかけて精彩を求めても使用感は違わないと思われるので落としどころでしょう。
試作は終わりとし、1個30時間かかるプリントをチマチマやっていきます。
追記
消える瞬間は見ていませんが、13時間経過で点いており、14時間経過で消灯していました。
電池のコンディションもありますので、公称値を8割の10時間とします。
推奨電池はPanasonicのeneloop(エネループ・単三電池型・1.2v1900mAh)です。
販売は予定しておりません。
3Dプリンタの稼働コストを500円/時としていますが、30時間では15,000円です。電気代とフィラメントの消費量からするとこんなもんです。
内部の部品原価は3,000円くらい。発光部を構成する専用基板や樹脂部品がそれなりにします。
組み立ても何気に面倒なので開発費を含む手間賃やらで10,000円は欲しい。
合計28,000円/台(笑
自分だったら買わない価格です。
アチコチにモックアップを見せて価格イメージ聞いたところ3,000~5,000円でした。自分もそう思います。
試作品の価格は量産品の10倍でも安い部類ですが、量産化の初期費用や在庫を抱える気はないので、作るなら毎回試作価格になってしまいます。
これでは売る側にも買う側にもメリットがありませんので、自分が使う分だけ作ることにしました。
#舞台の小物
2022年8月 この範囲を新しい順で読む この範囲をファイルに出力する
2022年10月 この範囲を新しい順で読む この範囲をファイルに出力する
本業系では「階段」を作っております。
一体の豪勢なモノではなく、4寸厚の平台を組み合わせて構成するための補助的な物です。
一般的な舞台道具で台を作りますと、高さが4寸、7寸、1尺、1尺4寸、1尺5寸、2尺1寸、2尺8寸になろうかと思います。
この中の数字を拾いますと、均等段差の階段を構成するなら7寸ピッチが都合良いと思うのですが、履きなれないヒール、着慣れない和装、ご高齢の方に7寸ピッチの段差は大きすぎる様子。特に降りる時が辛そう。
なら適切な段差はどのくらいかと聞かれれば正解は無いかもしれませんが、平台の厚み以上で組み合わせ的に都合が良く出来るだけ低い段差がよろしいかなと。1尺4寸を1/3にした4寸6分7厘(約141mm)などいかがでしょう。
先日、先の現場の舞台リハがあったので試作品を持ち込んで試してみたのですが、和装の方が裾を引くことも無く自然に昇り降りしていました。いいんでないかなと。
この考え方で整理しますと、4寸高の平台の高さを増すという意味で、7分高のゲタ、1寸高のゲタ、5寸3分4厘高の箱、6寸5分高の箱を作ったらどうかと。1尺高には5寸高、1尺4寸(2尺8寸)高には4寸7分高と9寸3分4厘高、2尺1寸高には5寸高と1尺5分高と1尺5寸8分4厘高の階段を当てられます。完全な均等ピッチにするのは面倒なのでやりたくありませんが、現実の平台の精度と自分工作精度からすれば、ピッチ誤差は3分以下で収まればいいかなと。
もちろん、1×3、1×6の平台も作っています。
ちょっと手間ですが、階段を構成しやすい体制を作っておくと何かとよろしいかなと。
#ガチ工作
一体の豪勢なモノではなく、4寸厚の平台を組み合わせて構成するための補助的な物です。
一般的な舞台道具で台を作りますと、高さが4寸、7寸、1尺、1尺4寸、1尺5寸、2尺1寸、2尺8寸になろうかと思います。
この中の数字を拾いますと、均等段差の階段を構成するなら7寸ピッチが都合良いと思うのですが、履きなれないヒール、着慣れない和装、ご高齢の方に7寸ピッチの段差は大きすぎる様子。特に降りる時が辛そう。
なら適切な段差はどのくらいかと聞かれれば正解は無いかもしれませんが、平台の厚み以上で組み合わせ的に都合が良く出来るだけ低い段差がよろしいかなと。1尺4寸を1/3にした4寸6分7厘(約141mm)などいかがでしょう。
先日、先の現場の舞台リハがあったので試作品を持ち込んで試してみたのですが、和装の方が裾を引くことも無く自然に昇り降りしていました。いいんでないかなと。
この考え方で整理しますと、4寸高の平台の高さを増すという意味で、7分高のゲタ、1寸高のゲタ、5寸3分4厘高の箱、6寸5分高の箱を作ったらどうかと。1尺高には5寸高、1尺4寸(2尺8寸)高には4寸7分高と9寸3分4厘高、2尺1寸高には5寸高と1尺5分高と1尺5寸8分4厘高の階段を当てられます。完全な均等ピッチにするのは面倒なのでやりたくありませんが、現実の平台の精度と自分工作精度からすれば、ピッチ誤差は3分以下で収まればいいかなと。
もちろん、1×3、1×6の平台も作っています。
ちょっと手間ですが、階段を構成しやすい体制を作っておくと何かとよろしいかなと。
#ガチ工作
2022年12月 この範囲を新しい順で読む この範囲をファイルに出力する
2022年の大晦日です。
コロナの感染拡大は完全に収まりはしなかったものの、仕事ではその影響も和らぎ忙しくさせて頂いた一年でした。
ご協力を頂いた各方面の方々に改めて感謝申し上げます。
ただ、体力的には過負荷が続いたもので、年末休暇に入ってからの2日間は完全にシャットダウン。大晦日の今日になってようやく普通に戻ってきた感じです。
年末にやるべきことの大半が出来ませんが、少しはこなして実家にも顔を出しましょう。
C言語の書き方は妄想だけなので合間に少し進めます。
#雑談
コロナの感染拡大は完全に収まりはしなかったものの、仕事ではその影響も和らぎ忙しくさせて頂いた一年でした。
ご協力を頂いた各方面の方々に改めて感謝申し上げます。
ただ、体力的には過負荷が続いたもので、年末休暇に入ってからの2日間は完全にシャットダウン。大晦日の今日になってようやく普通に戻ってきた感じです。
年末にやるべきことの大半が出来ませんが、少しはこなして実家にも顔を出しましょう。
C言語の書き方は妄想だけなので合間に少し進めます。
#雑談
2023年1月 この範囲を新しい順で読む この範囲をファイルに出力する
キー入力の処理を書き直してみました。
ファンクションキーやカーソルキーなどの複数バイトでキーコードを出すキーも扱えます。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言語