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を単体で使うときに、一番楽にプログラムを書き込む方法はこれだと思う。

 自分で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個)を入れるだけで使える開発環境。めちゃくちゃ簡単だなー。


***


 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){...}みたいに書いてもいい感じに最適化してくれるんだろうか? そんなところにこだわるよりもっと早くなる場所たくさんあるだろ、というツッコミは無視するとして。


2025年12月17日水曜日

小ネタ












 この規模の機体にAIM-120はデカいなぁ。センターラインからオフセットしてあるから2発くらい載せられそうだけど、あるいはノーズギアを避けるためか。とはいえ1発だけじゃ使いづらいだろうし、やはり2発載せられるんだろうか?

 AIM-92を4発くらい載せたほうが良さそうな気もするけど、とはいえ気軽に前線に出せるほど安い機体でもないだろうし、後ろからランチャーとして使いたいのもわからんでもないけど、しかし2,3発程度だと心もとないというか。無人機なら工夫すればRCSも小さくなるだろうけど、現在のデザインだとちょっと大変そう。まあ、今のはコンセプト実証用だしな。

 理想的には120を底面に4発くらい埋め込んでRCSを下げつつランチャーとして使って、必要に応じて空中待機させたり、緊急で対空ミサイルが必要になったら滑走路端に待機させていたやつを上げたり、いろいろ使えそうではあるが。


 地上スタッフが見てるスマホ、テレメか何かを関係者向けにストリーミングしてるのかと思ったら、Webブラウザで表示したFlightradar24でターゲットドローンの軌跡を見ているらしくて。時代というか、お国柄というか。

 Fr24のプレイバックで見るとRAAFウーメラ基地の北西に当該ドローンが写ってることがあった。さすがにMQ-28Aは見当たらない(全期間確認したわけじゃないけど)。




 懐かしガジェット修理シム『リ・ストーリー: 思い出修理屋』発表。実在ゲーム機などを丁寧に分解修理、高価なパーツは“部品取り”でやりくり - AUTOMATON


 ストーリー無しで稀に客が来るようなモードも欲しいな。例えば実時間で30分くらいの間隔で客が来て、客が来ない間はプレイヤーはプレイヤーの作業をやっていて、ゲーム内客対応をするタイミングで自分の作業も一旦中断して少し休憩する、みたいな。いわゆるポモドーロタイマー的に使える機能。ゲーム内でゲームのデモ画面みたいなのを起動してBGM/VGBに使えたりとか。

/* ポモドーロタイマーって作業内容によりけりだから自分はあんまり合わない気がする。勉強とか執筆作業とか、完全に集中できる内容なら定期的な休憩のタイマーは良いだろうけど、遊びプログラミングとかで数分ごとにWebブラウザを開いてググるような作業だと、ブラウザを開いたタイミングでネットの海に遊びに出る気がする。まあ、だから自分は手が遅いんだろうけど */




 WSOとして乗るの? BF3みたいなクソゲーはやめてくれよ??

 空母がフィーチャーされているせいか、F/A-18しか出てこないな。前作はF-22でも空母で運用できたからな…… AC6やAC7ではF-16がデフォ機だったけど、今作ではF/A-18になるんかしら? F-16は最新型を購入機にするとかで。海軍機専用で空軍機は使えないということは無いと思うんだけど。



 A Pilot’s Guide to the HX50 Autopilot System - YouTube

 2軸または4軸のオートパイロットを搭載している。2軸はサイクリック操作を、4軸はそれに加えてコレクティブとペダル(ヨー)も。

 2軸はATTI HOLDみたいな感じかな。ある程度の前進速度があればヨーも安定するだろうし。

 あとは、緊急事態(特にパイロットの体調不良等)で最寄りの空港に緊急着陸するような機能もあるらしい。それと、エンジントラブルの際に自動的にコレクティブを下げて、オートローテーションの安全性を確保する機能も。

 他にも色々な機能があるらしい。ラジコンヘリからドローンみたいな進化の仕方をしてるな。将来的に追加で認証が得られれば自動操縦で飛ぶような機能も売ったりするんだろうか? でかいタッチパネルとかネットワーク機能とかも色々乗ってるし、地図で目的地を選んだらそこに飛んでいってくれるような機能は作れそうだが。



“JAXAと共同研究”リアル月面探索ゲーム『REAL MOON』Steamで無料配信開始 - AUTOMATON

 俺達は月に行ったらまず真っ先に物理法則を確認する。

 重箱ろうと思えばいろいろ気になるところはあるけど、30分とか1時間とか遊ぶくらいなら面白いんじゃないだろうか。



 ルンバのメーカー「アイロボット」連邦破産法第11条の適用申請 | NHKニュース | アメリカ、IT・ネット

 経営難の企業をamazonが買おうとしたらプライバシー云々を理由に規制当局に邪魔されて、結局中国企業に買われるの、はたから見てるとアホとしか言いようがないな。



「アサヒがファイアウォールではなくFAXに救われた事実を考えよ」――キンドリル、サイバーレジリエンスの重要性を強調(クラウド Watch) - Yahoo!ニュース

「日本を代表する大企業のひとつであるアサヒが、ファイアウォールではなくFAXマシンによって救われたという事実を考えてみてほしい。これは『Failure of Resilience』、つまり障害からの復旧力が欠如しているということだ」

 多少業務効率が悪くなったにしろFAXで最低限の事業を継続できてるなら、緊急の代替手段としてはそれでいいと思うけどな(もちろん必要なセキュリティは確保しておくのは大前提として)。サーバーで運用するITシステムとFAXってアーキテクチャが全く別物だから、どれだけ最悪を想定してもサーバーを攻撃されてFAXまで全損という事態は早々発生しないはずだし(FAXまでIP化してたりしたらともかくとして)。

 日本と海外では商習慣もそれを変えるためのコストも全く違うんだから、外資系企業の外人が笑顔で「世界基準に照らせば日本は遅れてるよ」といって自社のソリューションを売り込んでくるのはちょっと眉唾で聞いたほうがいいと思うな。外資のインテグレーターが日本でシステム開発を受注して炎上したりというのもあるし、日本の商習慣というのは海外から見ると異様だろうし、それは攻撃者側からしても同じだろうし。

 うがった見方をすれば、セキュリティ企業ってクラッカーからの攻撃がないと仕事にならないから、日本が「いざとなればFAXでいいよ」と言ってる間はセキュリティ企業も仕事にならないわけだし。



 米海軍がIFFのトラブルを放置&その装置を信頼した結果味方を誤射したとか聞くと、米軍君さぁ、って感じが。御自慢のモード5やデータリンクはどうなってるんだよ。

 トランスポンダの資料とか読むと「IFFは味方と確認できたものを表示するだけだから、IFFで味方と判定できないものに射撃するのは各自(シューター)の責任だよ」みたいな話が口を酸っぱく書いてあるけど、それがどれくらい実践されているかというと。。。

 それに、不具合のある機材を使い続けたのもな。艦長をはじめ指揮権者が把握して放置していたなら怠慢だし、把握していないなら無能だし。

 機材の修理・交換に金がかかるから、といったって、SM-2を1発無駄にして、もう1発で味方戦闘機を撃墜して、いったいいくら無駄にしたんだよ。



 USB Type-Aコネクタ、裏表が分かりづらいとかかさばるとか細々と問題はあるにしろ、デザイン性の高い記録媒体を作れるという点ではかなり優れてるよな。フロッピーディスクとかCDみたいに機能性だけで見た目が決まらない。

 今のところはType-Cでこういうスッキリしたデザインの製品はあまり見当たらないし、たとえType-Cでこういう製品が出たとしても、小さすぎてデザイン的に微妙な気がする。Type-Aはある程度体積のある半導体を入れるのにも十分な大きさだし、大きすぎもしない。

 キオクシアのU366(上画像の製品)、在庫限りと書いてあるからもう生産してないのかな? こういうデザイン好きなのになー。



 オフィス内での調理が電子レンジしか使えないやつ、火災云々とか匂いが残るとかいうより、火災報知器の誤作動のほうが怖そう。

 火災報知器対策ならビニールテントの仮設陰圧室とかを使って排気を窓から出すなりHEPA経由で部屋に出すなりすれば対策できそうだけど、偉い人に認めてもらうのが大変そうだな。絵面もかなり怪しいしな。まるで映画やゲームで出てくる薬物や生物兵器を作ってる現場みたいになりそう。



 ノートPCのバッテリ、amazonで型番を探すとバッテリ単体で売ってて、商品説明に「安心の日本メーカー」とか書いてるんだけど、会社名でググって出てくるチープなホームページによると単なる輸入代理店なんだよな。中国で探してきた安いバッテリーセルに自社のロゴだけ貼って売ってるんだろうけど、どのあたりが「安心」なんだろう? 炎上(物理)しても少なくとも文句を言う相手の日本法人がある、とか?


