コグノスケ


2024年3月3日

解像度の設定を保存する

目次: Linux

Raspberry Pi 3 Model B (以降RasPi 3B)のHDMI出力の解像度はFull HDがデフォルト設定です。今日日のディスプレイで困ることはほぼありませんが、古いアスペクト比4:3のディスプレイなど、Full HD以外の解像度で出力してほしいときが稀にあります。

RasPi 3Bに限りませんけど、X Window Systemはxrandrコマンドで解像度を手軽に変更できます。しかし解像度の設定は保存されず、セッションを終了したり再起動すると元のFull HD出力に戻ります。まあ、これはこれで誤った設定のまま固定されないというありがたい面もあるものの、普通は再起動後も解像度を維持してほしいです。

調べるとX Window Systemの設定ファイルを変更するか、autorandrコマンドで解像度を維持できるみたいです(autorandrのソースコード)。例として1024x768 60Hzの解像度で維持するやり方を挙げます。

autorandrの使い方の例
$ apt-get install autorandr

$ xrandr -s 1024x768 --rate 60
$ autorandr --save (profile名)

設定は~/.config/autorandr/(profile名)/というディレクトリに保存されます。

autorandrとXDG autostart機能

起動時に解像度を変更している方法が気になったので調べると、XDG autostart(Desktop Application Autostart Specification)を使って実現していました。

Linuxのデスクトップ環境は実装ごとに自動起動の方法が違いますが、XDG autostartは多数のデスクトップ環境が対応している自動起動の仕組みのようです。私が使っている64bit版Raspberry Pi OSはデスクトップ環境としてLXDE (Lightweight X11 Desktop Environment)を採用していて、LXDEもXDG autostartに対応しています。

XDG autostartはデスクトップ表示の際に/etc/xdg/autostart/ディレクトリの下の設定を全部実行します。autorandrの設定は/etc/xdg/autostart/autorandr.desktopにありました。

autorandr.desktopの中身
[Desktop Entry]
Name=Autorandr
Comment=Automatically select a display configuration based on connected devices
Type=Application
Exec=/usr/bin/autorandr -c --default default
X-GNOME-Autostart-Phase=Initialization

実行されるコマンドラインのうちオプション-cはchangeの意味で、最初に見つけたprofileの解像度に変更します。オプション--defaultはdefaultという名のprofileを使うように変更する指令らしいのですが、効き目が良くわかりません。

もし複数のprofileが存在していた場合にどれが選ばれるのか気になるので、デバッグオプションを付けて実行してみましょう。

複数のprofileがある場合のautorandr -cの挙動
$ autorandr -c --default default --debug

fullhd (detected) (1st match) (current)
xga (detected) (2nd match)
| Differences between the two profiles:
| [Output HDMI-1] Option --mode (= `1920x1080') is `1024x768' in the new configuration
\-
Config already loaded

$ autorandr -l xga

$ autorandr -c --default default --debug

xga (detected) (1st match) (current)
fullhd (detected) (2nd match)
| Differences between the two profiles:
| [Output HDMI-1] Option --mode (= `1024x768') is `1920x1080' in the new configuration
\-
Config already loaded

こんな動作をしました。最後に利用もしくは保存したprofileが使われるみたいですね。

編集者:すずき(2024/03/19 11:07)

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



2024年3月4日

volatileをnon-volatileで参照してはいけない

目次: GCC

過去の日記(2021年3月13日の日記参照)にプログラムがバグっていて未定義動作だ(つまりGCCのせいじゃない)とコメントいただいたので、C11規格を眺めていました。

C11 committee draft(N1570) 6.7.3 Type qualifiersの6に、volatileとnon-volatileを併用したときの未定義動作の記述がありました。

N1570
6.7.3 Type qualifiers

...

6
If an attempt is made to modify an object defined with a const-qualified type through use of 
an lvalue with non-const-qualified type, the behavior is undefined. If an attempt is made to 
refer to an object defined with a volatile-qualified type through use of an lvalue with 
non-volatile-qualified type, the behavior is undefined. 133)

133) This applies to those objects that behave as if they were defined with qualified types, 
even if they are never actually defined as objects in the program (such as an object at a 
memory-mapped input/output address).

