2026年1月28日水曜日

小ネタ






 欧州のDMGって大きなイベントがあるとドローン映像を撮ってるけど、これってDMGの社員がやってるんだろうか? それとも外部の会社に発注してるんだろうか?

 欧州の映像だからか、25fpsでちょっとカクカクな感じが残念。せっかくドローンで取るなら50pとか60pで見たほうが綺麗だと思うのだが。



 京セラの自販機


 工場とかで必要な小さな消耗品の管理を行うためのソリューションらしい。

 日本だとミスミの自動販売機みたいなものがあるけど、京セラの自販機はあくまでも在庫管理や商品の提供を目的としているものであって、商品の補充や発注は顧客側(工場側)が行うのかな? あるいはそのあたりもなにかソリューションがあるのかもしれないけど。



 ロシア政府、“ロシア版『コール オブ デューティ』”の開発に「数百億円規模」の援助表明。「『CoD』はロシアを敵にしてばかりだ」として自前で作る - AUTOMATON

 プロパガンダ用に欧米で低価格でリリースして、陣営入れ替えModが作られて、セキュリティの欠陥で国家の尊厳に重大な損害を与えた、みたいな理由で開発会社に制裁金を課して、援助資金を回収、みたいな可能性。

 どんな内容のゲームを作るにしろ、「そっちが作るならこっちも作るよ」の口実になるだけな気がするけどな。でもCoDやBFみたいな巨大なフランチャイズがロシア政府や正規軍を敵にする作品を作れるとも思えないし、かといって完全新作で作るにもリスクがでかいし。政府がガッツリ資金提供するロシア版CoDは作られども、欧米側からそれに対抗できる作品が出るビジョンは見えん。ウクライナ政府が、という可能性もあるけど、それはそれでまたロシアが反発するだろうしなぁ。



 某レースゲーで建設できるらしい大型パラボラアンテナ、景観は野辺山っぽいけど、副鏡支持構造はあんまり日本の大型アンテナっぽくはないな。前作メキシコマップに置かれていたLMTモチーフの望遠鏡のアセットをそのまま使ったんだろうか?

 実物のLMTの副鏡支持構造はシンプルな棒状のフレームを斜めにクロスさせている。対してゲーム中のLMTはシンプルな棒状のフレームを垂直・水平にクロスさせている。大きさはだいぶ違うけど、三菱電機が作ったアタカマコンパクトアレイ(7m)は副鏡支持構造がシンプルな棒状を水平垂直に近い角度でクロスさせているから、FH5のLMTとは相似な感じ。

 結果として、次作FH6の巨大パラボラアンテナも、三菱電機のACA7mに近い形になっている。

 とはいえ、FH6の巨大アンテナはおそらく富士山とアルペンルートの中間付近に所在する野辺山がモチーフだろうし、いくらメーカーが同じとはいえ、ACA風ではなく45m風にしておいてくれると嬉しかったな。


 そういえば某VTuberが野辺山と関わってるな…… 「野辺山45mが出てくるらしいよ」って勧誘しよう(やめなさい

 45mはたぶん某アニメでも出てるだろうし、下手なモデルを使うと日本国内ではウケが悪そうだが。まあ、おそらく顧客層が違うから問題ないか。



https://www.hrr.mlit.go.jp/yukimirai-toyama/ouboronnbunn/30_tateyamayuuryo.pdf

 立山黒部アルペンルートの除雪作業に関して。H10年(1998年)以降はGPSも併用。それまでは、降雪前に路肩へ立てたポールを目印に作業していた。GPSを使う場合は除雪領域のセンターをGPS付きのブルドーザーでパイロットルートを作成し、それを掘り下げる作業要領。

 1998年のGPSはRTKを使っているかどうか悩ましいところだな。


https://www.giho.mitsubishielectric.co.jp/giho/pdf/2007/0701005.pdf

 三菱電機の高精度GPS測位サービス(PAS)を納入、2006年3月開通時の除雪に使用された。山間部なので補正データは衛星携帯電話経由で配布。

 ということは、その前の数年は通常のGPSを使っていたんだろうか?


https://jsurvey.jp/pcrg/kyougikai.files/m9.pdf

https://jsurvey.jp/pcrg/kyougikai.files/j23.pdf

 アルペンルート除雪に使った三菱電機のGPS受信機の説明。ネットワーク型RTK-GPSだそう。水平方向数cm、垂直方向10cm程度の精度。通常のRTK-GPSに比べて固定点を数kmおきに設置する必要がない、とアピールしているから、それまでは固定点を使ったRTK-GPSを使っていたのかな? そりゃまあ、S/A解除前のGPSで道路の除雪作業は無理か……


 準天頂衛星みたいに高仰角の衛星が増えて20mの壁の間でもRTKが使えるようになると、CADデータを入れたICT建機で綺麗に壁を削れるようになったりするんだろうか?



 会社の略称でCompanyの意味で後ろにCOとついてるところ、WebサイトのURLがhogeco.co.jpとかでなんか冗長な感じ。hoge.co.jpじゃだめなんか?

 co.jpならたいして変な場所にも飛ばんやろ、と思ってhoge.co.jpにアクセスしてみたらちゃんとタイムアウトするから、そのドメインは空いているはず。そっちを使えばいいのに。あるいはリダイレクトさせるとかでもいいけど。



 ユーザーアカウントの作成とかでパスワードを入力する画面、ランダムに配置したキーボードとか、タップするたびに配置が変わるキーボードとか、そういうのがあると嬉しい気がする。並んだキーをタップするとか、同じキーをタップするだけでランダムな文字列を作れる。入力した文字列を別途覚えておく不便さはあるけど、自分でランダムな文字列を作る場合は、ランダムなキーをタップして、それを覚えて、みたいな手間がかかるから、片側だけでも省略できるのは便利そう。ブラウザのパスワード生成機能を使えば両方とも省略できるから、それに対応していない場所でパスワードを考えるのが面倒、という話。



 ボルトを上から入れるか下から入れるか、という話の解説記事で、「ボルトを下から挿入した場合、下部に構造物があれば脱落することを防げます」とか書いてあって(完全には脱落せず、少なくとも多少のシアは耐えられる、みたいな表現)、いやいや、下に構造物がある場所でどうやって下からボルトを入れるんだよ、というツッコミ。

 ナットが下にあると重力で緩むから、みたいなことも書いてあるけど、なら重いボルトが下にあったほうが重力が効きそうな気がするが。上からボルトを挿入していれば完全にナットが脱落してもわずかなせん断力には耐えられるから、ナットの緩み(張力ゼロ)を許容するなら上から入れるべきじゃねって気がする。そもそも軸力ゼロを許容できるならボルト・ナットよりもっといい方法があるだろ、という話だけど。

 下からボルトを入れて、ボルト・ナット・部材に合いマークを書いておけば、ナットとボルトがズレていたときに一発で分る、というのに関しては、上から見た場合にしか適用されないから、例えばインフラ設備みたいに下から確認することがある場所ではむしろ上から入れるべき理由になりそう。

 こういう記事を書いてる人って、自分の記事が矛盾してるって気が付かないんだろうか? 気が付かないんだろうなぁ(身に覚え)。


 ボルトを下から入れなければならない理由って、ネットの記事で見る範囲だと腑に落ちる説明はあんまり無い気がする。実際に正しいことが書かれているのかもしれないけど、記事を見ただけではそれが判断できない(実際に試験してみないと判断できない)みたいな説明も含めて。

 ちゃんと根拠になりそうな理由でいうと、ワッシャ等を入れるときに、ボルトを上から入れるとワッシャ等を脱落させる恐れがあるけど、ボルトを下から入れておけば、ボルトが脱落しない限りはワッシャ等も脱落しない、くらいかな。

 建築物で高力ボルトを使う場合は重い工具を使いやすくするためにボルトを下から入れたほうがいいよ、ただし工具が干渉する場合は上から入れてね、とか、FAだと下からボルトを入れたら脱落したときにワークを破損させたり、食品ラインだと異物混入は対応コストが大きいからボルトの下からの挿入は絶対にNG(ナットも使用せず構造部材にボルトだけで締結)、とか、結局、TPOに合わせて選んでね、みたいな話になりそう。まあ、そりゃそうよな。あらゆるシチュエーションに完璧に答えられる銀の弾丸、なんてあるわけないし。



 某ロケットのアレ、1号機のときに第1/2段間分離で、衝撃が円錐で収束して第2段エンジンに過大な衝撃が、みたいな現象があったけど、このあいだのやつも円錐の構造破壊らしいけど、なんか現象が似てるような気がしないでもない。まあ、ちゃんと事前に解析してあるだろうから、正常であれば問題ないんだろうけども……



 Google Pixelのカメラ、設定で音量ボタンに割り当てる機能を設定できるんだな。デフォルトはシャッター。他にズーム(音量↓でワイド、音量↑でズーム)や音量(音量ボタンのデフォルト機能?)、OFF(音量操作も無効?)、が設定できる(もしかしたら音量は録音音量、OFFは出力音量?)。

 音量ボタンでズームを切り替えられるのは一見便利そうだけど、じゃあどうやってシャッターを切るんだ、という問題。せめてファンクションキーが1個あれば、音量ボタンと組み合わせて色々使えて便利だろうけどな。物理キーが増えると故障場所(壊れやすいメカ、水が入りやすい開口部)が増えるから作りたくないんだろうけど。でもAppleはiPhoneにアクションボタンを載せてるからな。やはりあると便利なんだろうし、多少のコストは気にせず実装できるAppleと、できるだけ価格競争力の欲しいAndroidの差もあるだろうし。



 RasPi PicoのMicroPhytonってもっと使いやすそうなものだと思ってたけど、意外と使い勝手悪そう。

 公式のインタプリタはUSB CDCとして認識されて、対話モードで動作する。なので、ターミナルで手書きする範囲においては、人間の認識能力やタイプ速度を超える動作はできない。あくまでもただのCDCなので、PC側でCDCにコマンドを送ったりするプログラムを書けば、オンボードフラッシュに入らないような巨大なスクリプトも処理できるけど、まあ、そんな事するやつはおらんやろ……

 BOOTSELを押しながら起動してMSCにmain.pyを入れればそれが走るらしいんだけど、なぜかウチのPicoは走らない。なんか、ウチのPico、調子悪くね??


 あと、MicroPythonはドキュメントが少ない気がする。C SDKは巨大なHTMLにメソッドの一覧と説明が書いてあるけど、Python版は見当たらない。

 結局BOOTSELでMSCとして認識させてスクリプトをコピーしなきゃいけないなら、BOOTSELでMSCとして認識させてuf2をコピーするのも手間としては変わらないし、スクリプトだとインタプリタで走らせてみないと結果がわからないけど、C/C++なら少なくともコンパイラが知る限りのエラーや警告は表示してくれる安心感がある。Pythonも多少の文法エラーくらいならIDEが警告は出してくれるだろうけど。


 電子工作をやったことがない人に対して、MicroPhytonインタプリタを焼いたRasPiPicoを配布して、USBで接続してターミナルから対話型でGPIOのインスタンスを確保してLEDをチカチカさせて、みたいなことは楽にできるだろうけど、その後ってどうするんだろうか。最初から専用のIEDを使うのかな。



 RP2040が2個乗ったボードってないんだろうか。STM32 Nucleoみたいに、1個はSWDブリッジ、もう1個がターゲット。コスト的にちょっと厳しそうだけど、買ってすぐUSBで接続してフル機能のデバッグができるのは便利そうな気がするが。



 イーサネットフレーム、ヘッダにデータ長が書かれていないのが結構謎い気がする。乗っているプロトコル(IPv4とか)を知っているなら内側のプロトコルを見てイーサフレームの全長を把握できるけど、そういう仕組ではないはずだし。

 ja.wikipediaの書き方を見ると、フレームチェックシーケンス(FCS)を見れば末端を把握できるから、可変長で長さが不明でもここで終了させればいいとわかる、みたいなことが書いてある。活線挿抜を考えると、自分がネットワークを最初に見たときに通信中だった場合に、ヘッダを見ていなくても末端を知る必要があるとか、あるいはパケット(イーサフレーム)が衝突してビット列の同期が取れなくなったときに末端を探す必要があるから、みたいなことなんだろうか。

 とはいえ、FCSってただの4バイトデータだし、ここに入っているのはCRC32だから、これを見てパケットの末尾を知ることは不可能なはず。例えばヘッダを見逃した場合やメッセージが衝突した場合、あるいはノイズでビットが化けた場合に、CRC32が一致することで末尾を判断することはできない。

 とすると、イーサネットフレームの末尾を判断するのは、イーサネットフレーム自体ではなく、その下のプロトコルで判断しなきゃいけない、ということになるはず。

 100BASE-TXならTRを受信したらそこで終了、みたいなわかりやすい基準があるけど、10BASE-Tにはそういう基準は無いはず。強いて言えばマンチェスタ符号として正しくないシンボルが出る、くらい。まあ、じゃあそれで判断すればいいだろ、と言われればそこまでなんだけど。


 wikipediaの記事だとFCSの後のEOFで、10BASEはキャリア消失で終了を検知する、みたいな事が書いてある。キャリア消失で終了を判定して、それまでに受信したビット列をFCSのCRCで確認して、OKなら上に投げて、NGなら握りつぶして、みたいな感じなのかな。

 正しくないマンチェスタ符号を検出して通信を終了、だと、通信途中でLANケーブルが抜かれたときに困るから、やはりキャリア消失で検出するのが安心なのかな? 少なくともPHY層では。MIIで上げる信号はマンチェスタ符号で切るとしても。

 とすると、FCSの「ペイロード長がわからなくてもFCSでフレームの末尾がわかる」という説明がニュアンス的に正しくない、ということなんだろうか。



 イーサネットってSPIみたいに送受信でコヒーレントである必要はないわけだから、TXとRXで変調方式を分けるみたいな使い方って無いんだろうか。

 例えばイーサネット接続のセキュリティカメラで、普段は動きが少ないけど場合によっては10Mbpsを大きく超えるから100BASE-TXで送るが、コマンドはほとんど無いから125Mbaudを常に出すのは電気の無駄なので10BASE-Tで接続する、みたいな用途。

 オートネゴシエーションで特定の通信方式だけ有効な情報を出して、自分がそれとは違う方式で出す場合、自分は10BASE-Tで送って相手はそれ以外の方式(100BASE-TX)で送らせる、みたいなことはできるかもしれないけど、自分が100BASE-TXを出した場合、相手も100BASE-TXで送ってくるはず。自分は100で出すが相手は10で出してもらう、みたいなことはできないはず。


 適当なEtherTypeを定義して、最初に10BASE-Tで接続して、そのパケットで32bit32個(128byte)とかのフラグテーブルを投げて、そのマトリクスから双方が対応できる最も高速な転送速度を決定して、リンクアップしたあとも定期的に投げ合って、高レートで送りたい時は100BASE-TXや1000BASE-Tに切り替えて、必要なくなったらまたビットレートを下げて、みたいなことはできそうだけどな。

 イーサネットフレームをPHYで読むのはWoLみたいに可能なわけだし、それと同じような感じで。MACで転送されると困る(ハブを超えて別の機器に影響が出る)から、それを防ぐためにFCS(CRC32)に固定値をxorしてMAC層から見ると常に壊れたパケットを飛ばす、みたいな対応は必要だけど。

 今のところ、電線を使うイーサネットの規格は20ちょっとあるらしいから、32bitテーブルでカバーできるはず。これ以上の高速化は電線ではやらないだろうから、車載とかFAとか特定用途を除けば増えないはずだし、そういう部分では特定のプロトコルしか使わないだろうからオートネゴシエーション的な機能では無視できるはずだし。FCSで壊すなら専用のEtherTypeを割り当てる必要はないけど、専用のEtherTypeが割り当てられていればデコーダが簡単になる利点がある。

 受信側は自動判別するとして、相手に送信してもらう方式だけ指定するなら、32bitとか64bitのビットフィールドを投げるだけでもいいけど、どうせパケットを切り詰めたってイーサフレームの最小長があるからパケットはあまり短くならないのよな。ロジックが楽になる利点はあるけど(PHYでキャッシュするメモリも少なくて済むし)。

 これくらいの仕様は過去に提案されていても良さそうな気がするけど、そういう規格が存在しないということは、需要がなかったんだろうな。まあ、昔はIoTみたいに非対称かつ省電力化が重要な用途もあまりなかっただろうしな。かといって今の時代に100BASE-TXの数百mW程度を削減したいみたいな理由で規格を新しく作って普及させられるとも思えないし。


 そもそも建前は置いておいて何をやるためにそういう機能が欲しいのかというと、変調するのは楽だけど復調するのは大変、100BASE-TXは足の早いマイコンならソフト実装で出せそうだけど、受信するのは10BASE-Tのほうが楽だよね、ちょっと多めの測定データを流すときに100BASE-TXで出したり、各種設定を10BASE-Tで受信できたら便利だよね、みたいな方向性。

 外付けMAC/Phyでなく、パルストランスだけ外付けで使えたら面白そうじゃね、と。まあ、実際にやろうとすると変調でリソースの大半を食われたりして実用にはならないだろうけど。そもそも125MBdの信号をプログラムが走るデバイスから真面目に出そうとしたら少なくとも250MHzで動くロジックが必要だしな。スクランブルも考えればさらにその数倍のクロックが必要になるし。

 プログラムが走らないプログラマブルなデバイスを想定すると、例えばShrike-liteに乗っているForgeFPGAはGPIO2本をパラでドライブすると、min120MHzが出せるそうだ。ここまで早いGPIOが使えるなら、100BASE-TXの波形は出せてもいい気がする。FPGAならLFSRだって組めるだろうし…… でもまあ、わざわざ4B5B/MLT-3変調のためだけにForgeFPGAを乗せるかというと。。。いや、そのためのグルーロジックだろ、という話ではあるんだけど。でも25Mbps程度でいいならW5500でいいし、少し上のチップ(例えばW6300、QSPIモード)なら90Mbps程度のスループットが出るそうだから、わざわざ汎用ロジックを載せて100BASE-TXに対応するくらいなら、専用のブリッジを積んだほうが楽だろうな。さすがにForgeFPGAで100BASE-TXの受信は難しいだろうし(3レベルアナログ信号のためにアナログ段を置かなきゃいけないとか、いろいろ)。



 ブレッドボードにジャンパワイヤで接続したW5500とFT232Hがいい加減じゃまになってきたので、ユニ基板に乗せてみた。


 ユニ基板使うの何年ぶりだ…… 計画性と躊躇のなさが明らか。プロに見られたらバチボコに殴られるけど、趣味の遊びだから許してッ!!

 とりあえず、DHCPでアドレスを取ることはできたので、たぶん動いているはず。

 オシロとかロジアナでプロービングしようとすると困るけど、必要になったときに考える。


 ストリナのFT232H基板はVer.2だと3.3V出力があるけど、手持ちはVer.1のVBUS出力オンリーなヤツなので、3.3VのLDOを載せている。あとは、FT232とW5500の出力が衝突すると嫌なので、100Ωを挟んでいる。せっかくなので、INTにLEDを配置している。とはいえ、W5500のINTを出しっぱなしにすることも無いけどな。あとはCSにもLEDをつけていれば、通信時に見えるので見た目が面白くはあるけど、面倒なので省略。


 FT232Hの固定穴がインチじゃなくてミリなのが絶妙な使いづらさ。最初はユニ基板にミリで穴を開けるジグを作ろうかと思ったけど、でもどうせ11mmのスペーサーが必要なので、基板側のネジ穴と合わせるブラケットを作ってみた。



 大昔に買ったCat.5eケーブル

 マーキングにELECOM Laneedと書いてあるのでエレコム製なんだろう。

 ツイストの様子がよく見える透明被覆のケーブルちょっと欲しいけど、探してもいまいち見当たらない。



 GitHub - steve-m/Pico-100BASE-TX: Bit-banged 100 MBit/s Fast Ethernet transmitter and UDP framer for Raspberry Pi RP2040/RP2350

 RasPiPico2で100BASE-TX送信。ADCでアナログ波形(AF)をサンプリングして、それをWFM変調して、そのIFデータをUDPでPCに転送する、というような処理をやっているらしい。スクランブルを正しく実装しようとすると計算コストが高すぎるはずだから、おそらくアイドル信号は出していないはず(コード未確認)。


 GitHub - kingyoPiyo/Pico-10BASE-T: 10BASE-T from Raspberry Pi Pico

 RasPiPicoで10BASE-T送信。受信は将来的に対応予定とのことだが。



 久しぶりにSTM32を使おうと思って、手始めにSTM32CubeMXをダウンロードしようと思ってゲストでダウンロードを試したのだが、一向にダウンロードができない。

 1つ目は、Gmailのエイリアスがだめだったっぽい。延々「メールアドレスはまだ認証されていません」みたいなエラーが出続ける。エイリアスなしのメールアドレスを入れてみるとそのエラーはでなくなった。が、今度は401エラーが出続けるようになった。なんでだよ。

 観念してSTのアカウントを作成。入力項目多すぎじゃねー?

 RP2040+VSCode(+拡張機能)みたいに比較的容易に開発環境を構築できる現在、STM32はあまり魅力的ではないかも。と思いつつ、機能面で言えばやはりSTM32のほうが強い気がする。必要に応じて様々なチップから選択できるという利点もあるし(RPは現状C-M0+とC-M33の2種類しかない)。

 気軽に電子工作を始めたいならRP、将来性を考えるならSTM32、とか? ただ、STM32は茨の道だぞぉ。あと、Arduinoプラットフォームで対応しているせいで玉石混交な情報がな。Arduino界隈は多くの初心者が自分のアウトプット用に色々な記事を書いているので、記事の質を判断できないうちにそういう記事を読むとちょっと大変なことになる。



 小さめのヤツを使いたかったので、STBee mini

 今回はUSB DFUファームを消して、SWDで書き込み(ST-Link v2は昔のNucleoのカケラ)。


 SPIペリフェラルでW5500を接続して、動作テスト。とりあえずDHCPでIPアドレスを取得。たぶん動いてる。

 今回はSPI2を使ったので、クロックは18MHz。コアクロックが72MHzだから、32クロックごとに2バイトをハンドリングする必要がある。キッチリ実装すれば足りそうな気もするけど、C++だとクロックに隙間が空いていて、処理が間に合わない。DMAなら隙間なく転送できる。DMAはDMAでいろいろ設定が必要だから2,3バイト程度の転送だと割に合わないけど。

 コードはC++で書いているので、色々と面倒。やはりC#は便利。特に、PCで走るC#コードを書いてUdpClientとかでロジックをテストして、それで動いたコードをほとんどコピペしてFT232H/MPSSEでW5500を叩いて、みたいなことをやっていると。



 Feature request: Programmable logic - STMicroelectronics Community

 STM32にグルーロジック用の小さいロジックセルがあったら便利だよねー、みたいな、白熱()した議論。


 RP2040に乗っているPIOって、実際に触ったことは無いしドキュメントもちゃんと読んでないけど、かなり「自由度の低いソフトウェア的な」機能な気がする(そもそも10命令に満たないアセンブリで書く時点で自由度が低いソフトウェア的なのは当たり前とはいえ)。FIFOで受け取ったビットストリームをSPIやUART、I2Cみたいなプロトコルで吐き出すことはできるけど、じゃあそれにm系列のPRBSをXORできますか?というと、おそらく不可能。現実的にPRBSが必要な状況なんて無いだろ、といえばそれまでだけど、あくまでもRPのPIOの柔軟性が低いということを言いたいのであって。

 極端な話、STM32と小規模なFPGAを貼り合わせて、STM32のIOをFPGAに取り込んだうえで自由にルーティングしたり簡単なビット演算を行って、FPGAのIOとして外に出す、みたいな感じの機能があって、FPGAを未初期化で使えばただのSTM32として、STM32から適当なビットストリームを吐いてFPGAをコンフィグすれば(マイコンに比べれば)複雑なロジックを処理できて、みたいな機能が欲しいわけだが。それこそShrikeみたいな感じになるんだろうけども。

 昔はWiznet W5200とSTM32F103CBを貼り合わせてパッケージングした製品とかも売ってたみたいだし、同じように小さいFPGA(e.g. ForgeFPGA)を貼り合わせてパッケージングした製品とかあっても良さそうな気がするけど、でもそんなもん作ってもコストが合わないから、どうしても必要なら各自PCBに載せろ、って話なんだろうなぁ。

 フォーラムの中でも書いてあるけど、そういう製品を作ったところでちょうどいい塩梅の製品にはならない(機能が過小or過大になる)だろうし。



 Wiresharkでデータ長0のDiscardパケットを受け取ると長さ0のUDPパケットとして表示されるの、期待した動作とは違うけど、これってどういう挙動なんだろうか。Discardってべつに1バイト以上無いとだめ、みたいな理由はないはずだし、0バイトのパケットでもDiscardとして表示されていいはずなんだけど。


https://www.ietf.org/rfc/rfc863.txt

 DISCARDプロトコルのRFC。めっちゃ短い。

「捨てるよ」としか書かれていないから、0バイトのパケットがDISCARDとして認識されないのはWireshark側のバグ的なものだと思うのだが。


2026年1月21日水曜日

小ネタ


 何日か前に届いた、ほぼ確実に迷惑メールであろう、プロバイダからの案内のメール、送信者がプロバイダの一般的なメール(実際のログイン通知とか)と同じなのは当然として、Gmailで見ると送信元や署名元も実際のメールと同じで、かつGmailが重要と判断したマークを付けている。ただし、通常のメールは送信先メールアドレスが自分のメールアドレスだが、このメールは正しくないアドレスになっている。それと、ログインして設定しろとURLが貼ってあるが、このURLはプロバイダのドメインではない(プロバイダから送られてくるメールはもちろんプロバイダのドメインのURLが貼られている)。

 送信元と署名元が実際のプロバイダと同じに見えるものが付属しているのも変だけど、それでころっと騙されるGoogleもGoogleよな。


 別の迷惑メール、普段迷惑メールなんて送信者名だけ見て関係のない会社(普段から迷惑メールで使われている社名)なら件名すら見ずに読み捨てるんだけど、たまたま目に止まった内容が面白かった。本文のフッターには社名や会社のWebサイトへのリンクが書いてあるんだけど、Example Companyという会社でURLはexample.comだそう。ちょっと面白い。

 迷惑メール用のサンプルデータをほとんど書き換えずにそのまま流用したのかな? メール本文の中に別のドメインのURLが書いてあるから、これが本体なんだろうけど。しかし、example companyとか書いてあるのも気にせず送るようなヤツが迷惑メール出してるのかぁ。そりゃまあ、一流企業の英語バリバリシゴデキ人間が業務or副業で出してるだけとも思わないけどさ。



「DXセミナーの案内がFAXで送られてきてガッカリ」みたいな話、むしろそれって正しいやり方なんじゃね?って気がするけどな。デジタルツールを使い込んでいる所にDXソリューションを売り込んだって意味ないだろうし、電話やFAXを現役で大規模に使っている組織こそDXするべきだろうし。適当なデータセットに乗ってるFAXの電話番号に一括して送信しているだけだろうし、大量の電話番号からその組織が十分にデジタルツールを使いこなしていて売り込む必要が無いと除外するのも面倒だろうし。



 主に人生の諸先輩方へ向けて作られているスマートフォン、UIが独特で使い方を聞かれても答えられないとか色々不満点はあるんだけど、タップ操作が感圧式になっているのはすごい羨ましい。

 PCのマウス操作みたいにクリック操作が明示的なHIDに慣れていると、普通のタッチ操作(含一般的なノートPCのトラックパッド)で「いや俺触ってねえんだけど!?」は結構フラストレーションになる。Mac系のトラックパッドはクリックが感圧なので、その誤入力が無い。スマホにもそういう機能が欲しい。

 一時期のiPhoneも感圧式のタッチパネルだったはずだけど、すぐに廃止された気がする。やはりタクタイルスイッチで計測できるトラックパッドと違って、スマホのタッチパネルで機械的なアナログ値を安定して取るのは難しいんだろうな。逆に言えば、意地でもその機能を削らない日本の端末メーカーの気力というか(今はレノボ傘下だから親企業は中国だけど)。キャリアやユーザーからの圧力もあるんだろうけど。



 文章を読みながら手持ち無沙汰でキートップを撫でながら思ったけど、FキーやJキーあたりに画像素子を埋め込んで、指紋認証やポインタ操作デバイスとして使うことってできないんだろうか。

 面積が小さいからポインタとしての操作範囲(ダイナミックレンジ)は狭いけど、ちょっとした文章の入力中に、数文字分離れた場所にカーソルを移動したい、というときに、右手を大きく動かして矢印キーを使うよりも、JキーやFキーを撫でてマウスカーソルを少し動かすくらいの操作ができたら便利そうだが。

 とはいえ、マウスカーソルの移動はできても、クリック操作をどこに割り当てるんだ問題が出てくるのだが。スペースバーの手前にボタンを追加する、あたりかなぁ。

 単にカーソルを動かしたい場合はViみたいな操作系は便利そう。今度はEscが遠いけど。



 ターボファンエンジンの発電能力増強のために高圧軸だけでなく低圧軸にも発電機を取り付ける、というやつ、実際のところどれくらい効果があるんだろう? 低圧軸は高圧軸で余ったエネルギーでブン回してるだけだから、高圧軸で発電しても、高/低圧軸の両方で発電しても、トータルで取り出せるエネルギーに差はない気がするんだけど。

 高圧軸の発電機が大きくなるとイナーシャも大きくなるから起動が大変……みたいな話は、そもそもその発電機に電力を突っ込んで回すんだから大して問題ないだろ、という気がするし。

 構造的に、高圧軸に大容量の発電機を取り付けるのが難しいから、比較的小型の発電機を2箇所に設置する、みたいな理由はありそうだけど。あとは、熱い場所に高効率な発電機を置くのは大変だから、メインは低圧軸で、でも起動用の電動機が必要だからついでに高圧部でも発電して、みたいなこともあるんだろうか。



 昆虫に過給器をつけたらどうなるんだろ、という空想。昆虫を巨大化させた設定がある創作物で、でも昆虫って巨大化すると呼吸できなくなりますよねー?みたいなツッコミに対して、サイバーパンク的な方向からのソリューション。エネルギーは外付けのLIBで、BLDCでブン回す方向で考えている。電池が切れたら(orリモートで停止させたりすれば)活動を止められるという利点もあるディストピア風味の味付け。



 気まぐれに読んでた中性子イメージングの資料で「核分裂で生じる高速中性子は使いづらいから水で冷やして使う」みたいなことが書いてあった。確かに水で減速する核分裂炉って、我々が日常的に「熱いものを水につけて冷やす」と全く同じ物理現象で高速中性子を冷やしてるんだよな。火で温めた石を水につけてお湯を作るのと同じ(マクロスケールでは核子が運動量を直接交換しているわけではないけど)。石がめちゃくちゃミクロになるし、トータルのエネルギーは非常に大きいので、日常のスケールとは全く違ってイメージが湧かないけど。でも水は沸くんだよね(ただし沸騰水炉に限る)。

 中性子イメージングの場合は水だけでなく液体水素を通して冷やしたりもするらしい。あまり冷やしすぎると波長が伸びて分解能が下がるんだろうけど、液体水素ならそこまで極端に冷えるわけでもなく、かといって早すぎもせず、値段も安いし、わりといい冷却剤なんだろうな。核分裂で生じた高速中性子や常温程度に近い熱中性子に対して、液体水素で冷やしたものは冷中性子というんだそうだ。熱中性子を通す場合、液体水素は厚さ3cm程度でいいらしい。極めて少量でも十分に冷却できるから、トリチウム化する量も少ないんだとか。たしかにあまり長く液体水素を通しているとそっちに吸収されてしまうのか。



http://www.spring8.or.jp/pdf/ja/SP8_news/no99_20/no99.pdf

 2020年。Spring-8でトリウム229の励起に必要なエネルギーを計測したい、みたいな話。

 トリウムの原子核は他の原子に比べて低いエネルギーで励起でき、原子核は電子雲よりも遥かに小さいし、電子雲がシールドの役目をしているので外部からの影響を受けづらいため、原子核を時計に使えば現在の原子時計よりもさらに精度の高いものが作れるはずだ、ということで、励起エネルギーの低いトリウム229で実験を行っているらしい。


https://www.jst.go.jp/kisoken/presto/evaluation/s-houkoku/sh-r03/JST_1112078_18070111_2021_Yamaguchi_PER.pdf

 トリウム229のトラップとかの話。

 冷却用のレーザとかで、結構大規模な装置が必要そうな感じだ。もっとも、応用の話で「「原子核時計」というテーブルトップサイズの装置による宇宙進化の解明という、新しい研究分野を創成する可能性も秘めている」と書いてあるから、実用化の暁には十分に小型化できると考えているんだろうけど。



***


 改めてRaspberry Pi Picoを触っている(比喩表現)。

 なぜか、Ras Pi PicoのRUN端子に触れる(物理)とリセットされる不思議な現象が起きている。内蔵プルアップ抵抗って100kΩ未満だろうし、そんなに簡単に動くものでもないと思うんだけど。それに、4.7kΩを追加で付けても、やはり指で触れると反応する。


 前に、BOOTSELを押してWDTを蹴ってUSB MSCで認識させるというやつ、あれ実は正常に動作していなかったらしい、という気がしてきた。

 定期的にキャッシュをオールクリアしたり、あるいはQSPI FlashからUIDを読むようなコードを書いてBOOTSELを押しても、正しく動作を続ける。そもそもQSPI Flashはデバイスが1個しか接続されていない場合はCSをGNDに落としてピンを1本省略するみたいな使い方ができるらしい? 軽くググっただけだとそういう使い方は見当たらなかったけど、SPIだとそういう動作ができるデバイスもあるし、QSPIでできても良さそう。ということで、そもそもRP2040のBOOTSEL(QSPI Flash nCS)を動作中にGNDに落としても、SSIの読み出しには影響はないようだ。

 BOOTSELでリセットしたい場合、自分でBOOTSELを読んでリセットするしかないらしい。その場合、BOOTSELをGPIOに変更する必要があるから、そのコードをRAMに置いたうえで、割り込みも停止して、とか、いろいろ手間がかかる。RP2040をリセットするのも、例えばCortex-M0+コアをリセットしても他のコアやペリフェラルは動作を続けるから、WDTを開始して待つ、みたいな方がいいらしい。QSPIがCSを使わないならGPIOに固定しても、キャッシュミスを含めて正常に動作するだろうけど、GPIOを読むときにBOOTSELの押下有無にかかわらずLOWでしか読めないし。


 RP2040のXIPはプログラム側からXIPに書き込みを行うとキャッシュライン(2040なら8byte単位)を無効化して次の読み出し時に強制的にFlashから取らせる機能があるらしいんだけど、軽く試した感じではうまく機能させられなかった(キャッシュラインを削除してBOOTSELをオシロで覗いても、VDDに張り付いていてQSPIで読みに行っている気配がない)。SDKラッパーのxip_cache_invalidate_rangeを使っても同様。


 結局、RasPiPicoを手軽に使いたいなら、2枚買ってJTAGアダプタとして使うのが一番確実っぽいなー。


 Ras Pi Picoはドキュメント(SDKが用意している関数やその機能)がHTML1ページで説明してあったりして情報を探すのが便利ではあるけど、いまいち釈然としない部分も多い。

 あと、当たり前だけど、STM32とはペリフェラル周りが全く違うので、自分がやりたいことをどうやったらできるのかを調べる必要もあるし。ある程度気合を入れて一気にいろいろ試していけば感覚も掴めるんだろうけど、そこまでのモチベも無いのでな…… STM32ならこの機能とこの機能を使えば楽に作れるんだけどなー、とか、いろいろ。


***


 PCでデータが通るところ、ぐぐると必ずオーディオ系のブログが出てくる。オーディオの人たち、どこにでもいるな。懇切丁寧に解説しているけど、でもその説明って……

 もちろん、データが通らない場所(e.g.純粋なパワーライン)も彼らの領分。


*


https://www.net.itc.nagoya-u.ac.jp/member/shimada/infoNW2025B/slide/lecture20250617slide_rev1.pdf

 イーサネットの特に物理に近い周りの話いろいろ。



https://www.fujitsu.com/downloads/JP/archive/imgjp/jmag/vol55-6/paper07.pdf

 2004年。1チップで10GbE12ポート240Gbpsのスイッチングハブ。25mの銅線をドライブできるIOを内蔵。


*


 DHCP、Wikipediaを見ながらざっくり実装してみた程度なのであまり詳しくは調べていないけど、最低限の機能だけならそれほど難しいものではない。300バイトくらいのUDPパケット(互換性目的で200バイトくらいゼロ埋め)を2往復+αで処理できる。NTPの数倍の手間、といった程度。10倍まではいかないかな。

 DHCPはMACアドレスと紐づけて処理される。ユニキャストで送ると送信したイーサネットフレームのMACアドレスに返答が帰るので、パケットでMACアドレスを偽装して実際には別のMACアドレスから送る場合は、ブロードキャストで送る必要がある。逆に言えば、実際にはネットワークに接続されていないデバイス(ネットワーク内に存在しないMACアドレス)に対してDHCPでIPアドレスを割り当てることもできる。

 攻撃らしい攻撃も思いつかないけど、攻撃者となる一つのデバイス(単一のMACアドレス)からDHCPサーバーにリクエストを投げれば、DHCPリソースを枯渇させるのは簡単にできそう。すでに接続されている端末に割り当てられたIPアドレスを横取りすることはできないけど、追加で接続される端末へIPアドレスが割り当てられるのを防ぐことはできそう。それで具体的になにか強烈に悪用できるかというと微妙だけど、迷惑ではある。

 DHCPサーバー側では、イーサフレームの送信者MACアドレスとDHCP DiscoverのMACアドレスが一致しないパケットは捨てる、みたいな方法で避けれるけど、少なくともうちのルーター内蔵のDHCPサーバーはそういう機能はないらしい。イーサフレームのMACアドレスまで偽装すればサーバから見れば偽造かどうか判断できないけど、そこまでされたらもうどうしようもないし。

 C#とかでMACアドレスを偽装してDHCPクライアントを作って遊ぶ程度なら、Discoverを送って、Offerを受け取って、Requestを投げて、Ackを受け取って、という手順でIPアドレスが得られる。W5500とかでDHCPクライアントを作る場合は、OfferとRequestの間に、割り当てられたIPアドレスに対してUDP SENDを挟むほうが良い。ARPが投げられるから、IPアドレスが存在していた場合はSEND_OKになるし、存在していない場合はTIMEOUTになる(不必要なパケットを投げるのでポート9とかあまり害がなさそうな場所に投げる)。

 DHCPでIPアドレスが割り当てられれば、パケットの中で指定するオプションでルータのIPアドレスやDNSサーバのIPアドレスも取れるから、DNSで名前解決したり、ルータを超えて外にパケットを投げたりもできる。ルータ超えもとりあえず問題はなさそう。少なくとも、適当なNTPサーバーにパケットを投げれば正しく返答が得られる。



 ということで、W5500からNTPサーバー(Cloudflare)にリクエスト


 ロジアナは送信割り込みと受信割り込みの時間を計測、オシロは10BASE-Tの適当な箇所(とりあえずプリアンブルの最初の立ち下がり)を計測。送信割り込みは送信開始前、受信割り込みは受信完了後だから、ロジアナの方は少し時間が長く計測される。


 NTPサーバーにCloudflareを選んだのは、違法コンテンツで荒稼ぎしているCDNなら頻繁に打っても迷惑かからんやろ、という理由。あとは、たぶんGoogleは日本国外のアジアサーバー、Cloudflareは日本国内のJPサーバーのはずだから、応答が早いというのもある(応答が遅いとオシロで見るのが面倒くさい)。応答速度で言えばNICTの小金井サーバーを指定すればCloudflareと同じ程度には早いはずだけど、カツカツの予算で運営しているであろう国立機関のサーバーをアホな遊びで負荷かけるのも忍びない(神戸サーバーは物理的に遠いのでレイテンシが若干増える)。awsはGoogleに比べれば応答は早いし、NICT神戸より若干早いので、おそらく国内サーバーだと思う。


 他のサーバーも含めて割り込み間隔を計測。何回か試すと、最初に比べて数ms程度短くなる。たぶん途中の経路が少しずつ最適化されて、その経路がキャッシュされるんだと思う。NTPで時刻精度が欲しいなら結構高頻度に(少なくとも途中で最適化された経路のキャッシュが消えない程度の頻度で)打たないとだめかも。でもそれをやるとルータのテーブルを占有することになるので、あまり良くなさそう(NTPサーバーへの負荷も大きいし)。数時間毎にバースト状に1秒間隔で5発くらい打ってRTTが一番短いものを採用する、あたりが落としどころかな。

 SEND_OKとRECVの間隔は、Cloudflareは28ms程度、AWSは30ms程度、Googleは55ms程度、かな。一旦経路が収束すれば、何回か送ってみてもほぼ安定した間隔が得られる。

 ちなみに、PC(C#)からソフト処理でCloudflareにNTPを打ってみると、RTTは172ms程度と計測される。実際は30ms程度で帰るはずだから、PC内部で150ms近い遅延が発生していることになる(ちょっと大きすぎるので、もう少し工夫すれば圧縮できそうな気もする)。


 そういえば、北海道にNTPサーバーってないのか?と思って、試しにさくらインターネットの公開NTPサーバーを叩いてみた。結果、23msで応答が帰った。Cloudflareを抜いてトップ。とはいえ、おそらく関東圏であろうCloudflareと比べて圧倒的に早いというわけでもない。もしかしたらONUあたりがボトルネックになっていて全体的に一定の遅延がかかっているだけかもしれないけど。

 北大にもNTPサーバーはあるらしくて、DNSで問い合わせれば正しそうなIPアドレスが得られるけど、試しにNTPパケットを投げても応答がないので、おそらく校外からは使えないんだと思う。



 NordVPNのIPアドレス検索に突っ込んでみると、AWSは大阪として表示されるけど、Cloudflareは結果なし、Googleはジョージア州、さくらは結果なし、になる。

 ジョージア州までは大圏航路で1.1万km、往復2.2万kmとして伝搬時間は最速でも73ms程度必要だから、普通に考えれば55msで帰るのは不可能。ニュートリノ通信とかで地球を貫通したとしても往復1.9万kmちょっとあるから、63ms程度かかる。ニュートリノ通信、あんまり早くないんだな。HFTで10ms早ければ大儲けできるだろうけど。/* 実際にニュートリノ通信が実用化されたとすれば、途中でルータを挟まずに直結できる分で差はもっと大きいだろうけど(※変復調のレイテンシは無視するものとする) */


***


 オシロでサンプリングした100BASE-TXを復元する遊び

 ↑オシロで取った波形(1Gsa/s)を1symbol(8samples)で折り返してグラフ化

 ↓1symbol分の平均値

 サンプリングした波形は主にオーバーシュートに起因するノイズが多いので、平均化するだけでアイがかなり広がる。


 平均値の微分値の絶対値の平均値

 1-8はラグのサンプル数、max/minはラグごとの最大値と最小値の比。ラグを大きくすれば微分値も大きくなるけど、最大/最小の比が下がってしまう。比はラグ1が一番大きいけど、とはいえ3割程度しか変わらないが。


 平均化したサンプルと、それの微分値の絶対値の平均値(ラグ1)

 ビットの位相と微分値の位相には関連性が認められる。

 微分値の適当な位置(最下点or最上点)を基準にして、そこからNポイント後をサンプリングに使う、みたいな感じにすれば、アイが開いているところのサンプルを取ることができる。


 ただ、今回のデータの場合は、微分の位相とビットの位相は微妙な位置関係になっている。サンプリングレートが数倍高ければ(数Gsa/sでサンプリングできれば)もっと綺麗な関係になるはず。もっと上のクラスのオシロが必要になるし、計算量もかなり増えるけど。

 あと、サンプルデータをざっと見た感じ、クロックエラーは十分に低そうな感じ。少なくとも、10kpts程度であれば十分にコヒーレント。短いパケットがどこにいるかがわかっていれば、クロックリカバリ無しで固定位相でサンプリングしても問題なさそう(今回の場合はW5500からUDPを投げて、SEND_OKでトリガしたので、その位置付近にパケットがあることはわかっている)。


 ということで、ビット位相は固定で、MLT-3の復調

 青と橙がMLT-3(NRZI)から復調したビット(青がビット0、橙がビット1)。PRBS(11bit)との相関値も緑で示している。

 100BASE-Xはアイドル時に正弦波状の信号が出しっぱなしになるので、31.25MHzの線スペクトルをばらまかないようにPRBSで拡散を行っている。接続初期はPRBS位相が不明なのでビット列は0と1がランダムに出ている。

 この乱数ビット列に対してPRBSを相関させる。一定の長さ(2047bit)のビット列が溜まると相関値が+1に安定して、2047bit周期で-2047のピークが出る(PRBSのアイドル信号は負論理なので相関値も負になる)。

 ピークを見つけたらそこをPRBSの基準として、ビット和を取る。以降はアイドル信号のビット1が出続ける。

 7000付近で短いUDPパケットを1個投げていて、相関値が暴れることで非アイドルであることがわかる(ビット0も出てくる)。

 ここのビットパターンを見ると頭にJKや末尾にTRがあるので、少なくとも100BASE-Xとしてそれなりに正しく復調できているはず。


 100BASE-TXでは10BASE-Tと違って常にデータが流れっぱなしになるのは、クロック同期だけでなく、PRBSの同期を維持する目的もありそう。そもそもPRBSを使わなければデータがない時は4B5Bビット列自体止めておけば線スペクトルは出ないのでは?という気もするが。それはそれでやはりクロックや4B5Bの同期が面倒なんだろうけども。



 拡散を解除した4B5Bから、過去10bit分のビットストリームを持っておいて、JKを見つけたら以降TRが出てくるまでをダンプすると、555555555555D550EBF6XXXXXX0008DC010203080045000020000A400080117633C0A80189C0A801B600440009000C76F3010203040000000000000000000000000000XXXXXXXXというようなバイト列が得られる。最初の55..D5はイーサネットフレームのプリアンブル(頭にJKが入るので、10BASEに比べて1バイト少ない)、50EBF6XXXXXXが送信先MACアドレス(PC宛で出したのでASUSのコードから始まる)、その次が送信元MACアドレス(WizNetの適当な番号を設定)、以降IPv4ヘッダやUDPヘッダ、ペイロード、パディング、CRC、と続く。CRCを計算すると正しく0x2144DF1Cが得られる。

 ということで、100BASE-TXも無事に復調を確認できた。


 わりと簡単に復調できた10BASE-Tに比べて、100BASE-TXは復調がかなり面倒くさい。当然だけど、ビットレートが上がると復調の難易度も上がる。もっとサンプリングレートの高いADCとか、それこそLSIみたいにリアルタイムでアナログ的な処理ができるのであれば、もっと特性よく受けられるんだろうけど。



 100BASE-TXは3値(+1V、0V、-1V)を使用して、NRZIでデータを送る。0を出すときは位相を維持、1を出すときは90度進める。アイドル時は1を出し続けるが、NRZI/MLT-3で125Mbaud/4=31.25MHzの3レベル正弦波が出続けるから、複数の100BASE-Tを引き回したりすると31.25MHzの強烈な線スペクトルが出る。これを抑圧するために11bitのm系列で拡散する。

 m系列の位相を決めるためには2047bitのアイドルが必要だから、少なくとも35マイクロ秒程度のアイドルが時々入る必要がある(まあ、イーサネットで帯域使用率を完全に100%フルで使うこともあるまいが)。

 なんか、ベースバンドと言いつつ、結局無線通信と似たようなことをやってるなぁ。10BASEはマンチェスタ符号だからどちらかといえば有線通信寄りだけど(ADS-Bとか、無線通信でもマンチェスタ符号の使用例はあるわけだが)、100BASE-Xはスペクトラム拡散とかしてて、普通に無線通信のベースバンド信号って感じだ。……だからベースバンド信号なのか。納得。

 10BASE-Tも100BASE-TXもツイストペア1本で送るから、適当なキャリアでFSK変調とかすればそのまま無線で飛ばせそう。もっとも、帯域幅がかなり広いから周波数使用効率は悪いし、変復調も面倒だろうけど。それに、有線用の規格だから誤り訂正とかは全く無いので、無線で飛ばそうとすると品質が厳しいだろうけど。だからわざわざWiFiを作ってるわけだし。



 100BASE-TXって平衡接続のプラスとマイナスを間違えるとどうなるんだろう? Google AI曰くリンクアップしないor極めて不安定になるとのことだけど、でもMLT-3って電圧レベルの変化が1、維持が0なわけだから、それがプラスに変わろうがマイナスに変わろうが関係なくね?

 10BASE-Tはマンチェスタ符号が逆転するので、ビット論理が逆になるから基本的に逆接続は駄目だろうけど。

 こういうのは実際に間違ったピンアサインのケーブルを作って試してみるのが確実なんだろうけどなー。気が向いたらEthernetのケーブルを作る工具類を買おう……とは思いつつ、頻繁に使うわけじゃないから圧着工具は安物でいいだろうけど、いかんせんCat.5eケーブルがな。。。100mとか買っても使わないわけで、1割使うかもわからないのに気軽に買える値段でもないし、かといってPCとかある程度信頼したい機器の接続に自作ケーブルを使う可能性があることを考えると極端に安いヤツを買うのも嫌なわけで。適当な長さのCat.5eAssyを買って切って使うのが現実的かな。切って使うことを考えてないであろうケーブルって切って使えるのかわからないけど。



 100BASE-TXって途切れずに(連続位相で)アイドル信号を出しっぱなしにするから、1対1が前提のはずなんだけど、最近のリピーターハブって100BASEや1000BASEに対応しているらしい。どういう原理なんだろう?

 他のデバイスから送られてきたパケットを一旦クロック復元して適当にバッファしてから再送する、みたいなことをやってるんだろうか? バカハブって実はスイッチングハブと同程度には複雑なことをやってる?? だとするとスイッチングハブと同じくらい複雑で、圧倒的に数が出ない分で、値段が高いってのは理解できる気もする(実際はどうかわからないけど)。

 というか、一旦復調して再クロッキングして配布するくらいなら、スイッチングハブのMACアドレスルーティングを省略して、入ってきたパケットを全部ブロードキャストとして解釈して出せばいいんじゃね、って気もするな。とするとスイッチングハブの小改造でリピーターハブとして使えそうな気もするが。

 でも最近のスイッチングハブなんてCPUやFPGAでなく、LSI/ASICで組んでるだろうし、それを改造しようとするとやっぱり製造コストが高くなるんだろうな。スイッチングハブのデバッグ用機能でMACアドレスルーティングをせずにブロードキャストする、みたいな実装がされているヤツがあれば、安くリピーターハブとして使えるんだろうけど、そういうふうに使えると知られている製品が有名でないってことは、無いんだろうな。

 スイッチングハブってMACアドレステーブルが空のときはブロードキャストするわけだから、強制的にテーブルをクリアするような(メモリで辞書引きしても結果を返さないような)機能があればいいんだろうけど。

 同じMACアドレスが複数のポートに接続されていたらそれぞれのポートにパケットを出す、みたいな機能を持ったスイッチングハブがあれば、監視したいデバイスのMACアドレスをPCから出して横流ししてもらう、みたいなこともできるだろうけど(MACアドレスをどうやって偽装するかはさておき)、実際のスイッチングハブは、MACアドレスは最初に登録されたポートを使って、一定時間(数分とか)で削除して、必要になったらブロードキャスト/学習で登録し直して、同じMACアドレスが複数存在する場合はテーブルから削除されたタイミングで新しく応答したほうが使われる、みたいな挙動らしい。



 10BASE-Tの10MHz(max20Mtoggle/sec)って、マイコンからすればSPI/UART/USB FSと同程度のGPIO速度なわけだし、変調方式だって極めて単純だし、10BASE-T Phyを内蔵したマイコンだってもっとあっても良さそうな気がするけど、Ethernet Phyを内蔵したマイコンってかなり少ない気がする。前回書いたSTM32はMACまでを内蔵していて、外付けしたPhyとはRMIIで接続する方式。

 別件で調べ物をしていたらルネサスのSHでPHY内蔵(パルストランスだけ外部に用意)というものが出てきた。BGAパッケージなので結構大規模なマイコン。

 平衡を扱わなきゃいけない(コンパレータで受けなきゃいけない)のが面倒、長距離を引き回して入ってくるノイズに耐えるのが大変、そもそも10BASEの需要が無い、みたいな理由なんだろうか。そりゃUSB FSと10BASEどっちを使いたいかというとUSBのほうが需要はありそうだけど、かといって10BASEもちょっとしたセンサやコントローラのネットワーク化とかでは便利そうな気がするけどな。USBは短距離のP2Pでしか使えないけど、10BASEなら比較的自由なトポロジで配置できるし。

 そういう機器を作りたいなら適当なPhyをSPIとかで外付けすればいいでしょ、みたいなことなのかもしれないけど。

 これからの時代だと、車載用の10BASE-T1Sや100BASE-T1を内蔵したマイコンは出てきそうだけど、マルチレベルを出さなきゃいけないからマイコン直結は面倒そうだ。結局RMII接続かな。ワンチップで(外付けPhy等無しに)10BASE-T1Sを接続できるマイコンは末端付近で便利そうだけどな。まあ、それが発売されたところで、家庭やオフィスの10BASE-T対応ネットワークに接続できるわけではないけども。



 Wikipediaのボーレートの説明を見ると、10BASE-Tは10Mbaudと書いてあるし、RS-232でもbpsとbaudは同じ値、みたいに書いてあって、ちょっと違和感。

 個人的には、ボーレートは1秒間で信号が変化する最大の回数、ビットレートはそれによって送ることができる実効データレート、の認識なので、例えば10BASE-Tはマンチェスタ符号化だから20Mbaudだし、9600baudのRS-232はスタートビットとエンドビットを除いて実効ビットレートは7680bps(Start1,Data8,Parity1,Stop2なら6400bps)、というイメージなんだけど。


2026年1月14日水曜日

小ネタ


 浜岡原発審査で過小評価疑い “データのねつ造 極めて重大” | NHKニュース | 静岡県、原発、原子力規制委員会

 そもそもなんで規制する根拠となる資料を規制される側に作成させているんだよ、という運用の問題な気がするけどなぁ。誰が好き好んで自分の首を絞める作業を馬鹿正直に行うんだよ。そういう問題が起きないようにするために、独立性を高めることを目的に作ったのが規制委員会だろ。せめて規制するための資料くらい自分で作れよ。まあ、規制するための数値を規制庁が用意しても、それに耐えられるという根拠を改ざんされたら意味ないじゃねーか、という話ではあるけど。


 経産省 浜岡原発の契約変更問題 中部電力に追加報告求める | NHKニュース | 原発、経済産業省

 別の問題も出てくると、体質の問題な感じもしてくるけど。あるいは長期間運転を止めているせいで緊張感が失われているみたいなこともあるのかもしれないけど。



 IT開発者向けの質疑応答(QA)サイト「Stack Overflow」で投稿数が激減、ユーザー戦慄 - やじうまの杜 - 窓の杜

 なんとなく個人的に感じている「昔のOSSって謎の活力があったよね」くらいの時期と相関していそうな気もするけど、でも2023年辺りまでは結構アクティブだからあんまり関係ないか。



 Shrike-lite: 開発ツール・ボード 秋月電子通商-電子部品・ネット通販

 ForgeFPGAとRP2040を載せたボード。

 オープンソースでGitHubに色々資料あるから参照してね、という方針。逆に言えば、まとまった資料が存在しない。LiteではないやつはRP2350が乗っているらしい。

 FPGAとRPは、RP側から転送するためのSPI接続等がある程度で、基本的には全部ピンに引き出して必要に応じて外部で接続する形かな。まあ、そのほうが使いやすいしな。



https://strawberry-linux.com/pub/ft232hx-v2-an001.pdf

 ストリナさん、手ハンダのクオリティがゲフンゲフン

 自分は基本的に共晶ハンダしか使ったことがないので、無鉛ハンダだときれいにつかないとかあるのかもしれないけど。



 半導体ウエハの見た目をしたウエハース(お菓子)って作れないものかな。8インチとか12インチとかちょっと大きめの円盤状の形で、表面に多少の模様をレーザー等で焼き込んだりして。必要に応じてカット(ダイシング)して提供してもいいし、丸いまま売ってもいいし。あるいはダイシングしたものをクリームで重ねてチップレットにしてもいいし。模様もレーザーで後から焼くだけじゃなくて、光ディスクみたいに焼いてもいいし。さすがにウエハース程度の引張強度だとあまり細かい模様は無理かもしれないけど。

 千歳あたりのお菓子屋さんで道産食材を使ったウエハースでそういうやつを作ってラピダスの話題に便乗して売ったら面白そうだけどな。

 ウエハースのレシピってググってもほとんど出てこない。IPコラボで買った大量のウエハースを消費するためのアレンジレシピとかばっかり出てくる。均質な内部構造を考えると材料や加工法がそれほど複雑とも思えないが、どうなんだろうか。


 熱で溶かした砂糖をチョクラルスキー法で引き抜いたらどうなるんだろう? 巨大な単結晶の砂糖とか作れるんだろうか? さすがに8インチとか12インチとかの砂糖の結晶を作っても取り回しが大変そうだけど、ミニマルファブで使うような0.5インチだと細めの金太郎飴くらいの径。産総研のミニマルファブの展示でお土産として半導体風の模様の金太郎飴とか配布しても面白そう。あるいは単色の砂糖の棒を0.25mmくらい(実際のウェハー厚程度)にうまく切断して、レーザーで半導体みたいな模様を焼き込むとか。同じ程度の厚さというよりは、同じ程度の曲げ強度で切断するべきかもしれないけど。

 理研が富嶽そうめんとか売ってるし、産総研も負けずに半導体ウエハースとかを売ろうぜ。研究者カードを入れてさ。


 メーカーによるグラニュー糖の加熱特性の違い|農畜産業振興機構

 いくつかのサンプルで融点を比較した結果とか。

 メーカーの違うグラニュー糖でカラメルソースを作るとかなり違うものが出来上がるらしい。微量な成分の差で大きな影響があるとかだいぶ半導体に近そうな感じがしてくるな。



 Google Pixelのカメラ、電源ボタン二度押しでカメラを起動して音量ボタンで静止画を撮影する機能、動画を撮影したいときに困ってたんだけど、音量ボタン長押しだと長押し中は録画されるんだな。長押し中に録画ボタンを左に移動して鍵アイコンに重ねるとボタンを離しても録画を継続して、録画ボタンをタップor音量ボタンで録画終了。タッチ操作ができない状況(厚手のタッチ非対応手袋を使っているとか)を考えると、物理ボタンだけでオルタネートに録画を開始できると便利なんだけど、ちょっと足りない。



 YouTube、デザインが変わってまた使いづらくなったな。

 YouTubeとかGoogleの機能やデザインの変更って「不便になった」と感じることは多いけど、「便利になった」と感じることってほとんど無い気がする。まあ、不便になったら目立つし、便利になっても無意識に使うだけだし、みたいなこともあるんだろうけど。

 それにしても、普通にスクロールやクリックができないUIって単純に不便だし、もっと言えばクソだろ。なんでそんなものがデプロイされるんだろう? Google系の会社、時々本当に変なことをやる。



 amazonみたいな大企業が作る防犯カメラみたいな製品にひどく反発しているレビュー系の仕事もやっている某有名企業、消費者のプライバシーを侵害して稼いでいるからみたいなのが理由らしいけど、彼らってどういう製品なら納得するんだろう。

 小さい会社が開発した製品ならいいの? そういう会社が開発したコネクティングデバイスが信頼できるとでも? セキュリティしかり、製品寿命しかり。あるいは小さな会社の製品がある程度普及したら簡単に買収されるリスクも有る。西側企業が買収するならともかく、家電企業が中国企業に買収されたりみたいなことも起きている昨今、下手に市場価値の低い会社が作る製品はそういう点でもリスクがあると思うが。AnkerやTP-LinkやiRobotの例もあるし。アメリカのビッグテックが消費者のプライバシーを侵害するのは許さないけど中国政府がアメリカ国民のプライバシーを侵害するのは問題ない、とでも思ってるの?


***


 ジャイロスコープのプリセッション、力学的に正しいかは別にして、感覚的に理解しやすいのは、人工衛星の軌道で考えてみることだと思う。

 人工衛星が円軌道を回っているときに、軌道面に対して垂直に力を加えると、垂直な方向の運動エネルギーが増える。元々持っていた運動エネルギーとベクトルが合成されるので、斜めの速度になる。あとはそのベクトルを面内に持つ軌道面を回転する。これだけ。

 これを十分に弱い力かつ長い周期で考えたときに、この人工衛星が例えば適当な間隔(10mとか)で大量に並んでいても、同じ動きをする。それらを紐でゆるくつなげても同じ動きをする。同様に、棒で比較的固くつなげても同じ動きをする。剛体(自転車の車輪とか)で考えた場合は、1周期未満の短い時間で力が加えられる前の箇所にもプリセッションが伝播する点が大きく異なる。

 大雑把にはそういう感じに見ておけばいい気がする。ただ、この方法でイメージするためには、人工衛星の軌道をある程度正しく認識しておく必要はあるので、例えば小学生にこのイメージを説明すれば全員が理解できるというようなものではないけれども。

 もう少し身近なもので近似したいなら、重りを付けた紐を振り回してもいい。ただし地球の重力は無視するものとする。


 質点に与えた力は時間積分して垂直方向の速度になるが、その力を受けた結果は元々持っていた運動エネルギー(接線速度)との合成だから、接線速度に対して垂直速度が小さければ角度の変化は小さくなる。接線速度が大きければベクトルの角度は小さくなるし、接線速度が小さければ角度は大きくなる。ジャイロ剛性はこれでおおよそイメージできる。もちろん、接線速度がゼロなら垂直に与えられた速度がそのまま出てくるから、歳差運動は発生しなくなる。どれほど小さくても接線速度がゼロでないなら、歳差運動が発生する。


***


 LAN内機器での時間同期の標準規格「PTPv1」こと「IEEE 1588-2002」【ネット新技術】 - INTERNET Watch

 累積誤差を排除した2代目PTP「IEEE 1588-2008」、LAN内機器での時間同期の精度を向上【ネット新技術】 - INTERNET Watch

 PTPv2の成功を受けて登場した「IEEE 1588-2019」は、広範な利用のためのオプションを追加した「PTPv2.1」【ネット新技術】 - INTERNET Watch

 PTPってちゃんと調べたことなかったけど、わりと簡単っぽい感じだな。UDPのパケットを投げるので、基本はNTPとほぼ同じ。

 NTPはクライアントから始めて1往復のやり取りを行う。パケットの中に送受信時刻を含めるが、送信時刻は送信する予定の時刻を入れてあるに過ぎないから、キューに積まれたりすると実際の時刻とずれることがある。

 PTPはサーバーから定期的に2つのパケットをブロードキャストする。2つ目のパケットには1つ目のパケットを送信した実際の時刻が記録される。クライアントは1つ目のパケットを受信した時刻を記録しておき、2つ目のパケットで時刻を決める。ただしこの1つ目の時刻には伝搬遅延分の遅れがある。

 正確な時間が必要になると、クライアントはサーバーに向けてパケットを送信する。クライアントはこれの送信時刻(含1way遅延)を記録しておく。サーバー側はそれを受信した時刻を記録し、これをクライアントへ返信する。クライアントが送った時刻とサーバーが受信した時刻を比較すると2way相当の伝搬遅延が得られるから、これを差っ引けば、サーバーとクライアントで時刻同期ができる。

 これがPTPv1の仕組み。

 PTPではパケットのどの部分を時刻の基準に使うかも定められているので、これと時刻を結合するために、PTP対応のハードウェアが必要になる。時刻の基準はあくまでもMAC層のパケットの頭が基準になるので、PTPに依存したものではないから、他にも汎用的に使える時刻基準ではあるから、汎用的に使える時刻基準としてPHYで対応して、それを流用してPTPにも使う、みたいなことは可能だろうけど。

 ただ、PTPv1ではブロードキャストのパケットにはPTPサーバーを選択するための情報(精度や確度など)を含めている関係で、パケットが大きくなり、これで輻輳が発生することで信頼性が低下する問題があった。そのため、PTPv2ではブロードキャストパケットを小さくすることで高頻度に放送できるようにした。これがv1とv2の互換性がない所以。

 v2.1ではCERNで得られた知見に基づいて精度改善を行ったり、曖昧さを除去する改定が行われた(その他色々なオプションの追加も)。例えばスイッチやルーターを通過する際に増える遅延(特に遅延に方向性がある場合)に対する改善など。PTPv2.1を使うためには対応したスイッチ/ルーターを使う必要がある。


 以上がPTPの簡単な仕組みだけど、この理解が正しいのかは不明。PTPの仕様はIEEEが決定・販売を行っているので、非会員が正規に買おうとすると250USD程度の値段になる。

 結局、規格が普及するかどうかは無料公開か有料公開かに関係なく、需要があるタイミングでタイムリーに規格を提案できるかどうかなんだろうな。よほど高価なプロプライエタリとかならともかくとして、200ドル程度でドキュメントが買えるならな。趣味で遊ぼうとかすると困るけども。


 PTPの要点はハードウェアでパケットの時刻決定ができる点と、パケットの送信時刻を別のパケットで送る点なので、やろうと思えばNTPの拡張でも対応できたような気がする。物理層の時刻決定は追加で必要として、残りはNTPのパケットだけでどうにでもできそう。ブロードキャストとか追加領域とか、一通り必要な機能はNTPにもあるし、124番ポートは特に使われていないようだから、これを追加でNTPに割り当ててもいいだろうし。

 例えばクライアントは124番を開いて、サーバーは124番に対してブロードキャストを行って、それを受信したクライアントは123番宛に追加でパケットを送って、従来のNTPは123番でそのまま使って、みたいな感じとか。

 PTP、わざわざ新しい規格を作るほどかなぁ、という気はする。下手に拡張するより作り直したほうがわかりやすいだろ、ってことかもしれないけど。

 PTPは100万分の1秒の精度がある、とかいったって、NTPだってパケットのフォーマット自体は数百ピコ秒程度の時間分解能があるわけだから、確度を改善すればいくらでも改善できるだろうし。

 ただ、上記の記事はあくまでもNTPに一番近い形態を解説しているだけであって、実際のPTPはもっと色々な設定が可能なので、柔軟に使おうとするとやはりNTPの発展では難しくて、PTPが必要だったんだろうな。


 PTPはイーサネットフレームのヘッダ開始点を基準に時刻を決めるので、自然にイーサネット内でしか使用できない。まあ、べつにルーターやWiFiを超えさせてもPTPパケットとしては問題ないはずだが、その間の遅延を確定(高精度に推定)できないので、PTPとしての精度は得られない。なので、パブリックPTPサーバーみたいなものも基本的には存在しない。

 将来的に広域通信網全体にPTP対応機器(ユーザーが見えないところはTCで、末端付近はBCで、とか)が配置されたらどうなるかはわからないけど。GNSSみたいにジャミング・スプーフィングのしやすい時刻でなく、有線で高い精度の時刻を配布できるPTPが普及すれば欲しい用途はあるだろうし。

 しかし、PTPは高頻度でパケットをブロードキャストしなきゃいけないから、広域に使うのは難しそうな気がする。BCとP2Pで通信するならNTPみたいにクライアントドリブンで使えるのかもしれないけど。/* PTPとP2Pの紛らわしさよ。。。 */


 PTPとしては、高い時刻確度が必要な場合はGNSS等で、そうでなく、あくまでもLANの中(例えばファクトリーオートメーションやテレビスタジオ)で機器間の同期を取りたい場合は絶対的なUTCとの同期は必要ないから、そういう場合はNTPで外部と同期すればいいらしい。

 もう少し厳密に言うと、PTPはUTC系ではなくTAI系+Leap情報を採用しているらしい。ので、GPS系とは相性が良さそうだし、閏秒を透過的に拡散する最近の公開NTPサーバーと組み合わせると問題が起きそう。特にホールドオーバー用に高精度なクロックをローカルにおいている場合。まあ、それくらい考えてるシステムならNTPサーバーの実装(LIを正しく返すかどうか)くらいは確認して使うだろうけど。あるいは、GNSSとかを使わない系ならむしろ閏秒は拡散してくれる方がありがたいって場合もあるのかもしれないけど。



 White Rabbit Project - Wikipedia

 CERNのPTP実装。白兎は『不思議の国のアリス』から。

 最長10kmの銅or光ケーブルを使ってナノ秒未満の精度が得られるらしい。

 1000BASE-Tなら125Msy/s、10GBASE-Tなら0.8Gsy/s程度だから、その逆数で8ns、1.25ns、クロックの真ん中でサンプリングするならその半分程度、PTPv2以降は数十~100Hz程度で同期信号を打つから平均化して数倍程度、と考えると、数ナノ秒からサブナノ秒くらいは行けそうではあるが、それにしても。


 確度で見ればGPSコモンビューと同程度で、線を引き回さなきゃいけない分導入コストが高いし距離とコストが比例するけど、外部からの攻撃が難しいとか外部システムに依存しないみたいな利点はありそう。あとは、Gbpsオーダーのデータを流すのにも使える。基本的にGPSはデータリンクには使えないからな。

 有線(ファイバーとか)に対してスプーフィングを仕掛ける難易度ってどれくらいあるんだろうか。十分に情報的なセキュリティを確保したネットワークに対しては、少なくともケーブルに物理的にアクセスする必要があるから、周囲の物理的なセキュリティ確保である程度は対策できるか。GPSならある程度離れた場所からでも受信アンテナに向けてうまい感じに電波を突っ込むだけでも偽装(あるいは妨害)できる可能性がある。物理的に接触する必要があるケーブルなら、建物の耐タンパー性で少なくとも偽装・妨害を試みた段階(物理的にネットワークへ触れる少し前)で検出できる。GPSだって信号自体の認証とかビームフォーミングでどうにかしようという話もあるけど、ビームフォーミングするとまたそれで時刻確度が悪化するとかもありそうだしな。ネットワークも完全に独立したシステムを作るのも難しいだろうし、電子的に外部から入ってどうにかしたりみたいなことも考えられない訳では無いにしても。



 電力保安用IPネットワークにおける高精度時刻同期方式の適用検討-PTP同期の精度評価とIP機器の同期機能割当て- 報告書 詳細情報 | 電力中央研究所

 ガチの研究所が自分たちの必要な精度(1us)を得られるかどうかを色々な条件で比較した結果。ネットワーク系の会社が技術ブログで概要を説明しているのとは異なって、かなり細かいところまで説明している。


 商用電源なんて50/60Hzだから対してタイミング確度あんまりいらんやろ、とか思ってたけど、60Hzを1度単位でサンプリングしようとすると45us程度になるし、マージンを考えると5us程度は必要になるのか。



 そういえばSTM32 Nucle-144でEthernetポートが乗ってるやつあるけど、あれどういうふうに使えるんだろ、と思って軽く検索。STM32自体はRMIIでインターフェースして、PHYはMicrochipのLAN8742Aが乗っているらしい。

 PHYのデータシートを見た感じ、割り込みに設定できるのはWoLとかA/Nとか、いかにもPHYが触りそうな部分だけで、イーサネットフレームの送信とか受信に関連しそうなものは見当たらない。

 そもそもPHYって電線から出てくる電圧レベルをデジタルデータに変換するまでが担当で、フレームを処理したりはもう一つ上の層(MAC?)でやるのかな。その割にWoLはPHYで検出できるから、少なくともWoLが入っているフレームを検出できる程度の機能はあるんだろうけど。


 STM32H7のEthernetはPTPにも対応しているらしい。PTPだけでかなりのページ数を割いて説明している。例によってパケットの内容とかの説明はないけど。

 PTPはMAC層で処理するから、EthernetのクロックとMIIのクロックの差とかもジッターに出てきそうだ。PHYでPTPを処理できれば一番いいんだろうけど、WoLみたいにシンプルなフレームと違って、もう少し上のレベルで動いているから、PHYで処理するのは難しそう。結局MACで処理するのが楽なんだろうな。それにしても、プリアンブルの末端(ヘッダの頭)で割り込みピンを駆動するくらいの機能はPHYにあっても良さそうな気もするけど。



 アメリカのエンティティリストに乗っている某社のドキュメントにPTPの詳しい説明が書いてある。パケットの内容とかも書いてあるので、とりあえず試しに投げてWiresharkで見たり程度はできそう。

 そもそもPTPの内容って有料販売だから気軽に無料公開しちゃだめだと思うんだけどな。グローバルに普及した一般公開されていない(有料販売されている)仕様書の類、このあたりの企業から無料で公開されがち。そういう信頼の置けない商売をやっているから西側から嫌われるんじゃないのか。まあ、ググれば他にもいくつかの企業(機微な製品を扱っているアメリカ企業を含む)が公開している情報にもパケット構造が断片的に書いてあったりするから、そこまで厳しく秘密にしているものでもないんだろうけど(それこそ現物があればWiresharkとかで見ればわかるわけだし)。


 PTPは仕様が無料公開されてないので自分で作ろうとすると大変そうな気がする。WiresharkはPTPv2に対応しているらしいので、適当なパケットを投げてみて試すという手はあるけど。あるいは、CERNのWhite Rabbitが「完全にオープンソース」だそうだから、それを追うという手もあるか。うさぎの巣穴へ真っ逆さま。


***


 W5500でポート9にUDPを投げて、オシロをSEND_OKの割り込みでトリガ

 ↑PCに4バイト投げたとき

 ↓ルーターに128バイト投げたとき

 10MbpsHD、黄色(ch1)がW5500から見たTX+、紫(ch2)がW5500から見たRX+。UDPを出す前にARPでアドレス解決をしているっぽい?

 ルーターからはなぜかエコーバック的なものが帰っている。ただ、W5500はこれを受信してもパケットが届いたとは認識していない(Socket.Int.RECVが立たず、Socket.RxReceivedSizeもゼロのまま)。PCから投げても応答を受信できないから、なんか変なパケットになっているんだと思う。波形を解析すればイーサフレームからパケットの内容を復元できるだろうけど、流石に面倒。。。

 SEND_OKのトリガは、実際には送信が終わる前に出ているらしい。メッセージが衝突したりした場合はどうなるんだろうか。トリガとプリアンブルのタイミングはかなり精密で、数回見た程度だと100ナノ秒未満のジッタ程度に見える。



 PCから同一のUDPパケットを4回送信してRecvで割り込み

 当然だが、パケットを受け取ったあとにRecv割り込みがかかる。2usくらいジッターがあるかな、という感じがする。やはりというか、送信よりも受信のほうが精度が出ない。そもそもW5500の割り込みってタイミングスペックあるのか知らないけど。

 パケットを長くするとフレーム末から割り込みまでの時間も伸びる。おそらくCRCの計算が10Mbpsより遅いんだろう(あるいは受信が終わってから計算しているのか)。受信した長さはRX Bufferを読めばわかるから、Recv割り込みからフレーム先頭の位置までの時間は計算である程度推定できるはずなんだけど、どの程度確実に決められるかは不明。


 W5500の送信割り込みジッタが0.1us、受信割り込みジッタが3usと仮定すると、多少余裕を見てトータルで5us程度になる(受信パケット長から十分な精度でパルス位置を推定できる場合)。NTPは送信時刻を決めるのが難しいけど、PTPのFollow_Upで投げるなら、W5500でPTPサーバ/クライアントを作れば、10us未満程度の同期精度が得られるはず(確度はまた別の問題)。PTPの理想的な状況と比べると4桁くらい悪いけど、ソフト実装のNTPに比べれば2,3桁くらい改善できるはず。そう考えるとNTPとPTPで6-8桁くらい違うのもすごいけど。



 ちなみに、W5500を100BASE-Tに設定すると常にビット列(100BASEのアイドル信号)が出続ける


 だいぶ波形がなまっている。オシロは200MHzだけど、プローブは100MHzなので、125Msy/sを見るのは厳しそう。でも頑張ってクロック同期すればデコードできないことは無さそうかな?

 100BASE-Tのバストリガに対応していないオシロで100BASE-T信号を見るとこれが常に流れるので、イーサネットフレームを狙ってキャプチャするのは難しい(W5500ならSEND_OK/RECVで割り込みをかけてこれをトリガすれば少なくともその付近にフレームがあるはずだが)。



 こういう遊びをしているとアナログ6+デジタル16くらいのオシロが欲しくなる。TekのMOS5みたいに、アナログ1ch or デジタル8chを8系統好きに組めるMSO5は便利そうだなぁ。なお値段。

 横河のやつだと12bit8ch+1bit32chみたいなモデルもある(MSO5換算12ch)。ベース価格で比べればTekの半分くらいの値段だし。まあ、それでも高級な軽自動車が新車で買えるくらいの値段になるらしいけど。横河の一部の機器にはIEEE 1588 PTPサーバー機能が乗っているらしい(クライアントは結構多い機種で対応)。カタログによると「誤差1us以下の高精度なクロック同期を実現」だそうだ。横河の計器は同一機器を接続してch数を倍増する機能があるけど、PTPで同期すれば異なる機種間でも時刻同期ができるらしい。トリガ信号を接続すればサンプリング時刻は同期できるけど、PTPなら非同期的な信号も含めて、柔軟に時刻同期できるだろうしな。

 Sigだとアナログ8ch+デジタル16chで100万円台から300万円弱まで(帯域幅による)。RIGOLもほぼ同じ価格帯かな。SigやRIGOLはいくら最近は良くなってきたとはいえ所詮は中国の安物計器メーカーから始まっているし、ブランド物には使いやすさとかの点ではまだまだ勝てなさそうな気がする。まあ、LeCroyあたりでSigのリバッジを売ってるのを見ると、ブランド品だって安物はクソみたいな品質なんだろうけど。

 LeCのカタログ、「アナログ8チャンネルとデジタル16チャンネルは常に利用可能です。他社の機器のように、デジタルチャンネルを利用する際に、アナログチャンネルを犠牲にすることはありません。テレダイン・レクロイなら、常に全チャンネルが利用できます」とか書いてあってすごい(横河のオシロでもアナログchをデジタルとして使うみたいな製品もあるし)。


*


 10BASE-Tの波形データをExcelに取り込んでみた

 縦軸は任意の単位(8bitADC直読み)、横軸はマイクロ秒。700kptsが2chなのでかなり重い。

 Excelで横幅が広い散布図を書くと補助目盛線の位置がずれる不具合、普通に迷惑なので早く直してほしいなぁ。。。



 .NET FWのChartでグラフ化

 .NET Framework久しぶりに触った。昔のC#って不自由だったんだなぁ。全然好きに書けない。それでもLangVersionで13.0とか指定すればかなり自由にはなるけど。


 2個目の送信を適当にマンチェスタ復号して手動デコード

 クリアビットと思われるエッジは青色の、セットビットと思われるエッジは赤色の点を打っている。また、それらを8個合わせて16進の値も合わせて表示した。復調にはクロックリカバリが必要かなと思っていたけど、クロックリカバリなしでもおおむね問題ない感じで復調できた。クリアビットが明らかに上に寄っているけど、プリアンブルの一番最初のエッジから50%後ろをサンプリングポイントとして採用しているだけなので、その分のズレだと思う(セット/クリア判定はサンプリングポイントから適当に±数サンプルずらした2箇所の高さを比較)。パケット長が60usで1シンボルが0.05usだからタイミングはそこまで厳しくないらしい。

 マンチェスタ符号のクロックリカバリってどうやればいいんだろう? エッジの位置を探すにしても、エッジが鈍っていたらどこを採用すればいいんだろうか。AC結合するにしても、ビットパターンによってはDCオフセットがあると思うんだけど。


 ビットの意味についてはWikipediaを見ながら復調してみたけど、とりあえず妥当な結果が得られていると考えられる。送信先ポートが0で送信元が9だけど、これは単にW5500の設定をミスっているだけ。16進の列もオンラインのCRC32計算機に突っ込んでみたら正しい結果が得られたから、少なくとも明確なビットエラーは無いはず。

 10BASE-Tは安いオシロでも十分に見えるシンボルレートだし、マンチェスタ符号だから見たとおりに復調できるし、楽でいいな。

 FCSの末尾は中途半端な電圧が出ているけど、これは単にマンチェスタ符号の振幅レベルが見えてるっぽい。実データの振幅が高いのはおそらくLANケーブルを伝搬したことで発生したオーバーシュートだろう。FCSの末尾ではマンチェスタ符号として不正なDCを出すことで明確に末端を示しているんだと思う。

 本来はARP(推定)や謎のエコーバックも復調したかったんだけど、思った以上に面倒なので省略。ただ解析するだけなら大した手間でもないんだけど、図示しようとするととても面倒。ChartなんでFW以外で使えないんだよ。。。


*


 ためしにW5500を操作するGUIを試作

 いろいろ設定できる場所とか見れるものが多いので、1画面に全部並べるとFHDでは収まりきらない。

 手動でパケットを投げたり読んだりもできるけど、とりあえずDNSだけ作ってみた。結構大変だった。主に普通のリソース管理で。SPIバスは1本しかないし、ソケットは同時に8本しか開けないから、それらをうまいこと管理する必要がある。

 結局、FT232H/W5500を使っていても、うまい感じに隠蔽すればC#のTcpClientやUdpClientと同じように使えるし、それこそSend/Receiveを作れば全く同じように使えるから、C#側でTcp/Udpを使うコードを書いてそのまま流用したりもできる。


 W5500のCommon Register 0x0017 Socket Interrupt Register、各ソケットから割り込み要求があるとそのビットがセットされるレジスタだけど、データシート上は書き込み可能(R/W)になっているのが謎い。0や0xFFを書いても何の効果もないし、もちろんセットビットに相当するソケットの割り込み要求がクリアされる、なんて機能も無い。


***


 そういえば、SpaceWireって情報がないときでもクロックが出続けているはずだけど、これでクロックを配布しようみたいな使い方ってないんだろうか? 全部の機器はルータで接続されているわけだし、ルータもクロックリカバリして他のポートにクロックを配布できるだろうし、すべての機器がコヒーレントに動いていれば、クロックを積分すれば時刻が得られるから、機器間の時刻同期も楽になるだろうし。

 ビットレートを切り替える際とかは困るだろうけど、宇宙用コンポーネントなんてルーティングも全部冗長化してるんだから、片方ずつ切り替えて常にコヒーレント(片系統が死んだら非コヒーレントで時刻決め)みたいな運用もできるだろうし。

 そこまでして精密にクロック(積分して時刻)を配布したい需要があるかどうかはともかく。SpaceWireだって時刻配布プロトコルはあるわけだから、大抵の需要はそれで十分だろうしな。


2026年1月7日水曜日

小ネタ


 米NISTの原子時計のラボツアー


 実験用のクロックだと思うけど、ナイトビジョンゴーグルが置いてあるのが面白いな(おそらくFLIR社のGen1)。機器では剥き出しの赤外線レーザーも使っているそうだから、センサーカードでトレースするよりNVGで見たほうが楽、ってことなんだろう。

 フィクション世界でよくある赤外線レーザーをナイトビジョンゴーグルで見るやつ、現実世界でも実際にやってるわけだ。


 コロラド州ボールダーってアメリカのかなり内陸の方にある。標準周波数・時刻を放送するにはそのほうが都合がいいんだろうけど、最近の一般相対論的効果が問題になるような(標準海面からの標高が必要になるような)時代になると大変そうだな。まあ、国土を網羅した水準点からちょっと伸ばしてラボに引き込めばそれで済むんだろうけど。

 将来的に標高計としての精度が10cmとか1cmとかのオーダーで日常的に得られるような時代になると、あまり内陸すぎると標準海面との結合が面倒になって海岸近くのラボのほうが使いやすいって話になったりするんだろうか? あるいは日本だと周りを海に囲まれていて潮汐が綺麗に流れないからモデル化が難しい、みたいな課題が出てきたりするんだろうか? 潮流を遮ることのない孤島に基準点を置いてコモンビューで結合するとかが必要になるのかな。

 単に海面と結合できればいい程度なら、東京大学は日本水準原点から近くて便利そうだ。NICTもそう遠い場所じゃないし。



 秋月電子、最近全然使ってなかったけど、久しぶりにいろいろ探して見るとディスコンマークだらけだな。

 秋月製のブレークアウトボードがだいぶ前からSparkfunみたいな設計思想でなんだかなーと思ってたけど、より一層電子工作初中級者向けに力を入れる一方で、かゆいところに手が届くような商品ラインナップを減らしているような雰囲気。

 ストリナもストリナで変なフォームファクタのブレークアウトボードを量産していた時期があったけど、最近はあまり見かけない気がする。そもそも最近は新製品をあまり作っていないというのもあるけど。ストリナは最近もちらほらセンサ類を出してるけど、基本的には電源周り専門メーカーみたいな感じになってきたな。

 最近は中国系の安いPCBメーカーが使いやすくなってきたから、変なSMDを使いたい人は自分で基板を起こしたり、部品もMouserとかで買ったりするようになって、小さい店だと中上級者向けの商品ラインナップは厳しいのかもしれないけど。個人向けにニッチな製品が買えるショップは大陸系のECストア(含不正規品流通ストア)がその役割を取って代わって、実店舗は入門・初中級が気軽に欲しい部品を買える方向に特化して、みたいな。時代の流れ的な。



 Type-C PDのデュアルロールなモバイルバッテリーとかで、ロールを強制的に切り替えるボタンが欲しい。例えばノートPCとモバイルバッテリーを接続した場合に、ノートPCの電力でモバイルバッテリーを充電したり、あるいは逆にモバイルバッテリーからノートPCを充電したり、というのを、気軽に切り替えられるようにしてほしいわけだ。

 CCのブリッジみたいなICで、特定のメッセージを捨てるとか、強制的にロールをスワップするみたいなICもありそうだけど、気軽に安心して信頼できる製品でそういう物があるかというと…… エレコムやサンワサプライあたりでそういう機能(ユーザーインターフェース)を内蔵したPD充電ケーブルとか売ってくれるとありがたいんだけど。あるいはスイッチ無しでも、ダイオードとして使えるPDケーブル(ケーブルの向きを変えたら給電方向を切り替えられる)とか。



 興味本位で海外通貨の購入方法を調べてみたら、近所のローソンが出てきて、いやいや、んなわけwwと思ってたんだけど、そういえばこのあたりってなまじ観光地なので、訪日客向けに外貨両替の需要もあるのか。

 ローソン外貨両替機|ローソン公式サイト

「外貨から邦貨への両替のみとなります」だそう。そりゃそうだろうな。

 Google Mapには近所にもこの機械が置いてあるらしいんだけど、公式サイトの一覧には書かれていない。謎い。


 旭川空港にも外貨両替機は置いてあるけど、100ドルとか100ユーロとかそのあたりの1金額しか対応していないらしい。海外旅行に行くために大きな額を両替したいわけじゃないからなー。単に小額紙幣を何種類か見比べるために手元に欲しいだけであって。



https://www.amazon.co.jp/dp/B076H4R6J6

 大量の毒ヘビが飛行機の中で暴れまわる、みたいな感じの作品。毒が出てくるので若干グロ表現ありのB級ホラーなので、他の人に勧めたいという気はさらさら起きない作品だけど。

 大昔に読んだB級映画の紹介で面白そうだと思って頭の片隅に入れていた作品。「フライトシミュレーター」(プレステ2)で2000時間の飛行経験を持つデブが最後に着陸を決めてサミュエル・L・ジャクソンが「神様プレステ様!」と叫ぶというシーンがあるらしくて面白そうだなって思って。

/* Bloggerのテキストエディタで黒文字黒背景にすると若干見えちゃうんだな。黒文字は明示的な色指示が無いので、スタイルシートとかブラウザの設定で真っ黒ではなく、濃い灰色で表示されるっぽい。ちゃんと見えないようにしようとすると、スタイルのcolorとbackground-colorに同じ色を指定しないとだめっぽい */


***


 間接的にニュートリノを見る生態系、という空想。

 惑星が恒星に近く、ニュートリノ断面積の大きい物質が比較的リッチな環境で、化学的に光を遮る物質がすくなく、地理的に恒星光が届かないような環境で進化した生態系を想定。このような環境では環境がニュートリノチェレンコフ光で発光しているはず。端的に言えば、このチェレンコフ光を見ることができるように進化した生物群。

 惑星の軌道が小さく常に暗黒の世界ということは、潮汐ロックした環境だろう。夜間側で生態系を維持できるということは、昼間側はもちろん、トワイライトゾーンも生息するには高温すぎる環境のはず。であるならば、恒星光を浴びたことがない生態系もあり得るはず。ただ、その場合は初期の低効率な光受容体を選択して残すことができないから、チェレンコフ光が見えるような高感度な目に進化する可能性がかなり低い。

 昼間側あるいはトワイライトゾーンで発生・進化した生態系が目を十分に進化させたあとで、何らかの要因で惑星軌道が縮小して生物は夜側へ移動し、その過程で高感度な目に進化させた、みたいな可能性はあり得るけど、ちょうどいい時間スケールで軌道を変えるのはかなり難しそう。あまり早すぎると生息地を移動する前に絶滅するだろうし、天体物理的な尺度での短期間でも、生物が進化するには十分に短い期間になるだろうし。

 あるいは、大きな軌道の時点では潮汐ロックはしておらず、惑星全体(少なくとも赤道全体)に生態系が分散していて、何らかのイベントで近日点が極端に下がって、かつ遠日点も下がって、一部の地域にいた生態系がたまたま夜側で生き残る、みたいなことは考えられるか。公転軌道を都合よく2段階に変えるようなイベントも思いつかないけど。1回だけならショルツ星みたいに恒星の接近で軌道がずれる可能性はなきにしもあらずだけど、もう1回となるとなぁ。内惑星とのスイングバイとかでなんとか…… それにしたってきれいな円軌道に持っていくのは難しいし。


 もしもニュートリノチェレンコフ光を見ることができる生態系があったとすると、進化の過程でニュートリノ断面積の大きい物質を排除するような選択もあるんだろうか? 「目に見える」食べ物を体内に取り込むと早く捕食されるということにはなるだろうけど、だからといって「目に見えない」食べ物をどうやって探すかという問題が出てくる。電気信号を探すみたいな器官が出てくるとかかな。そもそも「目に見えない」食べ物はどうやってニュートリノ断面積を下げてるんだという問題になるし。


 ニュートリノを「(間接的に)見る」というよりは、単純に光源として使っているだけではある。恒星に極めて近い惑星で、通常であれば温度が高すぎて生物が生存できない環境であっても、裏面なら適度に冷えるはずだし、裏面なら有害な放射線もほとんど完全に遮断できるが、惑星を貫通するニュートリノのチェレンコフ光を光源にして数百nm程度の電磁波を見ることができる生物が作れないか、みたいな考え方。


 地球の海洋でもニュートリノチェレンコフ光はそれなりの頻度で発生しているだろうけど、とはいえそれを見られる生物がいるかというと…… 人間がニュートリノチェレンコフ光を探そうとするとアホみたいな大きさのPMTが必要になるからなぁ。よほど強い理由がないと光受講器官をそこまで発達させるのは大変そう。


***


 EthernetってそのルーツはALOHAnetとかにもつながるわけだけど、これはUHF(つまりRF)でパケットをやり取りしていた。10BASEとかで明示的にベースバンド信号と書いてあるのは、それらと比較してという点もあったんだろうか?



 W5500のSocket n TX Write Pointer Registerの使い方が結構謎い気がする。送信する場合、データを入れたりSENDコマンドを叩いたりはコントローラー側で管理できるから、わざわざリングバッファを使う必要はないはず。RX Bufferみたいに、バッファの中にデータ長を持っているならともかく、そういうわけでもないし。書き込みするときにポインタをキューに持ってとかをやれば送信メッセージをキューイングできるけど、バッファの空き容量も自分で管理しなきゃいけなくなるし。



 W5500のSPIは基本的にCSをトグルして可変長(VDM; Variable Length Data Mode)で転送するけど、固定長(N=1,2,4、FDM; Fixed Length Data Mode)の場合はCSをトグルしなくても連続してデータを送ることができる。アドレスが離れた場所に8bit,16bit,32bitのデータを書いたり、同じアドレスに連続してデータを書いたりしたい場合は、FDMで転送するとCSトグル分の時間を省略できる。W5500のデータシートではCS Highの最小時間は30nsだから、無駄になるような時間でもないけど。

 W5500の場合、異なる番地に連続して値を書き込みたいという用途はさほど多くない。例えば宛先のIPアドレスとポートは連続した場所に配置されているから、まとめて6バイト転送(VDM)を行えばいい。強いて言えば、バンクを超えた場所(別のソケット)に対してまとめて読み書きしたい場合、とか? そんな使い方が必要になる状況も思いつかないけど。

 同じアドレスに書き込む用途は、例えばソケットにコマンドを送る場合が考えられる。例えばあらかじめ送るデータをTX Bufferに書いておいて、OPEN, SEND, CLOSEのコマンドを連続して送る、とか。

 今回の場合、ソフトSPIなのでクロックレートが極端に遅いので、1バイト転送(ヘッダ含めて4バイト/コマンド)に1ms程度かかる。このくらいの速度なら、OPEN, SEND, CLOSEを並べても問題なく送信できるようだ。UDPで送ったデータも正しく受信側で受け取れている(今回は5バイト転送)。10Mbpsなら1msあれば1万bitを送れるから、数バイト程度なら余裕で送れる。

 SPIクロックレートが20MHzとか50MHzとかで、コマンド間隔がマイクロ秒程度まで狭くなると厳しそうな気もするけど、とはいえSENDを打ってからすぐに転送が始まって、CLOSEを受けても先に送ってるパケットを出し切ってから閉じるだろうし。

 あとは、書き込みコマンドと読み込みコマンドを連続して出せる場合がある、みたいな利点もあるか。何に使うかわからないけど。SENDコマンドを打ったあとでInterruptを読んで、最速で送信が終わればSEND_OKが得られる、とか?



 試しにDHCP discoverを送信。offerが帰らないけど、Wiresharkで覗いたらちゃんと出てる。結論として、discoverを送ってからW5500をダンプするまでに0.1秒くらい待たせていたのを、もっと長く(2秒程度)待たせたらofferが見えるようになった。うちのルーター(DHCPサーバー)の特性なのか、DHCPとはこういうものなのか、応答が返るまでにちょっと時間がかかるっぽい。

 DHCPは貸し出そうとしているIPアドレスを使っている端末がないかどうかを確認するらしいから、それの待ち時間の分かも。WiFiとか多少レイテンシのある経路を考えると、応答がないと判断するまでには多少待つ必要があるし、それに応じてDHCP offerも時間がかかる、ということらしい(Wiresharkでdhcp or arpでフィルタすると、discoverとofferの間にarpが挟まる事がある。オファーを受けずに頻繁に探索するとarpを省略することがある?)。


 Wikipedia曰くDHCPクライアントもOfferを受けた段階でARPを出して、自分が見える範囲(DHCPサーバーが見えない可能性のある範囲)にも割当予定のIPアドレスを持った端末がいないかを確認する必要があるらしい。

 ただ、W5500からARPを出す方法がわからない。ぐぐってみると、TCPやUDPを出す前にARPを出すから、UDPタイムアウトをARPタイムアウトとして代用できるよ、みたいな話が出てくるんだけど、その場合って対象のIPアドレスが存在した場合は不要なUDP/TCPパケットを送信することになるはずなのだが、それってどうすればいいんだろう? ポート9にUDPで適当な長さのパケットを送ってみる、あたりが落とし所?


 Wiresharkは便利だけど、デスクトップPCはSDRのパケットが2系列流れているから、全部取るとあっという間にメモリ使用量が10GBを超える。/* デスクトップPC組んだときに後で増設しようと思って4スロットMBに2スロットしか積んでなくて、そのうち安くなるだろと思って放置してたらめちゃくちゃ高騰しやがって */

 ディスプレイフィルタでは[dhcp or arp]みたいに設定すればいいけど、キャプチャフィルタはもう少し複雑な設定が必要そう(少なくともDHCPは直接指定できない)。例えば[arp or (udp port 67 or 68)]みたいな感じにすれば良さそう? 


*


 SIGLENTのオシロ、起動するたびにIPアドレスが変わるのが謎いので、せっかくだし、Wiresharkでキャプチャ(2回分)

 DHCPはUnicastなのでDiscoverとRequestしか見えない。1回起動するたびにDiscoveryが3回出ているのが謎い。しかもトランザクションIDが2種類ある。


 W5500からDHCPのDiscover→Offer→Request→Packでやり取りすると、同じMACアドレスに対しては同じIPアドレスを割り当てようとしている気がする。

 SIGのオシロもMACアドレスは固定だから、同様に固定のIPアドレスが割り振られてもいいはずなんだけど、実際にはそうはならない。謎い。


 ユニキャストで通信されると何やってるかわからんな。リピーターハブを買えばいいんだろうし、amazonのレビューを見てもそういう用途で買ってる人が多いようだけど、しかしリピーターハブってわりといい値段するのな。高性能なはずのスイッチングハブのほうが安いなんて、量産効果すげーや。


 速度を固定してツイストペアを分岐してEthernetアダプタに突っ込んだりしたら、パケットをキャプチャできたりしないだろうか? 電力が半分になるけど、短距離の接続なら-6dB程度は問題ないだろうし。この方法だと片方向しか取れないけど、アダプタを2個使えばTXペアとRXペアを同時に監視できる。1000BASE-Tは双方向で使うからこの方法は使えないけど、10BASE-Tや100BASE-Tなら取れそう。この方法なら全二重のフルの帯域(20Mbps、200Mbps)も取れるはず。あるいは、半二重でいいなら、TX/RXペアを分岐したあとでアナログ的に加算してもいいはず。


***


 ArduinoでPORTD |= bit1;とかPORTD &= ~bit2;は許されるのに、PORTD = PORTD & ~bit2 | bit1;とかは許されないの謎い。エラーメッセージがno match for 'operator&'とかだから、PORTDとかってメモリマップドで直接触るわけじゃなくて、クラスでラップしてるらしい。

 PORTB&=1;とかやると読み出し、ビット操作、書き込みで遅そうだけど、パルス幅を測ってみるとちゃんと65nsあたりに見えるから、たぶんうまいことOUTSETとかOUTCLRに展開してるんだと思う。だからPORTB=PORTB&~1|2;みたいな操作ができない。

 あと、GPIOから読みたい場合、例えばPINDで8bitを読める、という説明があるんだけど、少なくともうちの環境だとコンパイルエラーになる。Google AI曰くVPORTB.INで読めるよ、とのことだけど、これはATmega側のレジスタなので、ビットマスクに互換性がない。

 ATmega側にはPORTA...Fがあるけど、PORTB...DはArduinoが上書きしているから、ATmega側のレジスタを直接触ることができない。


 Arduino、公式ボードだけでも大量にあるし、互換ボードも含めればさらに増えるし、それぞれで低レベルな部分は互換性が無いし、ググって出てきた情報がどのボードのものかも分かりづらいし、細かいところを触ろうとするとやっぱり大変。

 かといって、今更STM32もなぁ…… 比較的ガッツリSTM32に触っていた頃は手癖でプロジェクトを作ってmakefileを設定してビルドして、とかできてたけど、触らなくなってかなり経つからSTM32+STM32CubeMX+gccとかはちょっと面倒。

 今の時代に小さいマイコンでちょっとした制御を素早くやりたいなら、RasPiPico系にC++開発環境を載せて、速度が不要ならMicroPythonを使って、みたいな感じが良いのかな?


***


 一旦方針転換して、大昔に買ったストリナのFT232Hボードを叩いて遊ぶ。

 ちょっと前にこのボードのVer.2が発売されて、ディスコン部品の変更のほか、オンボードでLDOが乗って、外に3.3Vを出せるようになった。手元にあるやつはVer.1なので、5V出力のみ。W5500みたいに3.3V電源が必要なやつを相手にしようとすると、やはりLDOが乗ってる方がありがたい。


 FTDIのMPSSEを使うと、対応している変換チップならI2CやSPIのような同期シリアルバスやパラレルバスの変換チップとして使うことができる。昔は結構面倒そうな感じだった気がするけど、最近はSPIとかI2Cはラッパーが追加されて簡単に使えるようになったっぽい。

 試しにVer_libMPSSEを叩いて、DLLバージョンが読めることを確認。libmpsseはダウンロードした1.0.8と一致するけど、libftd2xxは3.2.21で、これはよくわからない。少なくとも、デバイスマネージャーで見えるFT232Hのドライババージョンとは一致しない。ググってもこの数値は出てこない。頭にlibとついているから、SPI/I2Cラッパーの下、ドライバの上の部分なのかも。

 続いてSpiGetNumberOfChannelsを叩いてみる。接続したFT232Hが認識されず、channelsが0固定で出てくる。……なんのことはない、FT232HをTeraTermで開いていたのが原因。閉じたら1が帰った。

 続けてSPI_GetChannelInfoでデバイスの情報を取得。DescriptionはASCII文字列(64bytes)だけど、SerialNumber(16byte)はバイナリっぽい。なんの数値かよくわからん。シリアルというくらいだから特に意味はないんだろうけど。

 SPI_OpenChannelとSPI_CloseChannelも、たぶん動作。

 この手の処理(DLL周り)、いい感じに実装する方法がいまいちよくわからん。ハンドルはnintで持つけど、nint剥き出しで取り扱うのも面倒だからクラスでラップしたいし、usingで閉じれるように関数の戻り値でインスタンスを返したいけど、開けなかったときは例外を投げるかnullを返すか、とか、いろいろ。if using(var dev = new Device()) { 正常系 } else { 異常系 }みたいな構文が欲しい。devが非nullのときはifブロックに入って、ブロックから出るときはusingを呼んで、devがnullな場合はelseブロックを処理して、みたいな。結局using var dev = new Device(); if (dev is not null) { } else { }で書くのと同じだから1行減るかどうか程度の違いでしかないけど。あとは変数のスコープの違いもあるけど。

 あとは、列挙型の持ち方も。readonly record structで定義しておくとToStringが自動的に実装されるからデバッグが楽だけど、当然書き換えができない。


 ここまでは順調だったんだけど、SPI_InitChannelでハングアップして進まなくなってしまった。色々試して、LatencyTimerに値を設定すると動作することが判明。ヘッダの定義には「value in milliseconds, maximum value shuld be <= 255」としか書いてなくて、8bit型だから「そりゃそうだろ」というような説明なんだけど、原因がわかってからフォルダ内でLatencyTimerに関する説明を探してみると、release-notes.txtの一番上のLimitationsの中に「LatencyTimer shuld be grater than 0 for FT232H」とそのものズバリの指示が書いてあった(FT232Hか否かはGetChannelInfoで見れるから、必要に応じて最小値の分岐もできる)。

 FT232HにはPORTDが8本あって、SPIはSCK, MOSI, MISOの3系統が必要なので、残り5本からCSが選べる。ここで選んだCSは明示的に出力に設定してやらないといけない(SCK, DO, DIはうまいことマスクしてくれる)。CSの論理も指定できるので、HでEnableになるシリアルデバイスを制御したりにも使える。

 SPI_InitChannelで渡すパラメータを、SPI_ChangeCS関数で渡すこともできる。CSは少なくとも5本使えるから、5個程度のSPIデバイス(CS論理が反転しているものも含む)を接続することができる。

 あとは、パラメータが問題ない場合でも、まれにInitでハングアップすることがある。そういう場合はデバイスの挿抜でハードウェアをリセットすれば解決する場合がある。


 データの転送はSPI_Read, SPI_Write, SPI_ReadWriteがあって、おおむね期待通りの動作をする。これらの関数に渡すオプションでCSを操作できて、例えばbit1を立てれば開始時にCSをアサートするし、bit2を立てれば終了時にCSをネゲートする。それぞれ0なら何もしないから、10バイト書いたあとに10バイト読むがその間はCSをアサートし続ける必要があって、転送が終わったらネゲートしたあとにさらに2バイト送らなきゃいけない、みたいなシーケンスも、問題なく要求できる。

 あとは、バイト数でなくビット数で転送数を指示するモードもあるらしい。オクテット単位でなく、中途半端なクロック数でも送れそう?(未確認)

 ただ、SPI_ReadWriteがなんか変な気がする。送信バッファが、最初にゼロ埋めされた8bitが出て、続けて指定したバッファが(つまり1バイトずれて)出る。受信側はおそらく問題ない(ループバックさせれば正しく1バイトずれた結果が得られる)。同じような操作(GCHandle/Dllimport)でSPI_Writeを呼べば問題ないから、たぶんReadWriteのバグだと思う。SPIで全二重が必要な状況はさほど多くはないけど、皆無と言い切れるわけではないので、ちゃんと使おうとすると困りそう。あと、読み書きをWrite/Readで分割して半二重で頑張るにしても、コマンドを分割するとその分多少のレイテンシが増えるし。


 面白い機能としては、SPI_IsBusyという関数があって、クロックの操作無しにMISOを読むことができる。例えばコマンドを送ると処理中はMISOがLowで、処理が終わったらMISOをHighに上げる、みたいなデバイスを監視することを想定している(もちろん逆も可)。ただ、SPI_IsBusyを呼んだ場合、CSのトグル操作(アサート&ネゲート)が挟まる。なので、一旦デアサートされるとMISOにビジー状態を出力しないようなデバイスを使うことは基本的にできない。

 もしCSのトグル無しにビジーチェックを行いたい場合は、CSのネゲートは省略したWriteで処理を指示し、Write後に一旦CSをChangeCSで別のピンに変更したうえで、IsBusyでポーリングして、ビジーが終わったら再びCSを戻して、SPI_ToggleCSでデアサートする(あるいは0バイトの書き込みでデアサートだけさせる、あるいはIsBusyで解放する)、みたいな処理は可能。

 ただし変更先のCSがジタバタするのと、それに接続されているデバイスがMISOへ出力して競合するので、この用途で使うCSはNCとしておく必要がある。MPSSEにはCSが5本あるから、こういう使い方をする場合はデバイスは4個までしか接続できない。


 SPI用の端子とは別に、GPIOが8本あって、任意に入出力として使うことができる。デバイスの割り込みピンを読んだりに使える(あくまでもアプリケーション側からポーリングして8bitバスを読む必要があるが)。書き込み時はDirも渡さなきゃいけないので、このあたりは適当なラッパーを作ると良さそう。どうせハンドルを持つクラスで隠すだろうしな。

 GPIOをCSとして使うことも可能ではあるけど、操作が煩雑になる欠点はある。あるいは、3to8デコーダとかを外付けして、デコーダのEnable端子にCSを接続して、みたいなことをすればバンクを切り替える感じでデバイスを大量にぶら下げることもできる。あまり多く接続するとSPIバスの負荷が大きくなるけど。

 結局、SPIデバイスを4,5個つないで10MHzくらいで使うのが安心かな。



 SPIとGPIOを操作するサンプル

 CS5本に対して、1本目はWrite, Read, ReadWriteを8バイトずつ、2-5本はWriteを8バイトずつ、その後、GPIO8本に対して32回のトグル操作。

 Writeの前とReadの後にちょっと時間がかかってるっぽい。その割にReadWriteの前はほとんど待ち時間がないのが謎い。それにReadWriteの後が長すぎるのも。


 GPIOは32回のトグルで1.54ms程度なので、1.54ms/31=49.7us程度と、ほぼ50us毎に操作ができる(矩形波を出して10kHz)。ジッタが大きいのはWindowsだししょうがないと思う。むしろ非RTOSでマイクロ秒程度の操作ができることのほうが驚き。コンテキストスイッチがなければそれなりに早いだろうけど、とはいえドライバ周りとかもレイテンシあるだろうに。USB HSのポーリング間隔って8kHzのはずだけど、最短27us(逆数で37k)でトグルってどうやってんだ。



 VCPで開いている場合はGetNumChannelsから見えなくなるけど、OpenChannelでMPSSEとして開いている場合はGetNumChannelsから見えたままになる。例えばGetNumChで1が得られて、OpenChannel(0)で開いた場合、再度(or別のアプリから?)GetNumChで取ると1が帰るが、index:0で開こうとすると、エラーが返る。

 どうせOpenChannelで開いて正常orエラーで判断するしかないなら、GetNumChannelsを呼ぶ必要性はよくわからん。

 しいて言えば、GetChannelInfoでデバイスのハンドルが得られるから、MPSSEとして開いているかは確認できるので、GetNumChannelsでデバイス数を得て、それぞれにGetChannelInfoで使用中かどうかを確認して、未使用なMPSSEを使う、みたいなことは考えられるか。あるいは、GetChannelInfoでシリアル番号を読んで特定のデバイスを選択するとか。

 他のアプリが開いているデバイスでもハンドルが取れるのかは未確認。それが取れたら結構変な使い方ができるけど、リソースの競合とかも怖いしなぁ。



 I2Cモードも試しに叩いてみたけど、結構クセが強そう。SPIモードのSCKがSCLになるのは期待通りだけど、SDAはMOSIで書いてMISOで読む感じになる。MOSIとMISOを短絡しなきゃいけないので、SPIとI2Cを切り替えながら使うような用途には不向き。そんな使い方したいかどうかは別として。あるいは、GPIOで制御信号を出してフォトカプラとかでつないでもいいのかもしれないけど。

 クロックレートは任意の数値を設定できるが、ヘッダにはよく使う速度として100kbps、400kbps、1Mbps、3.4Mbpsが定義してある。

 あと、Read/Writeのオプションが結構複雑で、うまいこと設定しないと正しく動作しないっぽい。なんとなく正しく動いていそうなパラメータはあるけど、本当にこれでいいのかはわからない。スタート/ストップコンディションの有無とかアドレスのスキップとか、色々オプションも設定できる。不要な場合を除いてStart/Stopは明示しておけばとりあえず大丈夫かな? あとはFAST_TRANSFER_BYTEもあるとよし。

 細かいところだと、Readで得られる転送済みバイト数が、バイト数ではなくビット数で帰ってる気がする。


 I2Cで1バイト書き込みの拡大

 3.3V系で4.7kΩ、100kbps。初期化オプションに2を指定している(HiZ/Lowモード)。


 I2CはSPIに比べてコマンドを出せる周期が低い感じ。レジスタを読む場合、書き込みと読み込みを個別にやらなきゃいけないので、その間少し時間がかかる。


 試しにTSYS01(大昔に何かで使った予備)を試してたんだけど、なぜかリードでアドレスを指定したときにNACKが頻発することがあって、うまく通信できなかった。結局、Resetコマンドのあとに10ms程度の待ち時間を入れて解決(Windowsが管理しているから25ms程度待ってるけど)。データシートにはそれらしいことは書いていないけど、Reset後に立ち上がるまで少し待たないとだめらしい。うまく動いたときは、もしかしたらOSやFT232の遅延でいい感じに時間が経っていたのかも。

 うまく使えれば妥当そうな値が読めるので、多少の事に使うなら可能ではありそう。



 試しにI2C High-Speed mode対応のデバイスを接続


 同じく3.3V系、4.7kΩ、100kbps/3Mbps。

 先に100kbps/ODでデバイス04h Wを呼び出して対応デバイスをHsへ移行させて、その後にクロックを3Mbps/PPへ変更してからSrに続けてデバイスのアドレスを指示し、レジスタを指示、さらにSrとアドレス、2バイト読み出し、というシーケンス。/* Hs移行指示は04h Wを使っているけど、これは予約されているので、本来は04h Rや05h W等を使う必要がある */

 明らかにドライブ能力が足りていないので、オシロでは閾値を任意に設定できるから正しい値が読めているけど、ロジアナやFT232Hでは正しい値が読めない。

 ちなみに、Sm/FmからHsへの移行指示を省略していきなり3Mbpsでデバイスアドレスを送ると、アドレスNACKが帰るが、Hs移行指示を出してからデバイスアドレスを送れば正しくACKが出るから、デバイス側のHsへの移行は正しく行われているはず。

 NXP UM10204を眺めてみた感じ、Hsでプルアップを強化するのはコントローラーの責任であって、通常時(Sm/Fm)は通常のプルアップ抵抗オンリーだが、Hsに切り替えるコマンドを出した時点でコントローラーは電流源をONにする必要があるらしい。ただ、この図ではあくまでもSCLに対して電流源を追加するというような書き方にしか見えず、SDA側は通常通りのような気がする。データラインはどうするのがいいんだろう?

 おそらくFT232Hには電流源を追加するような機能はないので、適切なHsコントローラーとして使うことはできないと思う。どうしても必要なら、FT232HのGPIOに定電流ダイオードをつけておいて、Hsに切り替えた時点でGPIOもトグルして、SCLとSDAをそれで引くという手はあるけど。

 あと、Sm/FsからHsへ切り替えるためにはいちいちI2C_Initを呼んでクロックを切り替える必要があるが、それに0.2秒弱かかる。よほど大量のデータをやり取りするのでもなければ、Fsで使ったほうが早いと思う。



 SPIでもTSYS01に接続

 ちゃんと読める。SPIの場合はビジーを取れるので、リセット後の2ms程度やADCの8ms程度も適切に待てる(A7:灰色のジタバタしているのがCS退避先)。

 クロックは10MHzで使用(TSYSは20MHzまで)。ちゃんと速度は出るけど、その分スカスカに見える。



 libmpsse、まだまだ開発中という感じが拭えない気はする。仕事で使えるかというと、ちょっと怪しそう。どうしてもPCとSPI/I2Cのブリッジが必要なら、FT232HをUARTで使ってその下に適当なマイコンを挟んだりして、テキストベースでコマンドを打って必要に応じてバイナリデータを交換して、みたいな感じのプロトコルを作ったほうが安心できそう。マイコンをHIDでPCに直結する手もあるけど、その場合はたいていFSまでだろうから、帯域幅が厳しい。手軽にやるならやはり232H経由のコマンドが楽そう。


***


 乱数発生器を内蔵した小さなチップって無いものかな、と思って軽くググってみたけど、あんまりなさそう? 電源ONで常時1Mbps程度で乱数を作って、十分に長いサイクルで予測が難しく、起動時に確実に乱数が出るようなしくみを持っているもの。

 LFSRの幅が100bitとかはちょっと計算が重そうではあるけど、数十Mspsとかであれば最近の半導体なら流してくれないかな。例えば100bitのLFSRを適当な頻度(数秒に1回程度?)でFeRAMとかに保存して、次回起動時はそこから再開して、工場出荷時に適当な初期値を書いておいて、みたいな感じで、乱数はSPIとかI2Cで好きに読むことができるような感じで。

 ある程度強度のある乱数が欲しい用途って、暗号化とかセキュリティの分野だから、大抵はそういうモジュールにTRNGも入っている印象。外付けでそういうのが必要な用途ってあんまりなさそう。

 マイコンにFeRAM的な長寿命のNVRが乗ってるなら、それで32bit程度のLFSRを作って必要なときだけ生成すれば、予測不能性が不要ならそれで十分だろうしな。FeRAMでなくても、32bit程度ならバッテリバックアップドメインの小さいRAMにも入るだろうし、ある程度綺麗な乱数が必要な用途ならRTC用の電池とかも積んでるだろうし。


***


 いよいよRasPi Picoに手を出すかー、と思ってamazonでポチってみたら、明らかにRSコンポーネンツのパッケージに入った基板が届いた。RSで620円で売ってるやつがamazonで1400円かぁ…… 送料含めてもRSで買ったほうがだいぶ安いんだな。でもRSはクレカがないと注文できないので。社会的な信用がない人間はこういうところで損が目に見えるな。

 このRSの袋が正規品なのであれば、中身も正規品と考えて妥当なはずだが……


 SPIのブリッジにArduino Nanoを使うよりRasPi Picoを使うべきじゃねと思ってポチったけど、FT232HでPCにSPIが直結できちゃったので、SPIブリッジを自分で作る必要がなくなってしまった。。。



 買ったまま開封すらせずに積むのもあれなので、とりあえずVS Codeの拡張で開発環境を入れて、blinkをビルド。USBで接続してストレージにblink.uf2をコピー。コピーすると勝手にリセットされて走るが、ユーザープログラムが走っている間はストレージとして認識できなくなるから、プログラムを書き込みたい場合はBOOTSELを押しながらRUNを地絡してストレージとして再認識させなきゃいけない。

 書き込みの手順としては、リセットボタンを押してプログラムを止めてからBOOTSELを押してリセットボタンを離して、USBとして認識されたらコマンドプロンプト等でcopyコマンドで書き込む、みたいな感じで、STM32F4のUSB DFUと同じような手間で使える。ただしRaspberry Pi Picoはオンボードのリセットスイッチが無いので、どうにか頑張るしかない。

 Picoを2枚買いして1枚をターゲットボード、1枚をデバッグアダプタとして使って、開発環境からデバッガで書き込んで走らせるほうが楽そう。この場合はデバッグ端子を接続する方法を考える必要があるけど。

 STBee Miniってオンボードでリセットスイッチやブートスイッチがついてて、買ったらそのままLチカできるしボタン入力も試せるから便利なのよな。スイッチが小さくて押しづらいというのはあるけど。


 BOOTSELはブート用のFlash ROM(QSPI)のSSにアクティブLowで接続されている。通常はプルアップされていて、RP2040が起動したときにSSがHighならFlash ROMから起動するが、SSがLowならRP内蔵ROMからUSB MSCを起動する、という感じになるらしい。

 ユーザープログラムからBOOTSELを読むことも可能だが、このピンはQSPIのSSだから、BOOTSELを押している間はFlash ROMからのプログラムを実行することができないので、普段使いしていいものでもなさそう。

 そのためか、BOOTSELはRasPiPicoの外部には引き出すことができない(クロックほどではないにしても、ある程度狭いパルスを通すから、変に引き出してトラブル起こされても困るからってのもあるだろうけど)。なので、外部にリセットスイッチとBOOTSELスイッチを追加して、ボタンを2個押してUSB MSCを起動する、みたいなことができない。手動でUSBを起動するなら外付けのリセットスイッチとオンボードのBOOTSELを組み合わせるしかなさそうだ。

 BOOTSELを押せばFlashからのプログラムの読み出しが止まるから、基本的にユーザープログラムは停止するはず。というわけで、WDTを設定しておけば、BOOTSELを押せば勝手にリセットされて、USBが起動する。RAMから走らせるプログラムでWDTをリセットしながら無限ループさせたりしていると機能しないけど、そういう状況を除けば、おそらくRasPiPicoを単体で使うときに、一番楽にプログラムを書き込む方法はこれだと思う。(2026/01/15)

 自分でcopy hoge.uf2 f:\とか叩く手間はあるけど、RasPiPicoのMSCは2E8A:0003として見えるから、これを検出したらファイルをコピーするスクリプトを書くとか、あるいは指定したパスで単に1秒毎にコピーを試みて、ドライブが認識されていなければ単にコピーに失敗するとか、色々工夫は考えられる。BOOTSELボタンを押したら勝手にプログラムが転送されてそれが走る、みたいなことはできるはず。

 RPには命令キャッシュ的なXIPという機能があるらしくて、こいつには16kの領域があるらしいので、それを有効にした場合はBOOTSELでQSPIを止めても小さなプログラムなら走り続けそうだけども。ぐぐってみるとXIPはデフォルトでONらしい。じゃあなんでBOOTSELで止まるんだ……



 とりあえず、Lチカは確認できたし、sleep_msの引数を変えれば周期も変わるから、開発環境も含めてそれなりに正しく動いているはず。

 VS Codeに拡張1個(+自動で入る3個)を入れるだけで使える開発環境。めちゃくちゃ簡単だなー。



追記:2026/01/15

 上述のWDTとBOOTSELでリセットするのはおそらく正常に動いていなかったので、とりあえず取り消しておく。


***


 C#でbyte hoge=(int)1;みたいな定数のダウンキャストで、キャスト先の範囲に収まる場合はエラーにならないんだな。列挙型も定数なので溢れなければ暗黙的に変換できる。一旦int型に明示的にキャストする必要はあるけど、例えばenum Hoge{foo=0x0001,bar=0x0100}があってbyte value=(int)Hoge.foo;は許可されるけど、byte value=(int)Hoge.bar;はエラーになる。byte value=(byte)Hoge.bar;もエラーになる(無理やり通すならuncheckedで囲む必要がある)。


2025年12月31日水曜日

小ネタ





 三菱電機のワイヤーレーザー金属3Dプリンタ


 三菱電機って切削機は作ってたっけ? たぶん作ってないと思うんだけど。工作機械メーカーが作る3Dプリンタは後加工も含めて一貫して処理できるようなシステムを考えていて、特に松浦なんかは金型用の比較的小規模なマシンとはいえ、積層と切削を交互にできるから工具を突っ込めないような場所も高い面精度で造形できたりするわけだけど、三菱電機はそのあたりがちょっと不利そう。

 まあ、DMGの機械も1台で切削も付加もできるようなやつもあるけど、その分機械1台を占有する時間が長くなるから、例えばスピンドルの稼働率は悪くなるわけだし。切削と付加は機械を分けて、段取りの手間は自動化で頑張って、全体で最適化して低コスト化して、みたいな方向もありだろうしな。



 マキノのレーザー加工機


 水の層流の全反射を使って光ファイバーみたいにレーザーを細いビームで送るので、加工部がテーパー状にならないし、切り屑の除去や冷却にも効果的。ヒュームが出ないのも良さそう。

 Nd:YAGの基本波1umは水の透過性が悪いので、第2高調波の緑を使っているのが特徴的な気がする。レーザー加工機で緑ってあまり見かけないような。赤外をよく吸収するワークなら赤外だし、銅みたいに長波長の反射率が高い材料は青色を使うし。




 スマホで撮ったデータをFramework expansion cardに転送すればそのままPCに挿せるから便利だよ、とか。そんなの普通のUSBメモリだって同じだろうよ、というような気はするけどな。


 とはいえ、Frameworkの拡張カードって色々使えて便利だよな。Type-C to HDMIアダプタとか、SDカードリーダーとか、ネットワークアダプタとか、一通り揃ってるし。

 Framework拡張カード用のUSBハブとかあっても面白そう。好きにインターフェースできるし、そこから拡張カードを外してスマホやPCに直結してアダプタとして使うこともできるし。結局Frameworkの拡張カードって単なるUSBアダプタなわけだし、USBハブに挿して非Frameworkマシンでも使えるようなやつがあっても良さそうだが。



 H3打ち上げ失敗 機体と人工衛星 大気圏に突入した可能性 | NHKニュース

 どこに落ちたんだろう。トランスポンダってNECだよね? 回収して再利用しようぜ。/* 昔のNECの衛星搭載機器は打上げに失敗したロケットから回収して通電したら動作したというネタ */


 なんか思ってたより大事っぽい感じで大変そうだなー。

 仮にフェアリングだとすると、W用のヤツを……とも思いつつ、フェアリングってロケットの中ではオーダーメイド(カスタマイズ)が多いはずだけど、発注してすぐ作ってくれるものなんだろうか。専業メーカーならなるはやで作業してくれるんかな?



 From Manufacturing to Testing: 2025 Year-End Recap - YouTube

 デジタルコックピット周りの説明で左側のPFDの後ろにおいてある白い板状のやつ、Starlink miniのアンテナに見えなくもない気がするけど、どうなんだろ。最初からアビオ系に組み込むにしたってそんな場所に置くかなぁという気もするし。



 個人向け金属製品製造サービス、図面不要で1点からのオーダーに対応:メカ設計ニュース - MONOist



 前回「名前とかどうでもいいだろ」とか言ったけど、DIY系YouTuberがcircuit boardのことを「基盤」と書いてるのを見ると「おまえその上に倉庫でも建てる気か!?」とか思うし、やっぱり名前は大事だなって。



 プレイヤーになりすましたAIを見分けるゲーム、素数テストとかそういう数学系のテストって通じるんだろうか? それとも素数やフィボナッチ数みたいな有名な数列はうまいこと対応するんだろうか? ちょっと性能の良い生成AI程度なら簡単な数列は正しく返せるだろうしなぁ。セキュアな情報、少なくともゲーム内で交わしていない鍵、例えばプレイヤーの誕生日とかを含めた非対称鍵みたいなものを用意して…… なんか普通のセキュリティと同じような感じだ。

 SFで素数テストをやるのはわりと定番のネタだけど、少なくとも現代技術レベルの地球のAIでも正しく回答できるとなると、知性の判定は難しそうだよなぁ。知性とは何か、知性をどうやって判断するか、だけでSFのネタになるし、現実の世界の話になっているし。



 Steam:ISS Simulator

 Ver1.3.0版公開。ライティングの調整、操作モードの追加、現在地(モジュール名)の表示、負荷軽減、バグ修正、パフォーマンス改善、だそう。

 試しに遊んでみたけど、前より重くなってる気がする。RTX3060でFHDだとLow設定じゃないと満足に動作しない。

 操作モードは「プロモード」が追加。視点操作のヨーイングがローリングに変わる。えーっと、ヨーはどこにやったの??? 宇宙ステーションって基本的に上下方向が厳密に定められているから、上下方向は固定のほうが「現実的」な気がする。サイエンスフィクション的な宇宙観でいうとプロモードのほうが近いかもしれないけど、あくまでもフィクション。

 謎な制御則や物理法則が現実と異なる点も相変わらず。

 特に評価するような内容は無いかな。


***


 24日に飛んでいた機体

 かすかに聞こえた音の感じからして双発以上のターボプロップっぽい気がする。

 Fr24機影なし、M-S無し。4種類のコードを送信(同一機と考えて振幅やドップラに矛盾なし)。M-Cに矛盾しない応答が一つ、M-1に矛盾しない応答が一つ。

 M-1らしい応答は明らかに数が少ない。質問自体が少ないんだろう(4倍や整数比から明らかにズレているのは謎い)。もう一つも応答数が少ないやつがあるから、これがM-2かな? 残りの応答が多いやつは民間空港のレーダからも質問されているM-3/A,Cだと思う。


*


 旭川空港が除雪か何かで閉鎖していたらしく、2機が1時間近く上空待機していた

 通常は右端(これは離陸機だけど)みたいにすぐに受信範囲からいなくなるけど、上空待機中はオーバルパターンで飛んでいるので連続的または間欠的に長時間受信できる。


***


 マブチ130をガルバノスキャナ的に使うやつ


 上画像が中立位置、0.3A程度まで不感帯、0.1V1A(0.1W)くらいを突っ込むと下画像くらいまで振れる。

 スプリングでセンターリターンするので、適当な電流で角度を指示できる。はず。大電力というほどではないにしても、そこそこ大きめの電流を制御しなきゃいけないけど。

 ヒス特性やLPF特性がかなり強そう。広帯域で使おうとするとパラメータ同定をしっかりやって適切なフィルタを通さないと厳しいかも。

 中央の不感帯が嫌な場合は片側だけ使えばいい。レンジが狭くなるけど、それほど広いレンジが必要ということもないだろうし。片側に振るだけなら両極性が不要だからHブリッジは不要でドライバ段も楽になるし。ただし双方向に電力を突っ込める場合、適当なフィルタを使えば逆方向に引っ張ることができる利点がある。


***


https://www.jstage.jst.go.jp/article/itej1978/41/2/41_2_130/_pdf

 1986年。テレビ放送にFAXを乗せる提案。

 FAX専用の副音声チャンネルを追加して両立性を図る。150秒(2.5分)を1フレームとして、1日を576分割し、1フレームでA4用紙1枚分を伝送できる。Y信号とC信号を映像ラインに同期して交互に(CはCBとCRを2倍速で1行で)送る。NTSCとある程度の互換性があるので、CRTに表示して確認したり、あるいはFAXとして印刷して保存したり、色々な使い方が想定できる。今のところ、既存の受像機とは両立性が悪い(副音声放送時にノイズを与える)が、対策方法はわかっているので今後のテレビで対応が進めば実用化が期待できる。

 郵政省と、現在のTBS系の会社で開発していたらしい。NHKではないけどテレビ放送の分野だからか、制御信号のデジタルデータの誤り訂正には短縮化差集合巡回符号を使っているらしい。

 例えば天気予報の番組で同時にFAXで天気図を放送してハードコピーを配布するみたいな用途で使えれば便利そうな気がするな。あるいは料理番組でレシピを放送するとか。でもこういう方式が普及したという話は聞かないので、普及しなかったんだろうな。考え方はISDB-Tのデータ放送に引き継がれてはいるけど。



 前にISDB-Tを復調していたときは「なんか動いてるからいいや」で放置していた差集合巡回符号の誤り訂正の実装、改めて調べ直したり、AIに聞いてみたり。放送用途メインで色々な場所で使われている割に、詳しい解説がほとんど出てこない。ただ、AIに聞いてみると、数学的な噛み砕いた解説とかを出してくれるので、参考にはなる。理解できるわけではないけど。

 誤り訂正のパリティチェック位置は(x^n+1)/G(x)で得られる。のだが、なんか釈然としない途中経過が必要になる。並びを上下反転させないとうまく動かない。変調するとき(冗長ビットを作るとき)と復調するとき(誤りを探すとき)で、ビットオーダーを逆にしないと動かない。

 行き当たりばったりのコードで確認しているから、整理すればもっと綺麗になるのかもしれないけど。


***


 気まぐれに安いW5500モジュールを購入。試しに適当なレジスタを読んでみると、ちゃんとデータシートと矛盾しない結果が得られるので、少なくとも読むのは正しく動いているはず。無害そうな場所に書き込んでみると、それも反映されるので、書き込みも正しく動いているはず。ただ、一部の書き込み可能なレジスタは、書き込んでも反映されない場所がある。


 試しにCommon RegisterのHardware AddressとIP Addressを適当に設定して、Socket n RegisterのモードをUDPに、ポートを適当に設定して、開いて、PC側から適当なパケットを送ってみたら、RX Received Sizeが増えて、Socket n RX Bufferをダンプするとそれらしい値が入っていた(32Kメモリは起動時はゴミデータが入っているっぽい)。

 RX Bufferに入っているデータは8バイトのヘッダと受信したデータで、ヘッダの内訳はIPv4アドレスとポート番号、データサイズで、ヘッダや受信したデータ含め送った内容(PC側のIPアドレスやその時のポート番号)とも一致する。


 Socket n RegisterのDestination IP AddressやPortは書き込んでも反映されない。TCPモードに設定してOpen, Connectを叩くと、設定したアドレスやポートに接続されて、Socket n Registerを読むと設定したアドレスやポート、それにハードウェアアドレスも表示されるから、おそらくDestination系は書き込みレジスタと読み出しレジスタが別れていて、TCPで接続しないと読み出せないんだと思う。一旦アドレス等が読めた場合は、切断してもそのまま読める。

 TCPで接続した場合、TX Bufferに書き込んだデータがそのまま送信される。DISCで切断してもFIN_WAITから進まない。これはC#で書いたサーバー側処理の関係のような気もするけど。


 UDPで送る場合も、TCPと同じように、TX Bufferに送りたいデータを書いて、TX Write Pointerを更新して、Destination IP Address / Portを設定して、SENDコマンドを叩く。RXみたいに、パケットの中にIPアドレスやポートを指定する必要はないようだ。UDPを受信する場合は誰が送ってくるかわからないけど、送信する場合は特定の相手を指定して(or 指定しないことを指定して)送信するわけだから、あくまでも宛先はUDP/TCPにかかわらずDestinationで指定するようだ。


 データシートはあくまでも電気的特性やレジスタマップが書いてあるだけだから、実際にTCPやUDPを投げるときにはどういうふうに操作する必要があるか、みたいなことはあまり書かれていない。とはいえ、そう変なものでもなく、多少の電子工作知識があれば既存のライブラリ無しでもどうにでもなりそう。まあ、既存のライブラリを使うのが常道だろうけども。


*


 W5500でUDP(SENDコマンド)を送ったときの、CSとTX+の波形。PHYの設定で10BASEに固定している。

 CSが立ち上がるより6.9us程度前からすでにプリアンブルが出ている(多分問題ないだろうけど、念の為にプリアンブルよりあとのパケット部分は隠している)。

 その際のSPIの波形

 数usというのは特に意味はなさそう。単にコマンドレジスタへSENDが書き込まれたら直ちに処理を開始して、内部遅延分が見えている、という感じっぽい。W5500はCSを使わないコマンド体系もあるから、CSでバスを解放するとかには関係なく、単にコマンドが書かれたら直ちに実行するんだろう。

 何回かパケットを送っても、CS立ち上がりタイミングとEthernet波形が出るタイミングはかなり安定していて、1us未満程度のジッタしかない。SPIはソフトSPIを書いているし、CSも同様にソフトで処理しているから、Arduino側のジッタの影響もあると思う(16MHzクロックだと1マイクロ秒の間に16命令しか走らない)。

 おそらく受信割り込みもハードウェアのステートマシンで処理してるだろうから、かなりタイミング精度は高いはず。うまいこと制御できれば、NTP程度なら十分な精度は出るかもしれないな。


 10BASE-TとかのBASEって、ベースバンド信号の意味なんだな。マンチェスタ符号化しているだけで、だいぶシンプルな変調方式だ。目で見てデコードしようとは思わないけど、適当なスクリプトさえ書けば100Mspsとかで取った波形からパケットを復調するのは容易にできそうだ。


*


 W5500を始めとしてW5x00系のEthernetチップは色々な使用例があって、例えばArduinoの標準ライブラリにも入っているし、ググればそれを使うための情報も多いんだろうけど、今回は試しに最低限の情報(主にデータシート)を参照して叩いている。これといってネットワーク化したいアイテムがあるわけでもないので、気分転換に叩いて遊んでいるという感じ。

 最近はPCで走るプログラムばっかり書いてて、PCの外で動くプログラムを書くのもかなり久しぶりだ。といっても、Arduino Nano EveryでUART-SPI変換をやって、結局C#でW5500を叩いているんだけど。テスト用のパケットとかもC#で作ってるしな。


 W5200にSTM32F1を重ねてパッケージングしたW7200という製品もあったらしい。DigiKeyには無いし、Mouserではディスコンで販売終了している。ストリナにはまだ在庫があるけど、評価ボードの在庫は無し。WIZnetのWebサイトでもW7200の情報は皆無で、ぐぐると忘れられたようにPDFのデータシートが出てくるだけ。そもそもW5200の製品情報自体が消えている。

 ぐぐってもあまり情報が出てこないので、だいぶニッチな製品だったんだろうな。もうちょっと時代が後だとSTM32F1にArduinoをポーティングして使う遊びが流行ってたから、ワンチップでArduinoが走って、パルストランスだけでEthernetに直結できるミニボードは面白がられたかもしれないけど。


2025年12月24日水曜日

小ネタ



 北海道宇宙レボリューション【後編】宇宙のまちづくりが進む大樹町に突撃!町長が語る衝撃の未来像&町の不動産を沸かせる意外な宇宙マネー事情とは! - YouTube







 PS2用のLinuxなんてのがあったのか。

 ぐぐってみると、今でもPS3にLinuxを入れて遊んでる人はちらほらいるらしいな。当然ながら、メジャーな遊び方ではないようだけど。



 GPS信号妨害で混乱 カーナビ6時間異常―中国・南京:時事ドットコム

 最近は配達とか相乗りとか、色々なところで位置情報が使われてるから、特に市民生活への影響が大きいわね。えてしてそういう用途はコストに敏感だから適切な代替手段も無いし、ユーザー側で頑張ってもらうのも難しいし。


 X インスタ SNS投稿写真 特定リスクに注意!生成AI画像解析ですぐに居場所が…投稿する時のポイントは? | NHKニュース | 生成AI・人工知能、IT・ネット、デジタル深掘り

 最近だとAIに画像を見せればすぐに場所を特定できるようになってきているから、市民生活に近い範囲だとGNSSに依存しない測位もできそうではあるけど。地図アプリでカメラにアクセス権渡して画像をサーバーに送って向こうで解析、とか、やろうと思えばできそう。やってほしいとは思えないけど。でもまあ中国ならそのうちどこかの企業がAIベースの測位サービスを始めて普及しそうだな。



 表舞台に上らなかった「世界初」のプロセッサ、MP944:マイクロプロセッサ懐古録(11)(1/2 ページ) - EDN Japan


 中東あたりを経由してF-14 CADCを密輸して分解する人とか出てこないかなー。ebayとかに出てるならともかく、戦闘機の部品を真面目に買おうとするといったいいくらかかるのか。。。よほどひどい壊れ方をしていない限りは、貴重な交換部品は売りたくないだろうしな。あるいは、すでに自国産のアビオに換装して捨ててる可能性もあるけど。

 米海軍のF-14ってどっかに残ってないんだろうか? あれだけ大量に廃棄したんだから部品の1つや2つどっかにありそうな気もするけど、正式に運用を終了した以上は交換部品の要求とかもないだろうし、適切に廃棄したんだろうか。

 Wikipediaを読む感じ、ちゃんと管理してあるのか、ずさんに管理しているのかはともかく、ある場所にはありそうな感じ。とはいえ、いちおうイランがF-14の運用を続けている間は、リバースエンジニアリングに繋がりそうなアビオ系の情報公開はされなさそうだな。相手は現物を持ってるんだからそれを調べればわかりそうではあるけど、だからといって積極的に出す理由にはならんし。



 米陸軍のLRHWダークイーグルは射程3500kmと新たに判明、炸薬量僅か13.6kgの意味を推定(JSF) - エキスパート - Yahoo!ニュース

 うちの近所を含めて、陸自駐屯地をいくつか挙げて射程範囲を示しているけど、これ陸自が買うみたいな話あったっけ? それとも米陸軍のMRBMないしIRBMを陸自駐屯地(or弾薬庫)に置くみたいな話? あるいは単に適当な地名をあげて範囲を示しているだけかもしれないけど。それなら中国側に中心をおいて「この円内の好きな場所に置けばここまで届くよ」とか書いたほうがわかりやすい気がするが。


 炸薬30lbってのもちょっと中途半端な気がしないでもないような。リーサリティエンハンサみたいに金属片を低速で打ち出すなら10kgも必要だろうか? かといってじゃあ例えば1kgでばらまきますとか言われても足りない気もするけど。あと、弾頭に対して極端に軽い金属片を撒いても、そんなのが効く目標にわざわざHGVを使うってのもなぁ。通常弾頭のCMでは突破が難しい場所に突っ込ませたいということだろうし、厳重に守られている場所なら柔らかいかも……という期待はあるのかもしれないけど。

 ペレットにしろロッドにしろ、大型の対空ミサイルであれば、航空機の与圧部に穴を開けるとか構造を切り裂くとか、あるいはエンジンにペレットが突っ込めばタービンを破壊できるみたいなことが期待できるだろうけど、それを対地目標に使って効果があるとも思いづらいのだが。ロッドで地上車両を切り裂くなら車両1両を認識して突っ込むシーカーが必要だし、ロッドで切れるなんて非装甲車両程度だろうから、それくらいなら誘導能力を100ftくらい改善させれば主力戦車を含めて大抵の車両には突っ込んで破壊できるけど、結局その程度の目標にHGVを使うだろうかという問題に回帰するし。

 硬目標に対しては純運動エネルギーで突っ込んで、もう少し柔らかい目標に対しては再突入体を炸薬で割って破片を散弾にして面的に使う、みたいなことは考えられそうだけど。V型成形炸薬みたいなものを内側に張り巡らせてあって、1個数百g程度の破片を1000個くらいばら撒いて、運動エネルギーで損害を与えるにしても、いくら超音速で突っ込んでくるとはいえ、非装甲車両が並んでいる場所に突っ込ませたって実際に被害を与えられるのは多くても数十~、多少の運動エネルギー程度なら修理して再稼働できると考えると、結局同じ問題に回帰するんだよな。

 航空機とか剥き出しの弾道ミサイルみたいに、修理コストが高い(容易に修理できない、破損したものを安易に使えない)目標が並んでいる場所ならそれなりに効果はあるかもしれないけど、戦争が起こりそうな状態になればすぐに分散させるだろうから、あんまり使いやすそうな気もしないし。防空システムで厳重に守られた大型の飛行場に並べられた航空機を多少なりともダメージを与えて猶予を稼ぐ、みたいな感じなら、使えないことがないことはないかな、といった感じ? 大型爆撃機で無誘導爆弾をばら撒くような事態も考えづらいけど、それこそCMやHGV、ASMの発射母機みたいに使うことを考えると、高価なHGVを何発か撃って大型機の稼働率を下げれば大型の対艦ミサイルが減って海軍が動きやすくなる、みたいなことはあり得るのかな。



 アメリカがトランプ級『戦艦』デファイアントの建造計画承認を発表、排水量3万5千トンのミサイル戦艦(JSF) - エキスパート - Yahoo!ニュース

 日本で「現代に戦艦(battleship)なんて存在しねーよ」論をやっている間に変なところから援護射撃が来たな…… 別に援護しようなんて気はサラサラないだろうし(タイミング的にも無関係だろうし)、どちらかといえば日本がイージス・システム搭載艦を作ろうとしているのを見て「アメリカのほうがデカいやつを作るべきだ」とか言い出したんだろうけど。それとも日本で戦艦云々が話題になって以降のここ数週間で「戦艦が欲しい!」とか言い出して絵を書かせたんだろうか? トランプならやりそうな気もしないでもないけど……

 Mk45を横並びに2門載せて副砲にするとかすさまじいね。ミリオタが妄想した最強兵器(攻撃力だけ考えて実用性ガン無視)って感じ。

 この大きさでMk41が128セル(タイコンデロガと同数)ってのはちょっと心もとない気もするけどなぁ。本格的な戦力投射には大型のVLSを使うにしても、Mk41にもトマホークとか色々乗せるだろうし。もうちょっと防空用のミサイルが欲しい感じはする。

 対空レーダーが中途半端に低い場所についているように見えるのもちょっと気になるな。なんで一番上に積まなかったんだろう? 重心が上がりすぎるとかちゃんと理由があるのか、あるいは。


 ろくに装甲もない(砲撃での殴り合いに耐えられない)こんな船は戦艦じゃねぇ、みたいな話は、あんまり意味ないような気がするけどなぁ。今の時代汎用駆逐艦だって遠洋に出たり海外派遣されたり色々使われているわけだし、フリゲートだって昔は駆逐艦よりも大きなものを指していたのに今では駆逐艦よりも小さなものを指すし、名前が指す対象なんて時代に応じていくらでも変わるものだと思うけど。巡洋艦(CG)より明らかにでかいから戦艦(BBG)と分けるのも無理ないと思うし。


 WWIIの戦艦が航空機の発達で役割を終えた、だから大型艦は航空攻撃等に脆弱だから無防備だ、みたいな話は、防空システムが発達すればある程度は覆せそうだけどな。どうせ小型艦(アーレイ・バーク級とか)だって防空戦闘は必要なわけだし、複数艦を分散させて個別に防空するくらいなら、敵の戦力を1箇所にあつめてまとめて防空戦闘する、みたいな考え方もできなくはない。まあ、相手からしても各個撃破する手間を省いて戦力を最大限投入できるようになるわけだけど。

 水上艦だと低空目標(対艦ミサイルとか)で攻撃されると困るけど、V-22を運用(&格納?)できるくらいの巨大艦なら、V-22にAESAモジュールをつけて空中哨戒機に仕立ててE-2D代わりに使ってもいいわけだし。

 過去のミサイルキャリア構想が実現しなかったのはコストを正当化(議会を説得)できるだけの材料を海軍が提供できなかったからだろうけど、止めるはずの大統領が最前線でゴリ押しするならワンちゃんあるかもしれんぞ。



 昨今の「プログラム次第でもう少しマシになったんじゃないか」という感じの話だと、シーケンス通りに立ち上がらない場合はアイドルモードで燃やせないか試す、みたいな機能はあっても良さそうな気がするな。アイドルモードで燃やすにしてもガスで押す必要はあるから内圧が抜けた場合に燃えるかどうかはともかくとしても。第1回が立ち上がらないならともかく、第2回燃焼ならすでにある程度の速度は持っているわけだし。第2段にダメージが有る時点で衛星側の健全性の問題もあるけど、それでだめでもどうせ近地点は低いから遠地点を上げたってそのうち落ちるだろうし。

 フルスペックの準天頂衛星システムの構築が遅れて「他国に依存しない測位」が遠のく、ってのは、沖縄に地上局を多数置いている時点で話半分だろうという気がするからなぁ。関東あたりに持ってこようとすると衛星側にだいぶ手を入れる必要があるだろうから数年で実現できるものでもないだろうし。いざとなれば南半球側の測位サービスは停止するとかになるのかもしれないけど。オーストラリアあたりにも地上局を置けば日本の南側がきな臭くなっても南半球でサービスを継続できるけど、他国に依存しない云々とは相性が悪そうだ。自国が依存しているわけじゃないからノーカン、の考え方もあるけど。



 JAXAのプレスキットの中のH-IIAの説明で「50機中6号機を除いてすべて成功し打上げ成功率は約98.0%」みたいな記述が出てきて、49/50=0.98だから「約」は不要なのでは?という気が。これが50号機の打上げ前なら「49機中48機が成功で打上げ成功率は約98.0%」は正しいんだけど。



 最近JAXAが大なり小なり関わっているゲームが何本か公開されているけど、どのくらい関わっているのか書いておいてほしいよなー。JAXAが関わっていると謳っているのに、物理法則を盛大に誤っているゲームとか、そうでなくても技術的に正確とは言い切れない描写とかを見かけたりするとな。。。



 わりと大きな音がした機体

 Fr24に機影無し、M-S有り。スコーク1200。インコヒーレントっぽい。近い場所を飛んだせいか、M-3/A,Cも振り切れてるし、M-Sもだいぶ強い。



 PoEでちょっとした電力(1Wとか、5Wとか)を簡単に得たいなと思って軽く調べてみたんだけど、PoEの受電って真面目にやるとだいぶ面倒なんだな。

 初期の仕様では2種類の給電方法を規定してあって、2ペアケーブルでデータと電力を流すのがAlt.A方式、4ペアケーブルでデータと電力を分離するのがAlt.B方式。給電側(PSE)はAlt.AとAlt.Bのどちらかに対応すればいいが、受電側は両方に対応する必要がある。さらに、イーサネットケーブルはストレートだけでなくクロスケーブルもあるから、極性が反転するのでダイオードブリッジも必要。受電側はAlt.AとAlt.Bの両方に対してダイオードブリッジが1個ずつ必要で、供給電圧は50V前後なので基本的にリニアレギュレータはNGで、高電圧を受けられるDCDCが必要。今でこそ高耐圧のDCDC Buckコンバータはそれなりの入手性があるけど、20年以上前だとかなり大変そうだ。

 en.wikipedia曰く、Alt.Aはクロスケーブルで極性が反転するからダイオードブリッジが必要だが、Alt.Bは極性が決まっているという書き方(暗にダイオードブリッジが不要と読める)だけど、現実には4ペアともクロスしているケーブルがあるから、結局Alt.Bもクロスケーブルが使われる可能性がある場合はダイオードブリッジが必要なはず。

 一番低コストに簡易PoE受電を行うなら、7,8ペアを基準(GND)にして、4,5ペアをダイオード1本で逆電圧保護、適当なDCDCで降圧、みたいな感じ? ただ、DCDCやディスクリートダイオードを入れるならダイオードブリッジぐらいケチるなよ、という気もする。ダイオードブリッジを1個入れるならもう1個もケチるなよ、という気もする。結局、フル機能のAlt.A/B両対応PDになる。


 受電回路はそれでいいとして、コネクタ側が大変そう。

 パルストランス内蔵コネクタの回路図を見てみると、ケーブル側の中点が出せないものとか、出せても75Ωで終端されているとか、そういう製品が多そう。物によっては予備ペアを短絡させてそれらをペアで引き出せるものもあるから、これならAlt.Bで使えるけど、物によってはそれらが75Ωで終端されているものもあって、これはPoEには使えない。

 少なくとも、秋月で取り扱っているパルストランス内臓のRJ-45は、中点はすべて75Ω終端かつケース内でGNDにAC結合かな(PoE対応のコネクタも売っているけど、在庫限りで残り13個)。

 かるくググった範囲だと、パルストランス内蔵PoE対応RJ-45コネクタって結構少なさそう。トランスレスのコネクタに外付けのトランスで中点を引き出すみたいな方法もあるけど、実装面積とかで色々と不便になりそう。

 市販のネットワーク機器でも、低価格な製品ではPoEの対応が進まないのって、このあたりにも原因があるのかな? かつてのPoE非対応なコネクタアセンブリが安価に生産されているから、PoEに対応するにはわざわざ高価格なコネクタを採用して、高耐圧なDCDCを追加して、みたいな感じで。


***


 OFDMのガードインターバル/サイクルプレフィックスの相関値、サンプルレートエラーだけでなく、ダウンコンバータの周波数エラーも含んでいるから、この位相だけでサンプルレートだけを抽出することはできない。



 パイロット信号を使用した等価処理で、切り出し窓がずれるとコンステレーションが小さくなる挙動がある。

 前方にガードインターバル/サイクルプレフィックスが付与されているから、窓が前にずれる場合は振幅方向には影響はないはず(複素平面の回転はある)。後方にはすぐに次のシンボル(GI)が来るから、切り出し窓が後ろにずれるとシンボル間干渉の影響が出始める。

 SISでパイロットの振幅が下がると、コンステレーションは膨らむ方向に影響があるはず。しかし実際には縮小している。不思議。可能性としては、パイロットの振幅が低下する以上に、データキャリアのSISによる縮小のほうが大きい、とかはありえるか。

 実際のところは有効シンボル長は8192(8.127Msps)とか10080(10Msps)とかだから、切り出し窓が10程度ずれたところで極端に大きな影響があるわけではない。とはいえ、QAM64みたいに振幅に敏感な変調方式だとちょっと気になる。

 前回フルセグを復調したときにコンステレーションの大きさが微妙にずれていた現象があったはずだけど、SISの問題だったのかも。



 1フレーム全キャリアのコンステレーション

 理想的とまでは言えないけど、それなりにまとまっている。

 だいぶ苦労したけど、チートしてTSが取れた。チートと言っても、数年前に自分が書いたソースコードから計算式を1個引っ張ってきた程度だけど。それ以外は、誤り訂正(巡回符号・畳み込み符号)以外はほとんど全部書き直したかな。やはり数年といえども書き方はだいぶ変わったので、より現代的(個人的)なコードになった。


 復調できなかったのは、時間インターリーブの遅延時間が誤っていたのが原因だった。時間インターリーブ長が不一致の場合、単純にバイト位置がズレるような挙動を示す。この際、エネルギー拡散を未解除の場合は同期ワード(47h)が誤った位置に見えることがある。一方、エネルギー拡散を解除した場合は同期ワードが見えなくなる。正しく復調できた場合、エネルギー拡散が未解除の場合はデータ部は乱雑なままだが、拡散を解除した場合はヌルパケットのFFh埋めで水平方向のパターンが見える。

 とりあえず、エネルギー拡散は解除せずに事を進めて、同期ワードが正しい位置(204バイトブロックの末尾)に見えるようになったらおそらく正しい、それ以外の場所に見えたら時間インターバルが間違っている、それも見えなければ別の場所が間違っている。同期ワードが正しい位置に見えたらエネルギー拡散を解除して、FFh埋めが見えればOK、みたいな感じで作業したほうが良さそう。

 先に部分受信だけ復調できて、これが動いてるからエネルギー拡散もOKだろう、とか思ってやってると、見えるはずのものも見えなくなる。


 R2でサンプリングしたデータの場合、S16C形式(4byte/サンプル)を使うはず。C#で処理する場合はComplex32で処理するのが楽。この場合は8byte/サンプルになる。OFDMを復調してコヒーレントモードで等価までできれば振幅を正規化できるから、浮動小数点のダイナミックレンジは不要になる。

 例えば80倍でスケーリングすれば-128 - +127のS8で-1.6 - +1.5875の範囲を表現できる。ISDB-TはI/Q軸で分離すればDBPSK系の±4/3(1.33...)が一番振幅が大きいから、分散を考えても多少の余裕を持って表現できる。分散が大きいとサチるけど、サチったところでDBPSKに振幅の意味はないから、問題ない。そんな事を言い始めるとQAM64を持てるギリギリまで拡大すればいいだろ、ということになるんだけど(正規化済みなのでパイロット信号の振幅情報は不要)。

 とにかく、S8C形式なら2byte/サンプルになる。ガードインターバルも捨てられるから8/9まで小さくなる。不要なキャリアも捨てるなら、5617/10080でさらに56%まで小さくなるから、S16C→S8Cと時間軸・周波数軸で不要なサンプルを削除する分で元の22%程度まで小さくなる。それでも元が40MB/sだから8.8MB/s程度にしかならないけど。

 キャリア1本ずつを保存するなら意味はないけど、WAVに合わせてU8Cで保存してもいい。実用的な意味はほとんど無いけど、後処理(後述)でテーブルから拾う時にオフセットを考えなくて済む。


 RS誤り訂正はZXingのやつを使って(だいぶ使いづらい。。。)、部分受信は誤り無し、フルセグはビット誤り率3.5e-4くらい。例えば188バイトのパケット2個に1ビットくらいの割合。RSパリティは16バイトだから少なくとも8bit/パケットの誤りは訂正できる。

 8bit正規化の形を使えばI/Q軸それぞれが-128 - +127の範囲になるから、オフセットすれば0 - 255の範囲になる。これでテーブルを引けば比較的軽い実行コストでビタビ軟判定ができる。コンステレーションは間隔2で配置されていて、それが/(42^0.5)でスケーリングされていて、正規化後に80倍するから、シンボル間距離は約25になるので、4.6bitくらいの拡張。そうやって復調してみると、RSビットエラー率は2.4e-5くらいまで下がって、誤り率が1桁以上改善する。軟判定の処理利得かなりでかいな。

 同様に部分受信(QPSK)も軟判定にしてみると、RSはBERゼロで変わらず、ビタビの推定誤り率は上昇(悪化)する。おそらく、硬判定の場合は象限だけ見ているからゼロイチに量子化できて、それで誤りが無いから最小の誤り率になるが、軟判定の場合は正しいコンステレーションの位置からずれたシンボルについては若干の誤りとして計測されるからだと思う。これは自作のビタビデコーダの特性もあるだろうし。おそらく隣の場所にまで飛ぶほど劣悪な条件で比較すれば、RS誤り率は改善すると思うけど、少なくとも正しい位置で見えている場合は硬判定のほうが数値の見かけ上は良くなる。あと、符号だけ見ればいいから、処理も比較的楽。C#の場合テーブルを引くと分岐が挟まるから、符号を見るほうが早い気がする(ストールしなければテーブルのほうが早い可能性はあるけど)。



 フレームごとに切り出し窓の位置・速度をグラフ化

 移動速度(左軸、サンプル/秒)、ウインドウズレ(右軸、サンプル)。

 ISI対策で10サンプルオフセットを狙っていて、クロックエラーで移動する分を吸収してのこぎり波状になる。クロックエラーは-4e-3sample/sec程度で、10Mspsなので、-0.4ppm程度かな。


 階層化レイヤー毎のビタビのエラー(任意の単位)とRS復号のビットエラー率

 Aビタビ(硬判定)は800ちょっとで理論値に張り付き、Bビタビ(軟判定)は1300程度で安定(理論値は1088)。レイヤAはビタビでエラー率(理論値との差)がゼロなのでRS復号もゼロに張り付いている。レイヤBは2e-5から3e-5程度で振動。188バイトあたり少なくとも8bitの誤りを訂正できるから、500e-5程度までは復元できるので、十分に低い誤り率で推移している。



 地震の時にサンプリングしたIQも復調

 中心部はだいぶ綺麗にコンスタレーションが出てる。ただ、周辺部のコンスタレーションは隣と繋がっているから、デマッピングエラーはありそう。実際、QAM64のRS BERは6e-5くらいある(先のBERもそうだけど、たぶん実際より92%くらいの値が出ているので、より正確にはさらに1割くらい高いはず)。17Mbps程度として6e-5なら1秒あたり1kbitくらい誤っている計算。

 このときはスクランブルが解除されていたので、TSをffmpegとかに投げてMP4とかに変換すればHDで再生できる。


 とりあえず、Airspy R2で広帯域のデジタル変調を受信できることは確認できたので一安心。ISDB-Tはパイロット信号が大量に入っているのでわりあい復調しやすい方ではあると思うけど。



 Visual Studioのソースコード内で書いた画像とかのパスにマウスオーバーするとプレビューする機能、結構前からあると思うけど、わりと邪魔な機能な気がする。VSがリソース(ファイル)にアクセスするから、外からアクセスできなくなる。ソースコードでパスを指定しているということは読むか書くかだけど、書きたい場合にVSが占有しているとブロックされる。そこそこ長い処理をやったあとでログを書き出そうとしてVSにブロックされて結果が全部飛ぶとか困るんだけど。

 ぐぐってもそれっぽい情報が出てこない。Copilotに聞いても的外れな回答が出てくる。どうやって切ればいいんだろう。



 低レベルな言語だと例えばfor(int bit=0x100;(bit>>=1)!=0;){...}みたいな処理はビットシフトした結果を分岐に使えて良さそうだな、みたいな雰囲気があるけど(実際はどうか知らないけど)、C#でもそういうのって効果あるんだろうか? それとも(CでもC#でも)for(int bit=0x80;bit!=0;bit>>=1){...}みたいに書いてもいい感じに最適化してくれるんだろうか? そんなところにこだわるよりもっと早くなる場所たくさんあるだろ、というツッコミは無視するとして。