***


 Airspy R2の拡張端子の割当

 大抵のペリフェラルは必要な端子を満足していないから使用できない。実質的に使えるのはGPIO以外だとUARTが2組(片方はクロックがあるので同期可能、もう片方はDIRがあるので半二重可能)だけ。

 SPIやI2Sはクロックがない。CANはRXがあるからバスモニタ的に使うことはできて、ブロードキャストされるデータを受けることは可能だけど、TXが無いから積極的には使いづらい。

 Ethernet(RMII)もたぶんピンが足りない。RMIIが使えたとしても、20MB/sを流すなら100Mbじゃ足りないし、ARQに耐えられるRAMも無いから、リアルタイムにデータを取れるネットワークSDRアダプタとして使えるものじゃないけど、少なくともPoE1本で比較的離れた場所に配置したり、NTPやPTPでタイムスタンピングしたり、ネットワーク経由でコマンドを打ってUSB接続のストレージに記録したり、FTPでノンリアルタイム転送したりみたいなカスタムファームを作る余地はあったはずだが。


 クロック同期のUSARTを9bitで使ってTXをOD駆動してRXと直結してやれば、I2Cとして使えたりするんだろうか? 定常状態の管理が難しそうだけど、GPIOのモード設定である程度制御できるだろうし。試しにSTM32のUSARTの資料を見てみると、SPIモードとして使えるとは書いてあるけど、I2Cとして使えるとは書いてない。STMはわりとI2C多めだからな……

 LPCのUSARTもSPIとして使えるなら(使えないことは無いだろうし)、少なくともSPIバス1本とGPIO数本は使えるわけだから、その下に適当なブリッジを置けば色々追加できるだろうけど。SPIが使えるならI2CでもCANでもEthernetでもたいていのプロトコルに変換するチップは市販されているし。Ethernetとかで使うにはスループットが低めだけど。



 LPC4370のADCHS、データシートを斜め読みする感じ、800mVppの入力範囲に対して12bit全体が割り当てられているから、適正な電圧範囲を入力すれば、-2048から+2047まで、しっかりフルスイングするはず。しかし、実際にはRAWで見る感じではそれより早い段階で飽和しているように見える。

 ということは、このクランプはADC(LPC)側ではなく、R860側の問題? ただ、rtl-sdr.comに置いてあるR820Tのデータシートによると、IF Output Levelは1VppType, 2VppMaxだから、ADCHSの0.8Vppよりも広いはず。

 ただしR820Tの出力インピーダンスは2kΩある。ADCHSの入力インピーダンスがどの程度かわからないけど、STM32の通常のADCが数kΩ以下であることを考えると、それより早いADCHSはそれより低いインピーダンスのはずだから、R820Tの出力がだいぶん減衰している可能性はありそうな気がする。

 LPC4370のデータシートではADCの前にオペアンプで低インピーダンス化したりする回路が推奨されているけど、R2の基板の写真にはR860とLPC4370の間にはCR類しかないから、直接突っ込んでいるはず。

 ただ、その場合でも波形がクランプされるわけではなく、単に信号レベルが下がるだけのはずだから、ゲインを増やして中途半端な2箇所にピークが出る現象はまた別の原因がありそう。


 ドキュメントの探しやすさはNXPよりSTMのほうが優れている気がする。STM32は商品ページにドキュメント類の一覧があるし、製品を使う上で最低限必要なデータシートやリファレンスマニュアルはログインせずにダウンロードできる。NXPも製品に関連したドキュメントの一覧ページはあるけど、例えばユーザーガイド(レジスタマップ等はこれに書いてある)をダウンロードするにはアカウントを作る必要がある。STMも一部のドキュメントはアカウントが必要だけど、あくまでもtips的な内容であって、必ず読まなきゃいけないというドキュメントではない(たまに役に立つことが書いてあるから読むに越したことはないけど)。あと、日本語しか読めない日本人としては、STMのドキュメントは公式で日本語参考資料があるから読むのが楽なのがありがたい。