(ざっくり訳)
const-qualified型で定義したオブジェクトをnon-const-qualified型の左辺値(lvalue)を使用して変更した場合、
動作は未定義です。volatile-qualified型で定義したオブジェクトを、non-volatile-qualified型の左辺値で参照した場合、
動作は未定義です。

133)
たとえプログラム内でオブジェクトとして定義されていなくても、これ(注: 上記の6のこと)は修飾された型で定義されたように
振る舞うオブジェクト(メモリマップされたI/Oアドレスにあるオブジェクトなど)に適用されます。

未定義動作ならmemmoveやmemcopyに何が起きても不思議ではないですね。C言語難しいわ……。

編集者:すずき(2024/03/06 00:09)

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



2024年3月6日

Raspberry Pi 3 model Bの代わりにROCK 3 model C

目次: Arduino

最近、M5Stamp C3 + Raspberry Piを組み合わせて的あてゲームを作っています。Bluetooth通信クライアント側のLinuxマシンにRaspberry Pi 3 model Bを使っているものの、販売終了につき新品が手に入りません。今は1台あれば良いので困りませんが、後でN増しするとき困りそうです。

Linuxマシン側の要件を挙げると、

  • Must: Linuxが動作、x86でもARMでも良い
  • Must: HDMI出力、USBホスト機能
  • Want: Bluetooth 4.0以上(BLEを使う)
  • Want: Raspberry Pi 3より速い、Raspberry Pi 5ほど性能は要らない
  • Want: 昔のRaspberry Pi 3Bくらいの価格(5,000円くらい)

まず値段的にx86のノートPCやNUCは購入候補から外れます(中古品でも厳しい)。ARMのSBCですと、FRIENDLY ELECのNanoPi R5系(Rockcihp RK3568B, Cortex-A55 x 4)か、OKDO/Radxa ROCK 3 model C 1GB版(Rockchip RK3566, Cortex-A55 x 4)がちょうど良さそうでした。

NanoPiとROCK 3はどちらでも良かったのですが、RSコンポーネンツで容易に購入できるROCK 3 model C 1GB版に決めました。

JavaのGraphics 2Dが遅い?

ROCK 3 model CはRaspberry Pi 3 model Bを置き換えるにふさわしい製品だと思いますが、私の使い方だと1点だけ問題があって、Javaの画面描画が致命的に遅いです。5秒に1回くらいしか描画されません。このままでは使いたい目的に合いません。

最初にGPUが有効になっているか確認です。GPU使用率を/sys/devices/platform/fed60000.gpu/utilizationを見ると、無負荷のときは0、アプリ起動時で20くらいでGPUは動いています。問題なさそうです。むしろ暇しているというか余裕すらありそうです。Javaのライブラリ系orアプリ実装の問題でしょう。

次にJavaのライブラリ系を確認です。現在、画面描画のダブルバッファリングに使っているのはBufferStrategyで、BufferStrategyが返すVolatileImageのisAccelerated()はTrueを返します。OpenGLによるHW描画が使われているようです。これも問題なさそうです。残るはアプリ実装の問題ですね。

余談ですが下記のようにGraphics2D経由で確認すると、

Graphics2D経由でisAccelerated()を呼ぶ
((Graphics2D)strategy.getDrawGraphics()).getDeviceConfiguration().getImageCapabilities().isAccelerated()

なぜかisAccelerated()がFalseになります。良くわからん動きです。

Graphics2Dのアンチエイリアス機能が遅い

タイトルの通りですが、アプリ実装が原因でした。コードでいえば下記の部分です。

図形描画とテキスト描画のアンチエイリアスON

Graphics2D g2;

g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);

図形描画とテキスト描画のアンチエイリアスをONにして使っていましたが、このうち図形描画のアンチエイリアスをONにすると著しく描画速度が下がることがわかりました。Raspberry Pi 3 model Bは双方のアンチエイリアスをONにしても特に問題がなかったため、気づくまで結構手間取りました。

図形描画のアンチエイリアスは今のところ見た目にさほど影響がないので、OFFにしました。テキスト描画のアンチエイリアスも描画速度に多少影響ありますが、OFFにすると見た目が悪くなりすぎるので、ONのまま使います。

問題の解決はしていませんが、回避できたのは良かったです。勢いで3つも買ってしまったROCK 3 model Cの不良在庫化を避けられました……。

編集者:すずき(2024/03/12 01:18)

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



2024年3月8日

JavaとM5Stamp C3とBluetooth LE - BluetoothデバイスとServiceの列挙

目次: Arduino

M5Stamp C3をBluetooth LEデバイスにして、Linux PCもしくはRaspberry PiなどのLinux SBCとお話する取り組みの続編です。

今回はbluez-dbusを使ってBluetoothデバイスの列挙、GATTのServiceの列挙を行います。

アダプタとデバイスの列挙

DeviceManagerというクラスとDeviceManagerクラスのスタティックメソッドが、bluez-dbusを使うときの根っこになります。

DeviceManagerのインスタンスを作成するため最初にcreateInstance()を呼ぶ必要があります。1回で良いです。これ以降はDeviceManager.getInstance()でDeviceManagerのインスタンスが取得できます。引数はfalseならシステム全体用のバスインタフェース、trueなら現在のログインセッション用のバスインタフェースに接続します。Bluetoothの仕組みとは関係なくて、Bluezが依存しているD-Busの仕組みが透けて見えています。たぶんfalseで良いはず。

bluez-dbusの初期化、createInstance()の呼び出し

//一番最初に1回呼ぶ
DeviceManager.createInstance(false);

//以降はgetInstance()でDeviceManagerオブジェクトを取得できる
DeviceManager.getInstance();

システムに存在するBluetoothアダプターの一覧を得る方法はこんな感じです。お手軽です。

Bluetoothアダプタの列挙

DeviceManager deviceManager = DeviceManager.getInstance();

List<BluetoothAdapter> adapters = deviceManager.getAdapters();

Bluetoothアダプターを1つ選んだら、Bluetoothデバイスを探して(Discovery)、ある程度時間を置いて見つかったデバイスの一覧を取得します。

Bluetoothデバイスの列挙

BluetoothAdapter adapter;

adapter.startDiscovery();
try {
    Thread.sleep(3000);
} catch (InterruptedException ex) {
    //ignore
}
adapter.stopDiscovery();

List<BluetoothDevice> devices = deviceManager.getDevices(true);

注意点としてはstartDiscovery()とstopDiscovery()の間はある程度の時間を開けないとデバイスが1個も見つかりません。

Serviceの列挙

Bluetoothデバイス特にBLE(Bluetooth Low Energy)デバイスとはGATTプロファイルを使って通信します。BluetoothにはATTプロトコル(Attribute Protocol)という属性をやり取りするプロトコルがあります。GATTはATTプロトコルの上で汎用的(Generic)にデータを通信するための取り決め(プロファイル)になります。

GATTというかATTはクライアント・サーバー方式のプロトコルでして、BLEデバイスはサーバーになります。サーバーはService(=提供する機能)を1つもしくは複数持っています。1つのService内にはCharacteristicが並んでおり、CharacteristicにはValueとDescriptorが並んでいます。こんな感じです。

GATTサーバー(BLEデバイス)
Service
Characteristic
  • Value
  • Descriptor
  • Descriptor
  • ...
Characteristic
  • Value
  • Descriptor
Service
Characteristic
...
Characteristic
...

通信に使うのはCharacteristicですが、いきなりCharacteristicを列挙することはできません。上位側にあるServiceから列挙します。Serviceを探すにはconnect()してgetGattServices()を呼びます。connect()とdisconnect()は数秒レベルで時間がかかります。

今回はM5Stamp C3に対してペアリングなしで接続しています。ペアリングなし=通信路の盗聴や乗っ取りをされる可能性があります。今回は特に困らないのでこのまま話を進めますが、盗聴や乗っ取りをされると困る場合はペアリングをする必要があります。ペアリングの方法もご紹介したいですが、今はやり方がわかりません。わかったらまた別の日記にでも書きます。

Serviceの列挙
BluetoothDevice device;
device.connect();
device.refreshGattServices();

List<BluetoothGattService> gattServices = device.getGattServices();

device.disconnect();