*


 方針を転換して、ISDB-Tの復調。

 とりあえず1フレーム約230ms分のコンスタレーション

 だいぶ広がってて汚い感じがする。

 ベランダにつけた小型のテレビアンテナをブースター経由で衛星放送とまとめてから部屋に引き込んで、スプリッタを通してDIGAに突っ込んで、DIGAからの出力をAirspy R2/SDR#でサンプリング。このアンテナ、スペックを確認したら4-5dB程度の利得しかないのな。適正なダイポールよりは多少マシだが……程度でしかない。ちゃんとしたテレビで受信するレベルなら支障はないけど、SDRで受信したりするにはちょっと弱いか。多少バラけてたほうが誤り訂正が効いてきて学習的な意味ではいいかもしれないけど。暖かくなったらもうちょっと利得のあるアンテナに交換したさあるな。

 RTL-SDR blog v3ドングルで受信したときはもっと綺麗に集まったコンスタレーションだったはずだから、ゲインの設定が悪いのか、R2の感度が悪いのか。

 RTL2832って28.8Mspsで取ってデシメーションしているから、出力が8bitだとしても入力感度はかなり高いはず。R2は20Mspsで取って、しかもADCが早い段階で飽和するから、信号の品質は結構悪そうな気がする。RTLはRTLで問題もあるんだけど。



 パイロット(SP)の位相のグラフ

 上から下に向けてOFDMシンボル番号、左から右にかけてキャリア番号。シンボル切り出し位置が正しい場合は水平なグラフになる。

 シンボル切り出し位置が正しくない場合(1マイクロ秒ズレ)

 これだけ線が並んでると分かりづらいけど、パイロット信号の位相が斜めになって、コンスタレーションが周波数軸で回転する。サンプリングレートの誤差があると時間軸で回転するはず。


 パイロット信号からはいくつかの情報を取り出せる。

 周波数軸上の角速度はシンボル窓の時間ズレに相当する。これを1フレーム分204シンボルとか適当な長さでフィッティングして角度を求めると時間の微分、つまり送信機・受信機間のサンプルレートの差が得られる。シンボル窓は60マイクロ秒程度の差までは計測できて、1フレームは230ミリ秒くらいだから、250ppm程度までが計測レンジ。

 時間軸上の角速度はキャリア周波数とローカル周波数の差に相当する。ただしシンボル間の角度が180度で折り返すから計測レンジはシンボル間隔1.134ミリ秒の半分の逆数、440Hz程度までしか計測できず、例えば搬送波周波数が550MHzであれば0.8ppm程度の曖昧さがある。

 Airspy R2はクロック精度0.5ppmを謳っているから、基本的には搬送波のビートだけで決められる。ただ、シンボル窓の微分で得たクロックエラーとビートで得たクロックエラーはそれぞれ-0.32ppmと-0.53ppmで、明らかなズレがある。560MHz付近の0.2ppmは100Hz程度の差だから、無視できるほど小さくはないけど、なかなか取り扱いが難しい大きさではある。


 もう一つ、OFDMのガードインターバルの相関値の位相情報もある。これは有効シンボル長1.008ミリ秒間のキャリアの回転を計測できる。これによると-0.84ppm程度。また突飛な値が出てきた。

 各計測値は現在のところテキトーに書いたコードで得た測定量を最低限単位だけ合わせて(無次元化して6桁移動)出力したものだから、符号にはある程度自由度がある。例えば0.84-0.53=0.31だから、量としては合う。GI相関の位相はFFTの前にサンプルに掛けるから、サブキャリアに影響するのも有り得そうな気がする。



 うまく行くときは上のコンステレーションみたいに比較的綺麗な結果が得られるけど、それでもフルセグの復調には失敗するし、場合によっては

 みたいに悲惨な結果しか得られないこともある。かろうじてQPSKっぽい濃淡は見える気もするけど、TMCC/ACすら見えない。

 昔書いたコードのコピペじゃなくて、ちゃんとデコーダを書かないとダメそうだな。

 R2は帯域幅が広いから複数のドングルで待ち合わせとかやらなくていいので、その辺は楽なんだけど、コンスタレーションが汚すぎて本当に復調できるのかも訝しんでる状況。R820T/RTL2832の組み合わせは広帯域信号(移動受信向けテレビ放送)を受信する前提だから、広帯域信号を突っ込んだときの特性はかなり良いっぽい。R2も探せば広帯域信号の受信に使ってる人はいるだろうけど。


*


 Airspyのファームウェアのビルド、試しにHyper-VでクリーンなWin11を用意して、WSL2のUbuntuで指示通りに全部コマンドを打ったら、一部自分でaptに触ったりする必要があったけど、ちゃんとビルドが通った。

 それで作ったバイナリをホストOSの方にコピーして、airspy_spiflash.exe -wで書いて、リセットして、airspy_infoで読むと、v1.0.0-rc10-6-8と表示された。


 リカバリについても、GitHubのWikiにちゃんと書いてあった。DFUモードで起動してNXPのドライバで接続して、バッチファイルを起動すればOK、とのこと。

 このバッチは通常のファームぅエアアップデートとはちょっと違う手順で、前回書いた通り一旦SRAMにファームウェアを置いたうえで通常のファームウェアアップデートを行うような感じっぽい。

 試してはいないけど、まあ、多分大丈夫だろう。


 ということで、ファームウェアのビルドと書き込みは確認できた。

 今回は仮想環境で試したけど、実機のWindowsでも問題ないはず。ただ、色々入れたりパスを設定したりするので、何か他のことをやりたいとき(orやっていたとき)に競合しそうな怖さはある。パスの設定くらいはどうにでもなるけど、libopencm3をsudo make installでどっかに配置していたりする。



 ホストツールについても、mingw64でビルドしたらそれらしいexeやdllが出てきた。ただ、dllの名前は違うけど(GitHubで配布しているバイナリはairspy.dll、ビルドして出てきたやつはlibairspy.dll)。dumpbin /exportsで見た感じ、一通りの関数は揃っているし、呼び出し側で名前を変えれば(orファイル名を変えれば)使えるはずだが。

 ファームの方もWin環境でビルドしてみようとためしてみたけど、もう少し手順が必要そう。ファームはWSL2で、ホストはMinGWでビルドするのが楽かな。

 ホストとファームの両方のビルドが通ったので、これが動けば、好きなUSBコマンドを追加してC#から叩いたりできるはず(デバッグの手間を無視すれば)。



 試しにHyper-VでAIRSPYをゲストOSに共有してairspy_infoを叩いてみたけど、AIRSPY_ERROR_NOT_FOUNDが出る。GitHubから落としたairspy_infoでも同様。デバイスマネージャーからはAIRSPYが見えているのだが。

 その場合も、ホストOS側で叩いたairspy_infoもNOT_FOUNDが出るが(これはHyper-Vに吸われているから正常)、ゲストOSを切断してAIRSPYの共有を解除すれば、ホストOSでのairspy_infoで正常にデバイスが見える。

 AirspyのサイトからドライバをダウンロードしてゲストOS側に手動で入れてみても効果なし。

 ゲストOSでビルドしたairspy_infoをホストOSにコピーして使えば問題無く見えるから、Hyper-VのUSBデバイスの取り扱いの問題だと思う。



 とりあえず、ホストとファームの両方のビルドが通るのは確認できたから、あとはノートPCとか、壊れてもあまり困らない環境でビルド環境を作れば、カスタムファーム等を作ったりできるようになる。とはいえ、ノートPCはスペックが低いからサクッとビルドが通るかはまた別の問題。


 こういう開発をやるベストプラクティスってどんなものなんだろう。複数のソフトウェアを開発する場合(特にインストールしたライブラリのバージョン等に依存性がある場合)、物理的にPCを分離すれば確実だけど、さすがに現実的じゃない。

 LinuxとかWindowsでも、ユーザーで分離すれば、ドライブ直下とかを使わない限りは問題ないのかな? ライブラリのインストール先にもよるだろうけど、ユーザーディレクトリに入れている分には。MinGWとか、ルートディレクトリとかProgram Files以下に入ったりするようなやつがいるとちょっと困ることになりそう。

 最近はストレージも小さくなってきたし、例えばNVMeを手軽に交換できれば手っ取り早いんだけど。メインのPCでそれはさすがにやりたくないし、ノートPCは底面パネルを開けるのが面倒だし。やっぱりFrameworkの拡張カードにOSを入れて取っ替え引っ替えって感じが一番確実なのかな。あるいは、競合とか気にせず一つのPC(アカウント)で作業して、問題が起きたらその時にどうにかするか。


 Hyper-Vで走ってるOSの中で走ってるWSLが管理しているフォルダをホストOSからサクッと触れれば楽なんだけどな。軽くググったくらいだと、簡単な方法はなさそうな感じ。大抵は実機で走ってるWSLが前提で、explorer.exe .でWindowsからフォルダを開けるよ、みたいな事が書いてある程度。そのフォルダを別のPCに共有するような話は書いてない。普通はそんな変な環境を作ろうとすることもないだろうしな。



 AirspyのPC側ツールで、去年の2月にairspy_calibrate.cというコードが追加されていて、SPIフラッシュに校正値を書いたりするようなものらしい。SPIフラッシュの適当な領域に32bit幅でppbの校正値を書くようだ。

 ただ、Airspy本体側のファームの最新のコミットは4年前で、キャリブレーションに関連しそうな機能は無い。カスタムファーム用の機能が公式のホストツールに入っちゃったとかなのかな?

 機能としては単に校正値を読み書きするだけだから、校正値は別の方法で入手する必要もある。

 この機能ってハードウェア依存はどうなんだろう。例えばSi5351Cだとクロックの細かい(ppm未満の)調整みたいなのは難しいはず。PLLで調整することはできるけど、そうするとジッタとかの問題が出てくる。とすると、やはりDigital Controlled Oscillatorを外付けすることを考えているんだろうか?



 DS28E18 データシートおよび製品情報 | アナログ・デバイセズ

 1-Wireデバイス、SPI/I2Cコントローラー、というブリッジ。曰く寄生給電できるから2線だけでSPI/I2Cデバイスを遠く(最大100m)に配置できるよ、とのこと。SPI/I2Cデバイスの電源ですら寄生給電するんだって。データシートを見ると1-WireコントローラーにFETが入ってるから、寄生給電と言いつつ実際はstrong pullupなんだろうけど。それにしたって最大10mAを間欠的に流すだけだし。まあ、ヒーターが入ってるとか、立ち上がりに時間がかかる&待機電力が大きいセンサを使おうとしない限りは問題ないかな?


***


 トーションバネを使ってセンターリターンするような機構を試作



 両側から挟んでやれば、両側に動かしつつセンターリターンするような構造になる。

 両側のピンの間隔が合わないとセンター付近にトルクがかからない部分があって、中立位置が重要な用途だと厳しい。おそらくゲームコントローラーのジョイスティックも同じような構造だけど、中立位置に遊びがあるのはこういう理由なのかも。ラジコンの送信機で別の機構(引きバネで棒を引っ張って回転軸のDカットに押し付ける)を使っているのは中立付近の遊びを嫌っているのかも。

 そう考えると、ゲームコントローラーのドリフト問題って、ポテンショメーターだから起きるとかホール素子なら起きないとかではなくて、周辺の機構の影響もありそうな気がする。ゲームコントローラーだって電源ONとか適当な頻度で中立点を取り直してるだろうし、たかだか数時間程度でそこまでドリフトするってこともなかなかない気がするんだけど。あるいは、それが起きるから問題なのかもしれないけど。


 最近寒いせいか、印刷品質がかなり高い気がする。プリンタを置いている部屋の気温は10℃を下回っていて、プリンタの推奨温度(15-35℃)の範囲外。大きなものを作ろうとすると収縮が問題になるのかもしれないけど、小さい部品を印刷する場合は適当に寒いほうがよさそう?



 Dカット型

 テコの原理がだいぶ効いてくるので復帰力がかなり弱い。Dフラットの形状(幅や曲率)で特性がかなり変わる。

 Dカットが平坦な場合は最初に動かし始めるためのトルクが大きい。その代わりに中立位置はかなり厳密に出る。Dカットに適当な曲率を与えた場合、動かし始めるときのトルクは小さくなる。その代わりに中立位置が厳密に出ない。

 アームの25mmあたりの位置にフラットを割り当てた場合、フラットの幅が5mmくらいあると距離が20%くらい変わるので、右側に回したときと左側に回したときで明らかにトルク(復元力)が変わる。

 回転軸とフラットの距離や幅で復帰力がかなり変わる。一つのバネで色々設定できるので調整は大変だけど色々なバネを買い揃える手間は省ける。

 あとは、ピンで挟む場合は角度とばね定数が直結するから角度とトルクがある程度比例するけど、Dカットの場合はそこがかなり弱そう(かなり狭い範囲で飽和する)。角度とトルクが比例してほしい場合は挟むほうが安心かも。


*


 ピンバイスにM3タップを入れるスペーサー

 このピンバイスに付属のコレットは3.2mmまでしかつかめないので、シャンク径4mmのM3タップは掴めない。ということで、適当なアダプタを作成。適当な下穴の樹脂(PLA)相手にタップを切るくらいなら問題なさそう。

 それくらいの相手だとちゃんとしたタップハンドルは過剰だし、かといって4mmシャンク直持ちはさすがにつらいし、微妙なところなので、ピンバイスで回せると便利そうな気がする、ということで試作してみた次第。

 探してみるとM3でもストレートシャンクのタップがあるらしいので、それが手元にあるならそれを使うのが確実。中国製の安いやつだと商品説明に明記してないことが多いので、確実にそれを買おうとすると難しそう。


***


 ISDB-Tを受信していたら急に極端に強度が落ちて、なんでだろ、と思いつつテレビを確認したら、こっちも映らず。ということで、暗くなって氷点下の気温の中、アンテナ周りの作業。

 前々から接触不良気味だったケーブルを交換して終了。温かいうちに交換しようと思ってケーブルとコネクタは買っていたのに放置していて、結局極寒の中で作業するハメに。いや、北海道で-5℃はむしろまだギリギリ素手で作業できるし温かい方か。手すりとか、金属を触ると手袋が張り付くけど。


 交換したケーブル

 本来、芯線は2mm突き出すように加工しろと指定されているんだけど、左側のやつは明らかに奥まった場所に入っている。実測で5mm以上足りない。ということで、これが接触不良の原因だろう。微妙な力のかかり具合で接触したりしなかったり、不安定な状態で、だましだまし使えていたらしい。このケーブルの先にブースターや衛星アンテナがついているから、少なくともDCまできっちり通ってはいた。それがなければRFだけ通って問題なく使えていた可能性もあるけど。

 電気屋とかに頼んだわけじゃなく、自分で設置したものだから、十中八九僕が加工したものだけど、とはいえこの手のものを加工するときって、手軽にできる範囲であれば指示を守って作業してきたはずだし、なんでこんな変な加工をしたのか腑に落ちない。10年とまでは行かずとも、何年も前のことだから当時どうやって加工したかなんて覚えちゃいないが。

 屋外で使うコネクタは、本来は自己融着テープでぐるぐる巻きにしてビニールテープでさらに簀巻きにして防水・防湿しなきゃいけないんだけど、コネクタの汚れ具合を見てもわかるように、全く防水加工せずに放置していた(楽な指示は守るが手間のかかる指示はガン無視するのだ)。端子の中の芯線も綺麗な銅色だし、根元で切ったケーブルもシールド含めて綺麗だし、意外と大丈夫そうだな。仕事でやるならともかく、遠くない将来にテレビが中断する&加工し直す覚悟があるのなら、手間のかかる防水処理はやらなくても良さそう。温暖とか台風が頻繁に来るような地域や、あるいは硫化水素や塩分濃度が高い地域だとまた別だろうけど。

 とりあえず、忘れた頃にやってくるテレビが視聴できないトラブルが解決できてよかった。原因も経年劣化でなく施工不良なので、他の箇所で同様の症状が出ることもないだろうし(同じように施工不良してない限りは)。


2025年12月10日水曜日