GATTのService内のCharacteristicを探すにはgetGattCharacteristics()を呼びます。

Characteristicの列挙

BluetoothGattService srv;
srv.refreshGattCharacteristics();

List<BluetoothGattCharacteristic> gattCharacteristics = srv.getGattCharacteristics();

CharacteristicのDescriptorも取得できます(getGattDescriptors()メソッドを使います)が、今回は特に必要ありませんので列挙するためのコードは割愛します。

送受信の方法はまた今度。

編集者:すずき(2024/03/16 23:03)

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



2024年3月9日

車のバッテリー完全に死亡で交換かと思いきや

目次:

またまた車のバッテリーが干上がって死にました。写真は撮っていませんが2Vくらいになっていたように思います。

しかし今日はディーラーでの半年点検の日でディーラーに行かなければならないので、ジャンプスタートしてエンジンをかけてディーラーまで行きました。去年買った(2023年4月22日の日記参照)KashimuraのジャンプスターターKD-238が大活躍です。活躍しないほうが本当は良いけど。

ディーラーに辿り着いて車を預けたら、ディーラーの駐車場から動かそうとしたらバッテリーが上がってて動かせなかった、ジャンプスタートしたと言われました。ごめんね……。

ディーラーからの意外な提案

またバッテリー交換で財布が軽くなるな〜と思っていたら、整備士さんからは意外な提案が返ってきました。

  • 一時的にディーラー所有のバッテリーに交換して車を返す
  • 上がった方のバッテリーは1週間掛けて充電してみる
  • バッテリーが充電できたら連絡するからまた来てほしい

とのこと。

バッテリー交換以外の新たなパターンに出会いました。交換して1年、走行距離も1000km程度、バッテリーはこんなに劣化しないはず?と判断したみたいです。たぶん安く何とかしてみたい、というご提案だと理解して素直に承諾しました。

バッテリー復活なるか?いつもと違うので楽しみですね。

編集者:すずき(2024/03/16 00:56)

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



2024年3月10日

誕生日

早いもので41歳になりました。昨年の日記(2023年3月10日の日記参照)を見ると、コロナの流行を心配していました。

コロナの流行は相変わらずのように思いますが、世の人々はもう対策に疲れたのか、感染リスクを無視して暮らすスタイルが定着したようです。個人的には感染しないに越したことはないので、これからもマスクなど予防は心がけたいと思います。花粉症にもなりたくないし……。

働き方はリモート10割から、リモート:出社=7:3〜5:5くらいの割合に落ち着きつつあります。特にオフィスに用事がなければ行かないなんて、昔では考えられない通勤スタイルですね。

この働き方の利点は「遠隔地に居る人」が気にならなくなることです。オフィスに集まる場合を除けば、家も沖縄も北海道も大して変わらないのです。実際、東京から離れて住んでいる人もいるようですね。

編集者:すずき(2024/03/15 03:34)

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



2024年3月14日

JavaとM5Stamp C3とBluetooth LE - Bluetoothデバイスとの通信

目次: Arduino

M5Stamp C3をBluetooth LEデバイスにして、Linux PCもしくはRaspberry PiなどのLinux SBCとお話する取り組みの続編です。

今回はbluez-dbusを使ってBluetoothデバイスと通信します。

データ通信の仕組み

前回の話と少し重複しますが、Bluetoothデバイス特にBLEデバイスとはGATTプロファイルを使って通信します。BLEデバイスはサーバーになります。サーバーはService(=提供する機能)を1つもしくは複数持っていて、Service、Characteristic、ValueとDescriptorが入れ子の構造になっています。

GATTサーバー(BLEデバイス)
Service
Characteristic
  • Value
  • Descriptor
  • Descriptor
  • ...

GATTのデータ送受信はCharacteristicのValueを読み書きすることで実現します。まずは簡単な送信側(Write)からご紹介します。

送信の方法、クライアント→サーバー(BLEデバイス)

private BluetoothGattCharacteristic GattTx;

byte[] dat = new byte[len];

//送信するデータを用意する
//...

GattTx.writeValue(bpart, null);

バイト配列を用意してwriteValue()を呼びます。書き換え属性を持っているCharacteristicでないと書き込みが失敗します。