小ネタ






 QF-16、最終127号機を納入


 QF-16って結構な数作ったんだな。どれくらいの数がミサイルで落とされたんだろう。第4世代ジェット戦闘機で一番被撃墜数が多いのってF-16かしら? 第3世代も含めるとベトナム戦争に参戦したF-4とかがいるので怪しいけど。



 コンピューター側の人間が作ったJSF++周りの動画


 NERVのマグカップやうーぱ(S;G)のぬいぐるみ等が置いてあるあたり、いかにも現代のコンピューターオタクって感じがある。……現代、か? 学生時代に触れたコンテンツと考えるとそう外してもないか。


 GCAPとかF-47ってソースコードどうするんだろう? 今更Adaを使うこともないだろうし、JSF++だって現時点でも20年前のコーディングルールだし、とはいえRustを使おうって話にもならないだろうし。最近だってRustでおざなりに例外処理したコードのせいで世界中がパニックになったしな。

 言語レベルで安全性を重視したからと言って、それを本当に信頼していいかを判断するほどの実績はまだなさそう。それくらいなら何十年も使っているC++(少なくともJSF++だって開発期間も含めれば20年の実績がある)を使おうって話になるだろうし。



 半潜水式の重量物運搬船みたいにフラットな船でSTOL機を運用したら軍事作戦で便利やで、みたいなコンセプト


 9人乗りで滑走距離45mとかアホみたいな短距離離陸能力である。

 日本近海で使ってるイメージのあたり、島嶼部みたいなところでチマチマした人員・物資輸送に使いたいんだろうなぁ。滑走路がなくても多少開けた場所があれば離着陸できるし。とはいえ、このあたりで平らな場所か…… UH-1で良くねって気がする。シリーズハイブリッドの小型高翼機ならUH-60やV-22よりは安価に量産できるだろってことなんだろうけど。



 米軍で戦闘機パイロットだった人たちが「レーダーロックなんて日常茶飯事だよ。ロシアとかイラン相手にもやったし、暇なときは民間機をロックして遊んでたし」とか言って笑っていて、いやぁ、核兵器ぶら下げて相手の鼻先まで行ってた国の人たちは覚悟が決まってるなぁ、って感じが。



 amazonの変なシステムトラブル?に巻き込まれて、その対応でWebサイトをめっちゃたらい回しにされてしまった。なんでamazonって人間相手にもっと簡単に問い合わせできないんだよ。。。スパムの問題とか言ったって、過去に何百回も正常に取引してる相手なら信用して連絡フォームくらい開けてくれよ。

 チャットボットは全く使い物にならず、結局自分の電話番号を入力して向こうからの連絡待ち。5分くらい会話して、対応してくれた人曰く「最近はAIで処理してるからミスることもある」だそうで。結果だけ見ればだいぶ得した気分なので(実際得したので)この件は水に流して終了。

 amazonのカスタマーサービス、最近はちょっと定型から外れた問い合わせをしようとするとたらい回しされて大変だけど、人間相手に話がつくとキッチリ丁寧にしっかり対応してくれて好感持てるのよな。そこにたどり着くまでが大変だけど。そもそも普段はカスタマーサポートに連絡する必要がある事態もそう起きないけど。



 だいぶ前から探していた75Ωの終端抵抗

 雑多に変換コネクタを入れている場所に入ってた。地金のやつはだいぶ紛らわしい。これで50Wくらいのダミーロードだと巨大なヒートシンクが目立つんだけど、1W程度のターミネーターだと全く主張がない。



 サンワサプライのスマホスタンドを買ってみた

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

 試しに色々載せてみたけど、かなり汎用性が高くて使いやすい。普通にスマホを置くのはもちろん、ヒンジがかなり硬いので、タブレットとか多少重いものも載せられる。まさか乗らんやろ、と思ってノートPCを載せてみたら、乗っちゃった。かなり軽いモデル(13.3インチ、800g)だから、1kgを超える一般的なノートPCだとさすがに耐えられないと思うけど。あと、画面が共振してさすがに実用的ではないけど。ドキュメントを開いておくサブディスプレイ的な用途なら使えないこともないかな、といった程度。そのくらいの用途ならタブレットで済むからなぁ。

 電卓とか、小袋のお菓子とか、工夫次第で色々載せられるので、机の上に2,3個置いておくと便利そう。

 試しにStream Deck Mk.2を載せてみたら、かなりいい感じ。Mk.2付属のスタンドは角度が固定(orスタンド無しの2段階)だけど、スマホスタンドに乗せれば自由な角度や高さに置けるし、キーボードに多少重なるような配置にもできるから、ホームポジションから押しやすい場所に配置できる。ただ、元がスマホスタンドだから、Stream Deckみたいに多少強く押さなきゃいけないものを乗せると、剛性が足りてない感じが若干ある。

 上面のパネルが水平になるようにすれば小物を置いたりもできるから、工夫次第でわりと何にでも使える。



https://www.jstage.jst.go.jp/article/itej1997/52/3/52_3_277/_pdf

 D-1 VTRの標準化に関して。

 国際規格だから世界中の組織が口出ししてきて、どれがいいかを決めるには実際に作って比較する必要に迫られた。結局他国の提案はあまり実験を行わずに、政治的に主張していたこともあって、実際に比較してみれば日本が主張した方向でまとめることができた。

 前にも全く別の分野で似たような話を見かけたな。どの業界でもあるんだろうな。



https://www.jstage.jst.go.jp/article/itej1978/43/4/43_4_404/_pdf/-char/ja

 1989年。テレビ局の記者が、自宅においてある15年以上前の14インチテレビを37インチに買い替えた時の話。

 かつてのテレビ放送は14インチのテレビで視聴する前提で調整して放送していた。最近になって各社が大型のテレビを販売するようになってきた。実際に制作に関わっている立場から大画面テレビを自宅に置いてみると、色々と気になるようになってきた。



 前回の、NTSCのクロマがなんでセットアップレベルに影響を受けるんだよ、というやつ、コンポーネント信号をIREに変換してから加算するのでなく、コンポジット信号をIREに変換するならすんなり書けるんだな。ただしコンポジット信号はあくまでもYUVの加算であって、IREに変換したあとに基準位相や同期信号を加える。

 今回の実装の場合、YUV段階でIREレベルへ上げてからクランプして加算するから、セットアップレベルが0%以外の場合とは相性が悪い。

 日本の場合、後期の仕様がどの程度だったのかは調べていないけど、初期はセットアップレベルは0%+10%-0%(0% - 10%)で規定していたらしい。なのでアメリカの7.5%±2.5%(5% - 10%)と互換性がある。あくまでも信号の電圧レベルはアメリカの規格を内包しているというだけであって、モニタ側は調整が必要になるけど。とはいえ、日本スペックの端端を入れたら影響を受けるわけだし。

 NTSCのエンコードはもうちょっとちゃんとやりたいんだが、優先度はあまり高くないのですこし先送りの予定。


***


 AORのブラックフライデーセールでAirSpy R2がセールで売ってたので、購入。

 付属のカードに書いてあるURLとパスワードで日本語のクイックスタートガイドと説明書のPDFがダウンロードできるけど、いかんせんバージョンが古いので参考になりそうなことは書いてないな。スクショも古いUIのまま。



 RTL-SDR blog v3ドングルとAirspy R2の基板

 どちらもRFフロントエンドはR860で同じ(R860とR820T2は名前が違うだけで全く同一のチップ)。


 Airspy R2の拡大

 表は主にR860、LPC4370、Si5351Cが乗っている。かなり高密度。

 SMAは端面から少し内側に入っているから、外側のナットを締めすぎると不必要なストレスがかかる。脱落して紛失しない程度にゆるく締めておく程度で良さそう。内側にも平ワッシャなりシム的なものを入れてもいいけど、調整が面倒。そもそもナット自体いらないのではという考え方もある。

 よく見ると下側についてるピンヘッダの高さがそろっていない。うーん。。。一応、拡張用のコネクタは1.27mmピッチに乗っているようだから、ドーターボードを作る場合は困らないようにはなっているはずだが(左下はJTAG)。


 裏面

 水晶は12MHz(LPC用)と25MHz(Si用)の2個。中央の水晶のパッドからハンダが漏れてるのがちょっと嫌な感じだ。クォリティチェック通過だって??

 8ピンパッケージはSPIフラッシュ(LPCのブート用)。マーキングは25Q80DVSIGで、W25Q80DVはWinbondの8Mb3.3V系の製品。ただ、接尾辞SIGはデータシートに記載がない。おそらくW25Q80DVSSIGというやつのはず(SSIGとして売っているやつも商品画像を見るとマーキングはSIGと書いてあるから、カタログの型番とマーキングは取り違えが無い程度に省略しているのかも)。



 SDR#で地デジの帯域を観察

 サンプリングレートが10MHz、SDR#では上下1MHzが非表示で、8MHz範囲が見える。ISDB-Tの5.57MHzも全体が余裕で見える。ch28の一番上のCPが565 928 424Hzに見えていて、本来は565 928 571Hzあたりのはずだから、-0.26ppmくらいかな? スペックは0.5ppmだから、それなりの精度は出てる。ただ、サンプリングを停止して放置して常温に戻してから再びサンプリングすると、結構ずれるから、温度特性はあまり良くないかも。70Hzくらいずれるかな? 常温から熱平衡で約0.15ppm程度の変動という感じ。ま、十分だろう。

 SDR#は相変わらず使いづらいな。最新版は2025年1月1日のやつ。なんでおまえ正月に仕事してるんだよ…… 一部のUIが文字化けしていたり、出力オーディオが壊れていたり、まともに使えない。手元の少し古いリビジョンなら正しく動く。


 R2は外部10MHzを突っ込めばそのまま引き込んでくれるはずだけど、とはいえ0.1ppmより精度のいいクロックをどうやって確保するかという問題がある。10MHzは用途が多いから、例えばSiTimeのSiT5503とか、5ppbで1.8万円くらいのクロックも売ってるけど。1本3000円くらいのRTL系に3万円の50ppbクロックは流石に高すぎだろと思うけど、Airspy R2に1.8万円の5ppbクロックなら、まあ、必要なら買えないこともないか、位の値段に感じられるな(28.8MHzは特殊な周波数だから在庫があるやつは値段が高いし精度も悪い。10MHzなら汎用的だから安くて精度のいい製品の在庫がある)。そもそもそこまで精度のいいサンプリングレートが必要な用途も思いつかないけど。

 5503はI2Cで発振周波数を数ppmとか引っ張れる。例えばR2でGPSを受信して周波数を追従、そのクロックを別のR2に配分すれば、高い周波数確度の受信機を作れる。そこまで極端な安定性が必要ない場合は、1分に1回くらいの頻度で1秒くらいGPSを受信して制御することもできるし、あるいは1時間に1回とかでもいい。時刻も合わせて計測すればUTC(USNO)とかUTC(NICT)に同期することもできる。

 5503は1分間で-11乗くらいの分散らしいから、複数箇所でGPSで時刻&周波数同期して21cm線を受信するVLBI的な遊びもできるはず。最近のインターネットなら登り50MB/s程度なら出ない速度じゃないから、リアルタイムにインターネットで結合したホビーVLBIも作れそう。外付けでRFスイッチが必要だけど、HMC7992をGPIOで制御するとか、どうにかなるはず。

 R2が定価で4万円、5503が2万円、RasPiやGPSアンテナ、21cmアンテナ等の周辺回路を合わせて10万円/拠点くらい、日本全国10箇所くらいに配置して、150万円くらいの設備投資で学習用VLBI観測ネットワークが組める。基線数が多すぎて計算コストが高すぎるって言うなら拠点数を減らして安価に組むこともできる。