次は受信側(Read)です。writeValue()と同様にreadValue()も用意されていて、最後にReadした値を読み出せます。しかし一度読んだ値なのか新しい値なのか区別が付きません、つまり値の更新の有無がわかりません。

最新の値を読む方法、サーバー(BLEデバイス)→クライアント

BluetoothGattCharacteristic GattRx;

byte[] dat = GattRx.readValue(null);

ではこの方法はダメなのか?というとそんなことはありません。一定時間ごとに現在値を見たい場合、例えば「温度計の値を1分ごとに読み出す」といった用途で役立ちます。

一方でストリームデータを扱う場合、新しい値がきたときだけ読み出したいので更新を検出する必要があります。検出には少しややこしい処理が必要です。bluez-dbusは何かの状態変化が起きるとPropertiesChangedというイベントで知らせてくることを利用します。使い方は、

  • AbstractPropertiesChangedHandlerを継承したハンドラクラスを作成
  • ハンドラクラスのインスタンスをDeviceManagerに登録
  • BluetoothGattCharacteristicのstartNotify()を呼ぶ(BLEデバイスからのNotifyを検知できるようになる)

コードで書くと下記のようになります。

状態変化イベントのハンドラ登録

public class PropertiesChangedHandler extends AbstractPropertiesChangedHandler {
    @Override
    public void handle(Properties.PropertiesChanged props) {
    }
}

BluetoothGattCharacteristic GattRx;

DeviceManager deviceManager = DeviceManager.getInstance();
PropertiesChangedHandler handler = new PropertiesChangedHandler(...);
deviceManager.registerPropertyHandler(handler);

GattRx.startNotify();

PropertiesChangedハンドラはCharacteristicsの値の更新も、別の関係ないイベントも何でも受け取るので、何のイベントが発生したか判定する必要があります。bluez-dbusのBluetoothGattCharacteristicクラスと、PropertiesChangedクラスはいずれもD-Busのパス(/org/bluez/hci0/dev_xx_xx_xx_xx_xx_xx/service0028/char0029のような文字列)を返すメソッドを持っていますので、D-Busのパスが一致するかどうかで確かめます。

変化した値と名前のMapをgetPropertiesChanged()で取得できるので、全要素を調べて名前がValueであり、バイト配列を保持していればCharacteristicの値の変化を通知するイベントのはずです。

イベントの種類の判別(簡易版)

BluetoothGattCharacteristic GattRx;

Map<String, Variant<?>> mapProp = props.getPropertiesChanged();

if (GattRx.getDbusPath().equalsIgnoreCase(props.getPath())) {
    for (Map.Entry<String, Variant<?>> e : mapProp.entrySet()) {
        if (e.getValue().getValue() instanceof byte[]) {
            dat = (byte[])e.getValue().getValue();
        }
    }
}

自分でBLEデバイス側の実装をしているなら、意図しないイベントが混ざることはありません。上記のコードのように簡素なチェック(例えば単にバイト配列かどうかだけチェック)でも動作するはずです。

編集者:すずき(2024/03/16 23:03)

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



2024年3月18日

画面のブランクを無効にする

目次: Linux

ROCK 3 model CのDebian bullseyeイメージは10分ほど?放置していると画面が消えてロック画面に戻る設定になっています。これはこれでありがたい動作ですが実験用に使っていてキーボードを繋いでいないことがあるので、ロック画面への移行と、画面が消える動作を無効化する方法をメモしておきます。

ロック画面の設定

ロック画面を無効化するには、Xfce4の[アプリケーション] - [設定] - [スクリーンセーバー](xfce4-screensaver-preferences)の、


xfce4-screensaver-preferences

タブ[ロック画面] - [ロック画面を有効にする]をOFFにすれば良いみたいです。再起動後も設定を覚えてくれています。

画面が消える(DPMS)設定

画面が消える機能はDPMS(Display Power Management Signaling)といって、Xfce4の設定パネルからだと[アプリケーション] - [設定] - [電源管理](xfce4-power-manager-settings)の、


xfce4-power-manager-settings

タブ[ディスプレイ] - [ブランク画面にするまでの時間]などから設定できます。しかしロック画面と違って設定を覚えてくれない?みたいで、再起動すると元に戻ってしまいます。理由が良くわからない……困った。

xsetとXDGで起動時にDPMSを設定

Xfce4は良くわからないので降参して、X Windowに頑張ってもらうことにします。DPMSの状態の設定と取得にはxsetを使います。リモートから実行するなら他のX Window Systemのアプリと同様にDISPLAY=:0などのように、どのディスプレイか指定する必要があります。

DPMSのStandby, Suspend, Offを一気に無効にするにはdpms 0 0 0と指定すれば良いです。DPMSの設定は最後の方に表示されます。

DPMSの状態の設定と取得
$ xset dpms 0 0 0

$ xset -q

Keyboard Control:
  auto repeat:  on    key click percent:  0    LED mask:  00000000
  XKB indicators:
    00: Caps Lock:   off    01: Num Lock:    off    02: Scroll Lock: off
    03: Compose:     off    04: Kana:        off    05: Sleep:       off
    06: Suspend:     off    07: Mute:        off    08: Misc:        off
    09: Mail:        off    10: Charging:    off    11: Shift Lock:  off
    12: Group 2:     off    13: Mouse Keys:  off
  auto repeat delay:  500    repeat rate:  20
  auto repeating keys:  00ffffffdffffbbf
                        fadfffefffedffff
                        9fffffffffffffff
                        fff7ffffffffffff
  bell percent:  50    bell pitch:  400    bell duration:  100
Pointer Control:
  acceleration:  2/1    threshold:  4
Screen Saver:
  prefer blanking:  no    allow exposures:  no
  timeout:  0    cycle:  300
Colors:
  default colormap:  0x20    BlackPixel:  0x0    WhitePixel:  0xffffff
Font Path:
  /usr/share/fonts/X11/misc,/usr/share/fonts/X11/100dpi/:unscaled,/usr/share/fonts/X11/75dpi/:unscaled,/usr/share/fonts/X11/Type1,/usr/share/fonts/X11/100dpi,/usr/share/fonts/X11/75dpi,built-ins
DPMS (Energy Star):
  Standby: 0    Suspend: 0    Off: 0
  DPMS is Disabled

これだけだと再起動すると元に戻ってしまいますから、XDG autostartで毎回起動時に勝手に設定する仕掛けにします。システム全体ならば/etc/xdg/autostart/に、ユーザーごとに設定したいなら.config/autostart/に設定ファイルを作成します。ファイル名は何でも良いですが、今回はxset.desktopという名前にしました。

DPMSを起動時に設定する、xset.desktop
[Desktop Entry]
Name=xset
Comment=Disable DPM
Type=Application
Exec=/usr/bin/xset dpms 0 0 0
X-GNOME-Autostart-Phase=Initialization

ファイルを作成したら再起動して、DPMSが望み通りの設定に変わるか確かめます。

Xfce4の設定パネルからだと[アプリケーション] - [設定] - [セッションと起動](xfce4-session-settings)からも作成&設定できるはずです。たぶん。

編集者:すずき(2024/03/19 11:47)

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



2024年3月19日

モジュラージャックの規格

古くは電話線で、今だとEthernetで良く見かけるモジュラージャックというコネクタとレセプタクルがあります。モジュラージャックの種別はRJなんとか(RJ11など)という名前で呼ばれます。数字が違うと何か違うのは知っていましたが、今まで気にしていませんでした。

最近、趣味で早打ちターゲットを作っていて電子回路&基板を書いているんですが、部品の1つにRJ14(6極4芯)を使っていて、そのときRJ11〜18までRJなんとかシリーズがたくさんあることを知りました。電子回路作成ツールのKiCadの部品リストによれば、下記の種類があるそうです。

  • RJ11: 6P2C(6極2線)
  • RJ12: 6P6C(6極6線)
  • RJ13, RJ14: 6P4C(6極4線)

どの規格で定められているのか?RJなんとかとは何か?RJ13とRJ14は何が違う?と気になったので規格に当たってみました。

1976年の規格、RJなんとか=USOCのこと

最初のどの規格で定められているのか?ですが、RJなんとかは41 FR 28699, July 12, 1976(PDFへのリンク)にて定義されています。古そうだなとは思いましたが、まさか50年前の規格だったとは……。