/* オンライン教材の会社が小中学生向けのVLBIシステムを作ってるらしいんだけど情報が全く出てこないんだよな。学会での発表の概要はあるからオフラインでは発表してるんだろうけど。小中学生相手にVLBIはうまく説明できれば面白そうだけど、だいぶ端折った説明を求められそうな気もするな*/



 地デジの帯域をWAVに保存して、とりあえず相関処理

 有効シンボル10080、ガードインターバル1260。1フレーム。ちゃんとピークが出る。


 有効シンボルをフーリエ変換

 中央セグメントは位相がそれなりに安定しているけど、それにしてもちょっと変な感じ。


 今のところISDB-Tを復調するモチベは無いので、とりあえずは放置の予定。地デジ放送は(どこかの政党が主張していたのとは反対に)スクランブル放送が行われているから、ISDB-Tのフルセグを復調しても、映像を取り出すことはできない。なのでISDB-TはSDR的にはあまり魅力的ではない。/* 実際はともかく、NHKも公式にはスクランブル放送を行っていないと言っているが*/

 ISDB-TはSPを取り出せば放送局(中継所)の高精度なクロックを仲介して受信機のクロックエラーを計測できるので、そのあたりを見たくなったらまたやるかも。とはいえ500MHzで0.2Hzくらいだから、0.1ppm程度までしか見えないはずだけど。それ以上精度のいいクロックを検証しようとすると、やはりGNSSを使うしかないかな。



 民間機が飛んできたときにSDR#で1030MHzと1090MHzをサンプリング、WAVで保存して、適当に振幅・位相復調


 インテロゲーションではインターモードとモードS、レスポンスはモード3/A/C系とモードS系が得られている。10Mspsなので、質問(0.8us幅)もちゃんと幅が見えている(インパルス信号ではない)し、モードS質問や応答も位相変調やパルス位置変調が正しく見えている。Mark Xの応答は0.45usだから質問よりは狭いけど、それでも多少の幅には見える。



 airspy.dllの練習がてら、C#からAirspy R2のファームウェアバージョンの読み出し。v1.0.0-rc10-0(2016-09-19)だそう。10年近く前のファームウェアだ。GitHubでリリースされているファームウェアはrc10-0(2016年)の次はrc10-6(2020年)だから、一つだけアップデートがある。気が向いたらファームウェアアップデートをやっておこう。しかし、最新のファームウェアアップデートが間4年で5年前か。。。


 とりあえずairspy_start_rxにコールバック関数を渡して、出てくるポインタをファイルに書き出して、SDR#で読み込んで、正しそうな結果は得られた(例えばFMラジオの帯域を受信してWAVに保存して、それをSDR#で読み込めばちゃんとラジオっぽい声が聞こえる)。

 ゲインは3箇所を設定できるけど、すべてR820Tに内蔵されたものなので、R2側(ADC以降)は固定ゲインっぽい。大きな信号が入るとスプリアスが出るので、いい感じに調整してやる必要がある。


 データフォーマットは、S16IQやF32IQを指定すれば、DLLレベルでフォーマット変換を行って適切な形に出力される。そのままWAVへ書き出せば正しく保存される。DLLの中ではIIRやFIRでDCブロックとか色々処理しているっぽい。商品ページに書いてあるIQインバランスやDCオフセットが無いというのは、ソフト的にDLLレベルで除去しているという意味らしい。

 DLLで処理する前の、R2から送られてくるRAW形式は、少なくともDLLのソースには説明が全く無いし、ファームウェアのソースを読むのも面倒なので完全に推測だけど、おそらく平衡IQ4本を1個のADCで20Mspsで順番にサンプリングしている感じらしい(少なくとも、商品説明には12bit ADC@20Mspsと書いてある)。複素平面を90度ずつ順番にサンプリングしているイメージ。

 LPC4370FET100には高速ADC(ADCHS、12bit, 80Msps)が1個しか乗っていないから、それを時分割で平衡IQ4chのサンプリングに使っているらしい。ADCHSは差動入力もできるけど、これは1chしか使えない(負信号が1ピンしか無い)から、ゼロIFを受けるには不適(低IFなら受けれるはずだが)。

 平衡IQ(あるいは平衡Iと平衡Q独立)である程度長い平均を取ると、DCオフセットが見えてくるから、それを差っ引けば一応DCオフセットフリーになる。IQインバランスは、そもそも1個のADCでIQをサンプリングしているから、原理的にはADC以降でゲインエラーが出ることはないはず。


 これを受け取って処理する場合、単に正極はそのまま、負極は符号反転して読み込んだ場合、5MHzの強烈なスペクトルが出る。その代わりにDCオフセットは相殺されるから、単にLPFを通して5MHzの線スペクトル(高調波は見えない(±5MHzに折り返される)から無視していい)を除去するだけでいい。

 正極は直接、負極は 4096-サンプル みたいに計算した場合、強いスペクトルが出る。正極は サンプル-2048 、負極は 2048-サンプル、みたいにしてDC付近に寄せると、わずかなDCオフセットの影響で弱めの5MHzのピークが出る。単純に負極を符号反転した場合に比べればピークは低くなるから、FIRの特性はその分大人しくても良くて、だいぶ楽になるはず。

 もう少し技巧的にやるなら、全サンプル(IQ正負4ch)の長期的な平均を取って正確なDCオフセットを得て、それを基準にすると、5MHzのピークはほとんど消える。

 ただしI軸とQ軸に50nsの時間差があるから、IQ軸が完全には直交しておらず、そのまま複素信号として扱うと0Hzでミラーした形で反対側にスペクトルが漏れる。SDR#で見るとそういう特性は無いから、DLLのフィルタはうまいことミラーを消してるんだと思う。

 このサンプルは、DCオフセットを別にすれば、IQ軸を相互に(正負をうまくハンドリングしつつ)ゼロパディングして、一旦20Mspsのデータにアップサンプリングした後に、適当なLPFに通して高周波成分を捨てつつ、10Mspsにデシメーションすれば、概ね正しい波形が得られる。I軸とQ軸はそれぞれ奇数番目と偶数番目(orその逆)がゼロパディングされるわけだから、20Mspsで作成したFIR係数を奇数番目と偶数番目の2つに分けて、IQ軸に対してそれぞれの係数を実数演算すればいい。ただ、広帯域でフラットな特性を得ようとすると、FIRはかなり係数を長くする必要があると思う。DLLのフィルタはもっと短いから、また違ったテクニックを使っているっぽい。


 RAWで取ったバイナリを一旦ファイルに保存してから、後処理でIQ信号に変換して、WAVファイルに保存

 とりあえず設計通りに動いているはず。

 +3.6MHzと-3.5MHzにFMラジオが2局あって、周波数対称の位置に目立ったスペクトルは出ていないし、通過帯域4.47MHzのLPFも設計通りの特性に見える。

 FIRは普通に実装すると演算コストがかなり高いし、そもそもDLLの変換でも問題ないだろうから、実用上はRAWを読む意味は無いはず。



 R2、ゲインを上げていくと結構早い段階で飽和する気がする。

 適当なアプリを作ってヒストグラムとスペクトル(F32IQ, I16IQだけ)を表示。とりあえず地デジの電波を受信。

 ↑飽和していない状態のヒストグラム

 ↑飽和し始めた状態

 ↑かなり飽和している状態

 飽和するとガードバンドもかなり浮いてきている。


 Rawで読み出し


 Raw状態(ADC出力値?)ですでに飽和している。LPC4370の高速ADCは電圧レンジが狭いらしいから、それが制限になっているのかな?

 Raw形式でデータを受け取るなら、ヒストグラムを見ればレンジを超えているか(or超えそうか)は判断できるから、ゲインにフィードバックするなり、アラートを表示して調整させるなり、対策は考えられる。ただしRAWからの変換が高コスト。

 SDR#等で受信する場合、かなり低い信号レベルでも飽和するから、注意する必要がある。

 4370のADCHSには任意の閾値から出たり入ったりすると割り込みする機能があるらしいから、ADCが飽和しそうになったらPC側に通知を出すみたいなことも、比較的簡単にできそうな気もするが。USBがどれくらい自由にデータを通せるのかはわからないけど、PC側からポーリングして1Hzくらいで監視するとか、PC側から閾値を設定するとか、その程度なら作れそう。



 オンボードにLEDが乗っているので、DLLからGPIOを叩いてLチカしてみた。ちゃんと反応する。ファームウェアから触ろうとするとled_on()とかled_off()みたいな関数が定義してあるからそれを使えばいいんだけど、C#からDLLを叩こうとするとポート番号0、ピン番号12、true、みたいな感じで指定しなきゃいけないので面倒。まあ、このLEDはケースを閉じてしまえば外からは見えないから、使うこともあるまい。なんでこんなところにLEDが付いてるんだよ。ケースの穴加工1,2個くらいケチるなよ。

 同様にタクトスイッチも乗っているけど、これについてはファームウェア側にも定義がない。試しに押してみるとUSBデバイスが切断されるから、単なるリセットスイッチらしい。商品説明の写真見たらちゃんとRESET Buttonって書いてあった。

 その商品説明にはオンボードLEDはRX LEDって書いてある。試しにSDR#で受信したら受信中に点灯した。ちゃんと制御しているのか…… なんで隠してるんだよ。



 C#のDLLラッパー、rtlsdr.dllよりだいぶ簡単に作れた気がする。まあ、単にrtlsdr.dllでDllImportの使い方をある程度学んだから、というのもあるだろうけど。あとは、今回はあまりググらず迷ったらCopilotに丸投げしたのも結構大きい気がする。Think Deeperで質問すればかなり実用的な回答が得られるので便利(GPT-5で質問すると劣化版検索エンジンみたいな性能しか出なくて謎い)。


 C#、Marshal.Copyで構造体にコピーできないのが結構つらいんだよなー。nintで渡されたポインタを(float,float)[]とか(short,short)[]にコピーする場合、一旦byte[]にコピーしてからMemoryMarshal.Castで型を変換して再度コピーしなきゃいけない。メモリ転送が多い。



 Airspy R2ってオンボードで丸々未使用のCortex-M4F 204MHzが乗っているから、いい感じのカスタムファームウェアを入れれば、例えばUSB CDCでADS-Bを吐き出すアダプタとか、あるいはUACでFMラジオを吐き出すアダプタとか、UVCでワンセグ映像を吐き出すアダプタとか、いろいろ作れそうな気がするんだけど、そういう用途ってあんまり見かけない気がする。そもそもAirspy R2の使用例を探したこともないから、あっても知らないだけだけど。

 LPC4370にはSD/MMCペリフェラルが乗ってるけど、R2の拡張ヘッダにはSDカードに必要な端子すべては出ていないはずだから、microSDカードスロットを追加してスタンドアロンでRawデータを保存する、みたいな拡張ボードは作れないはず。SPI端子は出てるからSPIモードでSD/MMCのファイルを読み書きすることはできるだろうけど、10Mspsの12bitパックデータを保存するにはバス帯域で1桁足りないはず。スタンドアロンでRawデータを記録したいならmicroBにOTGでUSBメモリをつなぐほうが早そうだな。

 買っといてなんだけど、Airspy R2ってどういう用途で使えるんだろうか。RTL系の2MHz幅では足りなくて、10MHz、1.7GHzくらいまでなら足りるような用途。うーん……


 試しに430MHz帯をSDR#で覗いてみた。違法無線が2,3組いたので聞いてみたけど、SDR#の狭い画面(最大化すると描画が遅くなる)で8MHz幅から選択しなきゃいけないから、かなり使いづらい。430MHzアマチュア無線に特化した受信ソフトとかがあるなら便利だろうし、あるいはR2は広帯域スペアナとしてしか使わず、実際の受信(&送信)は専用無線機を使うと割り切るならそれなりに使えるだろうけど、Airspy R2 + SDR#の組み合わせで8MHz幅の狭帯域通信を監視&復調しようとすると、あまり使い道はない気がする。

 アメリカならFMラジオが隣接してるから便利かな、という気はするけど、FMラジオを聞くだけならRTL系や普通のポケットラジオを使うほうが安く済むし。R2はカスタムファームを作りたいとか、あるいは専用の受信ソフトを作る(or探す)みたいな感じで、用途に特化した使い方をしないと、あまり利便性を感じない気がする。



 LPC4370のRAM上実行について - 滴了庵日録

 LPC4370は、282kBのRAMを内蔵するかわりFlashを内蔵しておらず、RAM上で実行することを前提としている。204MHzという高速な動作クロックのため、内蔵Flash上の動作では読み出しアクセスがボトルネックになるためである。

 SPIフラッシュからSRAMに読み出して起動するあたりFPGAみがある(理由は違うけど)。


 Airspy R2のリカバリ方法(ファームウェアを破壊した場合の復旧方法)を探してるんだけど、見当たらない。

 Airspyのファームウェアアップデートの手順を読む限り、ケースを開けてジャンパを変えろみたいなことは書いてないから、AirspyのファームウェアからもSPIフラッシュに書き込みはできるはず。実際、AirspyのDLLにはairspy_spiflash_erase, write, read関数があるから、SPIフラッシュの書き換えは好きにできるはず。ただ、これを使ってファームウェアを書き込む場合、USB DFUとは非互換だから、万が一ファームウェアを破壊してしまった場合は、別の方法でUSB DFU経由で書き込む必要があるはず。

 ファームウェアに付属のテキストファイルだとairspy_spiflash.exeにバイナリを渡して書き込め、と書いてあるけど、Wikiにはairspy_flash.batで書き込め、と書いてある。ファームウェアにはdfu_util.exeとかlpcdfu.exeみたいないかにもそれっぽいヤツも付属している。もしかしてバッチの中でうまく分岐してるんか?と思って見てみたら、単にairpsy_spiflash.exeを起動するだけの1行が書いてあるだけだった。。。


 LPC4370は内蔵プログラムROMが無くてSPIフラッシュから起動できるんだから、マイコン自身がSPIフラッシュにアクセスできるんだろうけど、読めるのと書けるのは別だろうからなぁ。それともイレース単位とかって標準化されていて、マイコンで透過的に処理できるんだろうか?

 このあたりはLPCのユーザーマニュアルを読めばいいんだろうけど、NXPマイコンって使ったことないから勘所がわからん(mbedでちょっと遊んだ程度ではLPCを使ったとは言わないし)。

 UM10503 LPC43xx User manual Chapter 5 Boot ROMのFig 16 Boot process for parts without flashを見る感じ、シリアルデバイスとして起動した場合、受け取ったバイナリはSRAMに保存するだけなのかな? その場合、USB DFUでまずSPIフラッシュに触れるプログラムをSRAMに転送して、そいつを起動してSPIフラッシュにファームウェアを書き込む、という二段階の手順が必要なんだろうか? Airspyの場合はUSB DFUでファームウェアのバイナリをSRAMに転送すれば、そのファームウェアが走るはずだし、そいつのairspy_spiflash_writeを叩いてもう一度バイナリを転送すれば、ファームウェアをSPIフラッシュに書き込めるのかも。


 ファームウェアのソースをざっと見た感じ、LPCのペリフェラルはレジスタを直叩きしている感じ(所謂HALみたいなレイヤを経由していない)。

 HALがあったところで、結局はデータシートでレジスタマップを見て、そのレジスタを書き換えるHAL関数を探して、それを実現する引数を探さなきゃいけないから、HALがあっても余計面倒なだけなんだよな。特定のマイコンしか使わないならレジスタを直接叩くほうが圧倒的に早いし楽。

 とはいえ、データシートの読み方すらわからないマイコンだと、レジスタに書いてる内容を調べるだけでも大変。


 試しにLPC4370の評価ボード的なものが無いか探してみたけど、なさそう。10年以上前のマイコンだしな。当時大人気のLPC-Link2もすでに秋月での取り扱いは終了している。一応マルツには在庫があるから、必要ならそれを買うことはできるだろうけど、納期16週間だって。試しにDigiKeyで見てみたら、生産中止で在庫無しだそうだ。じゃあなんでマルツで注文できるんだよ…… NXPのWebサイトではLPC-Link2はステータスがアクティブだから、まだ作ってるはずなんだけどな。

 値段を気にせずLPC4370ボードが必要ならAirspy Miniを買うのが早そう。壊さない限りはSDRドングルとしても使えるし。


 4370にはI2Cペリフェラルが2個乗っているけど、ファームを斜め読みした感じ、片方を5351に、もう片方を860に使っていて、拡張コネクタにはI2Cは出ていないらしい。どうしてもI2Cデバイスをぶら下げたいなら、DLLからGPIOを叩いてめちゃくちゃ遅いソフトI2Cを作るか、あるいはカスタムファームでソフトI2Cを作るか、工夫が必要そうだ。



 Airspyの解説記事