FR(Federal Register)は連邦官報のことです。FRはPDF形式で配布されていますが、PDF形式と言いつつ中身はスキャン画像の羅列でした。古い文書だと仕方ないですね。ところがOCRを掛けてくれているらしく文字列検索ができます。大変ありがたい。アメリカ政府ありがとう。

次にRJなんとかとは何か?ですが、この記号はUniversal Service Order Code(USOC)です。§68.502の説明を見ると、

§68.502のUSOCの説明
These USOCs are generic telephone company service ordering codes. If a telephone 
subscriber wishes to have the telephone company install a standard jack other 
than the one depicted in § 68.502(a)(1) below, he shall specify the appropriate 
USOC when requesting the installations.

(適当訳)
これらUSOCは一般的な電話会社のサービス注文コードです。電話加入者が電話会社に対し、下記の§68.502(a)(1)に
記載されているジャック以外の標準ジャックの設置を希望する場合は、設置を要求するときに適切なUSOCを指定するものとします。

とあります。§68.502(a)(1)というのはRJ11のことを指しています。RJなんとかは電話会社に設置を頼むときの注文番号だったんですね。へー……。

RJ14は書いてあるがRJ13は見当たらない

次はRJ13とRJ14の違いを調べます。FRからRJ14Cの規格を見つけました、こんな定義です。手書きの図が良い味出してますね。


RJ14の定義

しかしRJ13は載っていませんでした。後で追加された規格なのか?残念ながらRJ13とRJ14の違いはわからないままです……。

Code of Federal Regulationsのほうが見やすいかも

黄ばんだ画像のFR 28699, July 12, 1976より、CFR(Code of Federal Regulations)のTitle 47 Vol.3 1996年(PDFへのリンク)の方が見やすいかもしれません。

日本語だとFR(Federal Register)は連邦官報、CFR(Code of Federal Regulations)は連邦規則集という名前だそうで、CFRはアメリカ政府が発行している規則集です。法律に準ずるものらしいですが、法律の専門家ではないので詳しいことはわかりません。

Title 47はTelecommunicationの話題で、Vol.1からVol.5まであります。Vol.3の一部しか見てないですけど……。

編集者:すずき(2024/03/20 02:52)

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



2024年3月24日

PCBを設計して注文

目次: Arduino

シューティングの練習でいつもお世話になっているTARGET-1秋葉原店に、6つの的を撃つシューティングゲームが設置されています(TSS?だったかな、名前は忘れました)。10年くらい頑張って稼働してくれたそうですが、製造元が既になくて壊れたら修理ができないんですと困っていました。

シューティングゲームのボードとターゲットの回路を見た感じ、素人の電子工作でもなんとかなりそうな作りだったので、代わりとなるおもちゃを作ることにしました。最初は簡単かなと思っていましたが、意外と時間を食ってしまって結局2か月くらい電子工作をしてました。

今日は電子工作の集大成となるPCBの発注です。発注先はJLCPCBです。ボードだけなら5枚でたったの$3、恐ろしい安さです。今回は部品も実装してもらうので合計$67(円安のせいで1万円近い)ですが、それでも安いです。便利な時代になったなあ。

KiCadからJLCPCBに設計図を出す方法

KiCadのプラグインFabrication Toolkitをインストールします。


JLCPCB Fabrication Toolkit

PCBエディターのツールバーの右端にアイコンが増えるはずです。


JLCPCB Fabrication Toolkitのボタン

ツールバーのボタンを押すとダイアログウインドウが出るのでGenerateボタンを押します。


JLCPCB Fabrication Toolkitのダイアログ

KiCadのプロジェクトがあるディレクトリの下にproductionディレクトリが生成されるはずです。productionディレクトリの下にある*.zipをJLCPCBのWebサイトの見積もりウインドウにドラッグ&ドロップします。


JLCPCBのウェブサイトのZipファイルをドロップする場所

見積もりページが表示されます(ボードの外観も表示されます)ので、ボードを製造する際のパラメータを選びます。右側には見積もりが表示されます。JLCPCBのシステムは非常に使いやすいですね。