https://airspy.com/downloads/Airspy%20RadioUser%20March%202015.pdf

 シルクによるとAirspy R0だそうで、部品の種類や配置はR2とほぼ同じ。R0の日付は2014年8月でR2は2015年8月だから、1年でR0, R1, R2を作ったのかな? で、その後10年改定無しか……

 2010年代前半のオープンソースソフトウェアorハードウェアって謎の活力があったよな。



 試しにLED用の穴付きのサイドパネルを作ってみた

 LEDのところに穴を開けて、光ファイバで導光している。輝度が低いので明るいところではほとんど見えないけど。ファイバを曲げて効率よくLEDに接続すればもっと明るくなるだろうけど、今回は端面を45度くらいに切り落として光の一部を取り込んでいるだけ。

 リセットスイッチも押せるような機構があるとカスタムファームを作るときに便利そうではあるけど、USBコネクタとかケースの突起を避けながら力の向きを90度曲げなきゃいけないから、ちょっと大変そうだ。

 リセット端子がブートセレクトの2.45mmにも接続されていれば取り扱いが楽でいいんだけど、JTAGとか拡張コネクタとか、ハーフピッチの場所にしか出ていないので外付けスイッチは大変そうだ。かといってオンボードのスイッチもJTAGのハーフピッチの横だから下手に触ると横の端子を折りそうだし。そういう意味では、リセットスイッチを操作できるような機構がサイドパネルについていると便利なんだよな。



 試しにAirspyのファームのビルド環境を作ってみようと思って、とりあえずUbuntuで試してみるか、と思って、USB 3.0のUSBにISOを焼いてみたんだけど、なぜか起動しない。前に焼いたUSB 2.0のメモリからだと、なんかやたら遅い気がするけど、一応起動するから、USBメモリ側の問題のような気がする。

 USBが問題ならNVMeに焼けばいいのかもしれないけど、わざわざWinOS環境消してまで試そうとも思えないしなぁ。ノートPC、NVMe交換するの面倒すぎ。このあたりの手間はFrameworkとかもほぼ同じなんだよな。パームレスト剥がしたら簡単にNVMeが交換できるような構造になってれば便利だろうに。


 AirspyファームのGitHubのWikiを見た感じ、makeを通すのにpythonが必要らしい。大変そうだなー。