編集者:すずき(2024/04/12 11:00)

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



2024年3月25日

Might and Magic Book One TASのその後

目次: Might and Magicファミコン版

以前(2023年9月3日の日記参照)にMight and Magic Book One TAS US版の更新版(7m 19s)のTASをTASVideosに投稿して、Acceptされました。その時に「2023年に遊んでみる人はいても、TASに挑む人はまずいないと思うので、20年くらいは記録をキープできるんじゃないですか。はっはっは。」なんてことを書きましたが、1か月くらいでTaoTaoさんが大幅に更新(JP版5m 28s、US版5m 00s)してくれました。

大幅更新ポイントの紹介

時間が掛かるはずのJP版と、US版がほぼ同じクリアタイムになっているのが大きな特徴です。クリアタイムの大幅短縮にはMight and Magic Book Oneのクソデカバグ「イドの迷宮はクリア不要」が大きく貢献しています。

アストラル世界の最後にイドの迷宮をクリアしたかどうか判定する床(X:7, Y:8)があり、クリアしていれば通過でき、クリアしてなければソーピガルの町に戻される仕掛けです。ところが床のイベント設定がバグっていて南向き以外で突入すると発動しません。つまり北向きのまま後ろ向きに歩けば素通りしてしまいます。とんでもないバグですね。

詳細は発見者のTaoTaoさんのサイト(マイトアンドマジック(FC)攻略/解析 - マップ - アストラル世界)を見てほしいです。

その他のテクニック

他にもいろいろと工夫されていて非常に短時間でのクリアとなっています。わかる範囲で紹介したいと思います。

扉の突破(JP版、盗賊への転職を不要にする)
JP版は盗賊がソーピガルの宿屋に居ない&Lv.1の場合は盗賊以外は扉の鍵の開錠に成功しないため、誰か1人を盗賊に転職させなければなりませんでした。しかしわざと扉の罠に掛かってダメージ0の判定を引き扉の鍵を突破すると非常に早く突破できます。言うだけなら簡単なんですけど、試行錯誤だけでやろうとすると全然引けません。
そらとぶじゅうたん(JP版、魔法使いなしで「ひこう」を使う)
JP版はキーカードを手に入れる(オーラのクエストをクリアする必要がある)ため、いくつかマップをめぐる必要があり「ひこう」の魔法が欲しいところです。これを魔法使い+魔法の泉ではなく、ポートスミスの「ひふきあり」から「そらとぶじゅうたん(使うと「ひこう」の効果)」をドロップさせタイム短縮しています。Lv.1で「ひふきあり」をワンパンKOできるんですね。知りませんでした。
エンカウンター予約
モンスターとのエンカウンターがイベント発生後にも発生するという仕様を利用して移動回数を減らす工夫です。例えば、移動→イベント→エンカウンター、という順序で発生します。動画だと火山の神と話すときがわかりやすいですね。
降参ワープ
モンスターとの戦闘を回避する方法には「逃げる」と「降参」があります。逃げる、もしくは、降参時に一定条件を満たすとマップ依存の固定座標にワープします。なぜかいくつかのマップでは逃げた後の座標と、降参した後のワープ座標が異なり、近い方にワープすればタイム短縮できます。これはバグじゃなくて仕様だと思いますけど、降参だけ特別扱いする意味はさっぱりわかりません。

これらはいずれもTaoTaoさんの詳細に渡るプログラムや乱数解析の賜物です。いやーすごい。

編集者:すずき(2024/03/26 03:20)

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



こんてんつ

open/close wiki
open/close Linux JM
open/close Java API

過去の日記

open/close 2002年
open/close 2003年
open/close 2004年
open/close 2005年
open/close 2006年
open/close 2007年
open/close 2008年
open/close 2009年
open/close 2010年
open/close 2011年
open/close 2012年
open/close 2013年
open/close 2014年
open/close 2015年
open/close 2016年
open/close 2017年
open/close 2018年
open/close 2019年
open/close 2020年
open/close 2021年
open/close 2022年
open/close 2023年
open/close 2024年
open/close 過去日記について

その他の情報

open/close アクセス統計
open/close サーバ一覧
open/close サイトの情報