2014年 01月 20日

Raspberry Pi を中心にやってみようとしているところ

Raspberry Pi せっかくあるので、一応作りたい目標をもっていろいろ試してみてる。現時点での思惑を書いておく。

概要

無線機の周辺を拡張して、PCと連携しやすくしたり便利にしたり、というのが目的。具体的には

  • 無線機の Wi-Fi 化
    • API サーバになってLAN内のコンピュータから無線機の情報を取得・設定する
  • アンテナ切替情報の取得・設定
  • そのたもろもろ

全体

  • Raspberry Pi
    • I2C バス
      • アンテナ切替コントローラー (AVR)
      • センサー計 (温度など)
    • シリアルポート
      • 無線機コントロール (RS-232C 変換)
  • WebSocket サーバー
    • 周辺機器の中央集権サーバー
      • 無線機コントローラー
      • アンテナ情報
      • センサーなど

ある程度拡張性を持たせつつこれらを収めたい。無線機の近くで使うので、ある程度ノイズ対策が必要かもしれない。

ブロックごとの設計

電源部
  • アンテナ切り替えリレー用に 12V (最大 400mA 程度) が必要
  • Raspberry Pi が 5V 700mA が必要
  • ほか周辺機器分はそんなに食うものがないので、かなり余裕を持っても 5V 500mA ぐらいあればよさそう
    • Raspberry Pi の GPIO が 3.3V で接続機器もあわせたいので 3.3V も必要

12V が必要なので、ACアダプタとして 12V を使い、降圧して 5V, 3.3V を作りたい。

  • 12V 500mA (6W)
  • 5V 1A (5W)
  • 3.3V 500mA (1.65W)

ぐらい確保できたら十分そう。PC用の電源だと、100Vから直接これらの電圧を全部調達できるけど、コストはともかくオーバースペックでデカすぎる。

12V 2A ぐらいのACアダプタ (24W) から 5V はスイッチングである程度高容量を高効率でとりだして、3.3V は 5V からリニアレギュレーターで安定化させる感じにする。

http://akizukidenshi.com/catalog/g/gM-02038/

5V 3A のスイッチングDC/DCコンバーターで、変換効率は最低でも73%。

  • アダプタ: 12V 2A
    • 12V 500mA
    • 12V 1.5A (18W) -> 5V 2.6A (18 * 0.73 = 13.14W)
      • 5V 1A
      • 3.3V 500mA を 5V からリニアレギュレーターで作ろうとすると、電圧差はそのまま熱になるので ( (5 - 3.3) * 0.5 = 0.85W が無駄になる)、単に 5V 500mA を消費すると考えることができる。
アンテナ切替コントローラー

ATmega168P をつかって実装。TWI (I2C) がついてるので簡単。内蔵8 M クロックで動作させて、アンテナのリレーのコントールをI2C経由及びボタンで行い、LED でどのアンテナが有効かを表示する。

リレーは2〜6つほどを同時に駆動する必要があり、この時最大で 400mA ほど流れる。かなり余裕があり、3.3V でも十分スイッチできるパワーMOS-FET でスイッチングする。

電源は I2C を Raspberry Pi と直接繋げたいので 3.3V 供給

センサー類

基本的に I2C 対応、3.3V 品なので、そのままバスに繋ぐだけ。ごちゃごちゃやりたいのでブレッドボードを内蔵してそこに差す

RS-232 変換

無線機とのインターフェイスのために RS-232 変換をする。

2014年 01月 13日

1アマ (第1級アマチュア無線技士) 免許がきた

12月10日に受験して、12月24日の合格発表と同時に申請を出し、免許日は1月9日で、それから2日後には不在票 (書留にしたので) が入ってた。思ったより早かった。営業日的には7日ぐらいかな。

今まで持っていたやつはラミネート加工されたやつだったけど、新しい形式になっていわゆるカードサイズになったのと、英語表記が併記されるようになった (電波の性質上、国際的に使われうる免許だからかな) のと、ホログラム (富士山と桜?) っぽいものが全面に入るようになったみたい。

2013年 12月 24日

1アマ合格

25日発表ってアナウンスされてたと思うんだけど、なんとなく見にいったら24日に発表されてた。合格日は速報の日と同じらしいので、さっさと書いて出してきた。

25日にハガキが届いた。はやい。

2013年 12月 10日

1アマ (第1級アマチュア無線技士) 試験を受験した

試験問題

アマチュア無線の試験を前回 (3級) 受けたのは、まだ電信受信試験があった中1のときだったので、実に14年ぶりぐらいの試験になった。その間に電信の試験は廃止され2級と1級はあまり難易度に差がなくなったみたいなので (数学的な部分だけ?)、2級は受けないことにした。

動機

  • 10MHz, 14MHz (2級以上で許可) に出てみたくなった
  • 3級とか小学生でもとれるし恥ずかしい感じがする
  • 資格の説明が「 アマチュア無線局の無線設備の操作」 とシンプルになってかっこいい

やりたいことは2級でもできるし、QRO (2級で最大200W、1級だと最大1000Wまで許可されるけど、集合住宅だと出力をあげるのは悪手) する気もないので、モチベーション的な問題が大きい。

勉強

昔はどうだったか知らないけど、1アマは難しい難しいと聞いていた割に、今はそんなに難しい試験ではないように思った。中学で数学ちゃんとやって卒業してたら余裕、みたいな感じだと思う…… (複素数の計算が一部あるけど、1アマだとたいしたことはしない) 電信聞き取りがないし、ほんと単に数学力が難易度に直結する。

自分は中学・高校で数学をちゃんとやらなかったばかりか、かけ算九九でミスをするレベルなので、そのへんが大変つらかった。問題を方程式にするまではできても、かなりの頻度で計算ミスをして、しばらく気付けないことがある。計算ミスが多いと、それに気をとられるがあまり、考慮不足で根本的に間違えることもあって辛い。

2ヶ月前から落ちてもいいから基礎からというつもりで準備をしたけど、本気でやりまくったのは最初の1ヶ月だけで、模試をしてみたら合格点を超えてしまったのでだんだんやる気が落ちていった。使った本は

第一級アマチュア無線技士試験問題集 (合格精選400題) - 吉川忠久

吉川忠久

5.0 / 5.0


基礎からよくわかる無線工学―第1級・第2級アマチュア無線技士国家試験準拠 - 吉川 忠久

吉川 忠久

4.0 / 5.0

と、中学生レベルの計算を思い出すためにドリルを買って2回ぐらいやった。高校受験用だと中1〜3まで纏まっていて便利。

中1~3数学10分間復習ドリル―サッと復習ググッと学力アップ - 中学教育研究会

中学教育研究会

5.0 / 5.0

ドリルは体感的にはかなり効果があって、その後問題を解くのが気分的にもだいぶ楽になった。

あと、本でよくわからなかったところは以下のサイトが大変わかりやすかった。たぶん以下のサイトと過去問題だけでも工学は受かると思う。

前述の通り、複素数に関しては1アマでは普通に文字式を解くのと変わらないレベルのことしか要求されないので、余計な勉強はしてないし、特に苦手意識もつかなかった。新たに覚えたのは分母にj がきたとき共役複素数で分母を有理化というルールだけだった。

本番

直近の過去3回の問題は事前にやってたけど、工学は本番の問題が思いのほか難しく感じた。これは1枚目に計算問題が集中しており、なおかつその全てが事前にやった問題集や試験問題に同じ形の問題がないというものだったからだと思う。なのでかなり焦った。そう難しい変化ではないとはいえ、方程式の変形をよくミスするので、結局念のため4回ぐらい解いたりした…… (おかげでこれらは正答できた)

能動素子 (半導体) の問題が全然でなかったなあという印象だった (出たことは出たんだけど)。ことごとく、出たらいいなあとなんとなく思っていた問題はでなかった。逆に、出たら捨てようと思っていた過渡状態の問題がでて悲しかった (けどこれは改めて考えたら解けた)

間違えた問題(A問題の2問)の原因は、理解不足による勘違いと、根本的な解きかたのケアレスミス (2倍するのを忘れた的な) だった。

久しぶりに全力で応用部分の頭使った感じだった。終わったあとヘロヘロになった。

法規は単に覚え間違いが多かった。「無線電信とは~通信設備である」が何度見ても納得いかない。設備じゃねーだろと思うんだけど、定義だから仕方ない……

答えあわせ

試験日の3日後?の15時に公式の解答が出るみたいで、答えあわせをした。(法規、工学ともに、150点満点中 105点 正答率70%以上が合格ライン)

  • 法規: 130点 (正答率87%)
  • 工学: 140点 (正答率93%)

だった。試験後の印象としては、法規は余裕で工学がヤバイ、だったけど、点数的には逆だった……

マークミスさえなければ、合格しているはず。25日に正式な合格発表がある。

まとめ

やればできた。勉強はじめる前はいろいろあって受かる気がしなかったんだけど、実際勉強してみると、そんなグダグダ言うほどには難しくなくて、これさえ受かないとかだと自分相当ダメなんじゃないかと思ってプレッシャーだった。(難易度的には1陸特より少し難しいぐらいらしく、無線資格としては1陸技・1総通まであるわけで、入門レベルなのだなあという感じ…)

たまには試験的なものをしてみるのもいいかもなあと思う。けど、受けるモチベーションが起こる試験があまりない。多少勉強する姿勢ができたので、継続して何かしら勉強をしたい。

2013年 11月 30日

Web Audio (JavaScript) で RTTY (周波数偏移変調) をデコード

RTTY (ラジオテレタイプ = 無線による文字伝送) というものがありまして、大変昔昔に考えられた通信プロトコルなのですが、アマチュア無線では一応現役のデジタルモードであります。

RTTY で通信すること自体にはあんまり興味沸いてなかったのですが、プロトコル自体には興味があったので、Web Audio と絡めて、試しに実装をしてみました。

RTTY のプロトコル

そもそも RTTY はラジオテレタイプの総称なのですが、アマチュア無線においては典型的には以下のようなプロトコルのようです。

  • 170Hz シフトの FSK (複数の周波数を切り替えて信号を伝達する)
  • 5bit の ITA2 コード Baudot Code (ボーコード) で、スタートビット1bit、ストップビット1.5bit の非同期方式
  • 速度は 45.45 ボー (22msecごとの符号)

さらに、無線機とのインターフェースとしては AFSK (Audio? FSK)、直接FSK というのがあって、前者は LSB モードの音声としてオーディオ帯域を入力するもの。後者はキーイングに応じて無線機側で直接送信周波数を 170Hz シフトさせるものです。

AFSK だとマイク入出力だけで無線機とのインターフェイスが完結するので接続は簡単になりますが、無線機に表示されている周波数と実際発射される周波数にズレが生じたり、ALC の調整とか、電波の質とか、送信が少々面倒です。まぁしかしとにかく AFSK として実装をしました。

なので、送信側としては 2125Hzの「マーク」符号 (=ビット1に相当) と、シフトされた「スペース」符号 (=ビット0に相当) を作ります。

Baudot Code

RTTY が開発された当初には ASCII コードとか存在しなかったようです。

5bit しかないので、アルファベットと数字・記号をシフトコードで切り替えながら送受信することになってます。なので、シフトコードの受信にミスると文字化けが起こります。

出力 (送信)

まずデバッグしやすくするため、送信側から作りました。デバッグには既存の MMTTY を wine で起動してマイク経由で適当にやりました。仕様通りに信号を変調すればいいので送信は比較的楽です。ただ、以下の点にハマりました。

  • LSB モードの復調結果を取り込むことを前提としているので、マークとスペースの位置が反転する (スペースが170Hzアップシフトになる)
  • 下位ビットからの送信

入力 (受信)

まぁ当然めんどうくさくて、とりあえず同期検波を実装してみました。マーク周波数、スペース周波数それぞれについて、I と Q (1/4位相ずれ) 信号を作ってやるやつです。それで直流になるので、あとは頑張って22msec分のサンプルを数えながらデコードしています。

この方法だと特にフィードバックとかがいらず、ストリーム1パスで処理できるので気が楽でいい感じです。

今回は JS 側でフィルタとか書きたくなかったので、最後のほうまでダウンサンプリングせず、できるだけ Web Audio の API で実装してみました。単に面倒だったのと、Web Audio の知見を溜めようという狙いです。I/Q な信号が2本なので、合計4チャンネルの信号を作って一気に1つのローパスフィルタノードに入れたりして結構楽しい感じです (ただ、こうするとチャンネル間で干渉するっぽい)。オシレーターノードを使ってもっと綺麗に書けないかと思ったけど、かえって面倒だったので素直に sin/cos してます。

ちなみにローパスとハイパスの Q 値は 0 以上の場合、カットオフ周波数付近がなぜか増幅されるという挙動になるのでハマりました。減衰傾斜が急になるのだとばかり思っていたら全然違った。バンドパスの場合の Q 値は上げても減衰傾斜が急になるだけです。

2013年 11月 19日

モールス練習 進捗

練習開始から111日。練習のモチベーションはかなり落ちているんだけど、割と習慣化できているので、1日に少なくとも5分程度はやってると思う。習慣化というか、せっかくここまで頑張ったんだし……っていうサンクコスト的な感じで続けざるを得ない。

前回書いたときから3週間ほど経ったけど、あいかわらず 100% をとらない限り次に進まない、というのを続けてる。23wpm で 100% を出して、今は 24wpm で 100% を狙っている。90%以上はコンスタントに出せていて、あとは運が良ければ100%とれるかな?という感じ。たまに 25wpm、26wpm をやってもまぁ90%ぐらいはとれる感じ……

というのはランダムの話で、やはり単語聞きとりになるとかなり精度が落ちる。80〜90%ぐらいになってしまう。符号の聞きとりだけじゃなくて、単語の認識をしようとして処理速度が追いつかない感じ。ただ、速度を落とせば聞きとれるかというと、そういうわけではなくて、頭に浮かんだ文字の一時記憶が数msecなので、遅いと遅いで単語が聞きとれない。

あと、「business」とか、「conversation」とか、長い単語になると、さらに辛い。単語は i e s あたりが本当に頻出なので、速度が1.5倍ぐらいになるインパクトがある。ss は特徴があるので覚えやすい。hh とか ii という列は普通ないので、ss は s 単体よりも正確に聞きとりやすい。process とか discuss とか possible とか、よくでてくる。

初期のころからやって聞き慣れつつある th からはじまる頻出単語 (the then they them this there their) は結構聞きとれるようになってきた。初期のころこれ無理だろ、って思ってたけどかなり時間をかけて慣れてきてる…… とはいえ、これらの中でも this there their は難易度が高い……

2013年 11月 01日

モールス練習

練習開始から93日、ほぼ3ヶ月ぐらい経っているので経過を書いておく

  • 10月09日: 25wpm ランダムまで90%をとれ次第すぐ進むぐらいの勢いでやる。
    • 1ヶ月で、20wpm ランダムならぎりぎり90%をとれるぐらいになる
    • 2ヶ月で、25wpm ランダムならぎりぎり90%をとれるぐらいになる
  • 26wpm からどうも急に難しくなったように感じられる
    • 一部の符号の聞き間違えが足を大きくひっぱっている (特に S H 5)
  • 20wpm まで戻り、100% がとれ次第次のスピードに進むという基準に変更
    • 基礎練習
    • S H 5 を特に意識してやる
    • 3 7 z あたりも苦手だったけど、全体的に精度が上がるのは感じられる
  • 22wpm ← 今ココ
    • あいかわらず S H 5、1 J で間違えることが多い。

22wpm でもランダムなら、ほぼ90%はとれる、という状態にはなっている。ただし単語聞きとりだと、短い符号が多くなっておいつけなくて、もっと低く80%代なことも多い。それに身体状態に大きく左右されるのも変わりない。寝る前とかだと95%もとれなくなる。

最近急がしくて交信を聞く暇がなく、とにかく朝と夜の聞きとり練習だけをやってる。実感としては正直、ラバースタンプレベルでも余裕でとれるような感じではない。タイピングまではできても、意味まで理解して聞きとろうとすると単語単位で落としてしまう。それに、実際の交信だと25wpmはあたりまえな感じなので、現状の能力では全く足りない。

ラバースタンプでも、名前と住所は必ずちゃんと聞きとる必要があるところなので(住所はJCCで送ってることが多いからそれほどでもないけど)、それぐらいは1発でとれるようになりたい。それに、ラバースタンプとはいえ、何を送ってこられるかわからないのは怖い。緊張するとさらに聞きとれなくなると思う。

2013年 10月 21日

AVR で USB 接続の PC キーヤーを作る

PC からモールス符号を発生させて無線機に入力するものが欲しいと思っていた。当然既にそういうのはあるんだけど、どうも気に入るのがないので、必要な機能だけ自分で実装する。

基本の要件としては

  • クロスプラットフォームであること
    • というか Mac で動くこと
  • USB バスパワーで動くこと

なので、簡単そうでいろいろ教材としても楽そう。

クロスプラットフォームで面倒なドライバを書かなくてすむ方法は HID デバイスとして作ることだと思うので、そのように作ることにした。また、USB 用の外部チップとか用意したくないので V-USB (AVR マイコン上で USB を処理できるライブラリ) を使うことにした。

いろいろやってなんとか2日ぐらいで最低限の機能の実装ができたのでいろいろメモしておく。

回路図とコード

コード: https://github.com/cho45/AVR-USB-CW


現状制作途中のものなので、実際使う際に必要なリレー部分とかは書いてない。

現状だとダイオード2本で約1.4V程度電圧降下させて 3.3V〜3.6V 程度を作りだす方法を使ってる。V-USB の Wikiに書いてある方法の1つ。

左下のはそのうち試してみたい回路で、AVR自体には5Vをそのまま供給して、信号ラインだけ 3.6V にツェナーダイオードで電圧降下させる。電源電圧を3.3V程度にしてしまうと、動作周波数が 12MHz 程度までしか保証されないので、16MHz や 20MHz で動かすならこちらのほうが安定しそう。

V-USB

まず examples/hid-{data,mouse} を動かして、ふむふむと思いながらやってみたけど、なかなかハマった…… HID デバイスを作ろうとするとデフォルトの usbconfig.h から結構書きかえないといけないんだけど、それを知っていないとだめなのでつらかった。

usbconfig-prototype.h から作るのではなく、example/hid-* のをコピってくるほうが確実に動くと思う。

まだコントロール転送しかできてない。少なくともインタラプト転送はやることになりそうだけどデバッグがだいぶ大変 (追記:インタラプト転送は Mac + libusb だとできなかった)。

あと、自分で設定している割込みの頻度が高すぎると STALL しやすい…… クロック周波数にしても、こういった処理にしても結構シビアなので気を使わざるを得ない……

HID のレポートデスクリプタ定義は、大本の仕様書がどこにあるのかわからないのでコピペと感で書いて試した。

V-USB を妨げない delay_ms

_delay_ms は定数しかスリープできないのと、ビジーループなのでその間割込み以外何も走らなくなってしまう。V-USB は usbPoll() を少なくとも50msecに一回は呼ばないといけないとかなので、これは使えない。

なので、まず割込みで時間を測るタイマー変数を作る。

必要な精度以上のタイマー(あまり短くないほうがいい)を用意 (この例だと1ms) して、グローバルな timer という変数をインクリメントするようにする。(F_CPU / 分周設定 / OCR0A) CTC のほうが自由に時間を設定できて楽

	/**
	 * timer interrupt
	 * CTC 16MHz / 64 / 250 = 1kHz = 1msec
	 */
	TCCR0A = 0b00000010;
	TCCR0B = 0b00000011;
	OCR0A  = 250;
	TIMSK0 = 0b00000010;
unsigned long timer;
ISR(TIMER0_OVF_vect) {
	timer += 100;
}

以下のようなマクロを用意して DURATION(msec) で、引数に与えた時間が timer 換算でいくつになるかを出す。浮動小数点演算を使った瞬間、出てくるバイナリサイズが長大になるのでそうならないようにしてる。

#define DURATION(msec) (unsigned int)(msec * 100)


delay_ms を実装する。_delay_ms におけるビジーループ部分が任意に書けるので、ここで usbPoll() をする。

void delay_ms(unsigned int t) {
	unsigned long end;
        cli();
	timer = 0;
        end = timer + DURATION(t);
        sei();
	while (timer <= end) {
		wdt_reset();
		usbPoll();
	}
}

これでナイーブに delay_ms() を使ったコードでも可読性と効率をそこそこ両立できそう。しかし、なんかもっといい感じにコード書けそう。。普通どうやるものなのかよくわからない。

I2C 液晶

デバッグするとき、何かしら文字を表示できるインターフェイスがないとつらいため導入。シリアルポートに出力してデバッグするのがたぶん一番楽なんだと思うけど、レベル変換が必要で手元にあるものではできなかった。


I2C を使うにあたって、原理を理解していないのと、なおかつそれを AVR で実現する方法がわからないのと、さらには「デファクトスタンダード」な通信プロトコルも存じあげないため、全ての箇所でハマりにハマった。チップは ATmega168P なのでそこまで細かい原理を知っていて実装できる必要はないけど、だいぶハマった。

やり終わってみれば、別に難しくはないんだけど、どこに問題の原因があるのかが、見える現象が少なすぎて大変だった。面倒でもいちいちLEDチカチカさせて動作確認をすべき。

以下に I2C 液晶 (アドレス 0x7c) を操作するコード。何をするにせよ、とにかくデータシートをよく読んで理解するのが大変に重要だと実感した。

#include <string.h>

#define START 0x08   
#define ReSTART 0x10   
#define MT_SLA_ACK 0x18   
#define MT_DATA_ACK 0x28   
   
#define MR_SLA_ACK 0x40   
#define MR_DATA_ACK 0x50   
#define MR_DATA_NACK 0x58   
   
#define SLA_W 0xA0   
#define SLA_R 0xA1   
#define ADDRESS 0x00   
#define DATA 0x55   

void Error () {
//	unsigned i = 0;
//	for (i = 0; i < 3; i++) {
//		set_bit(PINB, 0);
//		_delay_ms(500);
//		clear_bit(PINB, 0);
//		_delay_ms(500);
//	}
//	clear_bit(PINB, 0);
}

void i2c_start () {
	// start
	TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
	while (!(TWCR & (1<<TWINT)));
	if ((TWSR & 0xF8) != START) return Error();   
}

void i2c_stop () {
	TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWSTO);
}

unsigned char i2c_write (unsigned char data) {
	TWDR = data;
	TWCR = (1<<TWINT) | (1<<TWEN);
	while (!(TWCR & (1<<TWINT)));

	switch (TWSR & 0xF8) {
		case MT_SLA_ACK:
		case MR_SLA_ACK:
		case MT_DATA_ACK:
			return 1;
		default:
			Error();
			return 0;
	}
}

void display_write_instruction (unsigned char address, unsigned char data) {
	i2c_start();
	i2c_write(address);
	i2c_write(0b10000000);
	i2c_write(data);
	i2c_stop();
	_delay_ms(1);
}

void display_write_data (char* string) {
	unsigned int i = 0;
	unsigned int len = strlen(string);

	display_write_instruction(0x7c, 0b00000001);

	i2c_start();
	i2c_write(0x7c);
	i2c_write(0b01000000); // Co=0 RS=1

	for (i = 0; i < len && i < 8; i++) {
		i2c_write(string[i]);
	}
	i2c_stop();

	_delay_ms(1);

	i2c_start();
	i2c_write(0x7c);
	i2c_write(0b10000000); // Co=1 RS=0
	i2c_write(0b11000000); // set ddram address to line 2
	i2c_write(0b01000000); // Co=0 RS=1
	for (; i < len && i < 16; i++) {
		i2c_write(string[i]);
	}
	i2c_stop();
}

void display_init () {
	TWBR = 0x24;
	TWSR = 0b00000001;
	TWCR = 1<<TWEN;

	display_write_instruction(0x7c, 0b00111000); // function set to 0 (default)
	display_write_instruction(0x7c, 0b00111001); // function set to 1 (extended)
	display_write_instruction(0x7c, 0b00010100); // internal osc frequency
	display_write_instruction(0x7c, 0b01110000); // contrast set
	display_write_instruction(0x7c, 0b01010110); // power/icon/contrast control
	display_write_instruction(0x7c, 0b01101100); // follower control
	_delay_ms(300);
	display_write_instruction(0x7c, 0b00111000); // function seto to 0
	display_write_instruction(0x7c, 0b00001101); // display on/off control
	display_write_instruction(0x7c, 0b00000001); // clear all

	_delay_ms(10);
}

ハマり

ハードウェアが絡むコーディングは、一度ハマると

  • 配線ミス
  • コーディングのミス

のどちらで発生しているかの見極めができないとかなりつらい…… 配線ミスはあってはならないので、最初の段階でよくよく確認しておかないとあとあとつらい。どんなに確認しても確認したりないぐらい確認する必要がある。あと配線後は必ずテスターをあてたほうがいい……

USB コネクタのピンの半田付けを適当にしすぎたせいで、試している最中に1本がはずれて通信できなくなるということがあった。こういうアホみたいなことでもコーディングミスを疑ったりすると時間を食ってしまう。

PORTB, PINB

出力を操作したいときは PORTB なのに、PINB と書いていてしばらく気付かなかった。この場合、微妙に出力されたりされなかったり、みたいな不安定な挙動になって、全く動かないわけでもないのでなかなかコーディングミスであることに気付けない。

Mac 環境で Ruby + libusb を使って HID デバイスを操作する

最初は feature レポートだけでごにょごにょしていたのでよかったけど、インタラプト転送をしようとしたところで、claim_interface が ERROR_ACCESS エラーを出して止まることがわかった。ググった感じだと、HID デバイスの場合、そのへんの処理を OS のドライバが握っているため、ユーザレベルだと直接扱えないらしい。

とりあえずどうしようもないっぽいので、feature レポートだけで情報をやりとりするように変えた。現状のプログラムだとそれでも問題がないっぽい。

2013年 10月 11日

無線局運用規則の読み方

アマチュア局は、第8章とそこから示されている第4章だけ読めばいい。ぼーっとしていて、ほかの章をうかつに読むと微妙に違う規則があって紛らわしいので、読みかたに注意する必要がある。

http://www.tele.soumu.go.jp/search/area/all_index.htm

法規:特性周波数・割当周波数・基準周波数

ひととおり法規をやってみると、この3つがどうしても意味不明だった。

電波法施行規則 第二条

五十六  「割当周波数」とは、無線局に割り当てられた周波数帯の中央の周波数をいう。
五十七  「特性周波数」とは、与えられた発射において容易に識別し、かつ、測定することのできる周波数をいう。
五十八  「基準周波数」とは、割当周波数に対して、固定し、かつ、特定した位置にある周波数をいう。この場合において、この周波数の割当周波数に対する偏位は、特性周波数が発射によつて占有する周波数帯の中央の周波数に対してもつ偏位と同一の絶対値及び同一の符号をもつものとする。
五十九  「周波数の許容偏差」とは、発射によつて占有する周波数帯の中央の周波数の割当周波数からの許容することができる最大の偏差又は発射の特性周波数の基準周波数からの許容することができる最大の偏差をいい、百万分率又はヘルツで表わす。
|

http://law.e-gov.go.jp/htmldata/S25/S25F30901000014.html

割当周波数、特性周波数はなんとなくわかるような気がするけど、基準周波数の説明が意味不明すぎる。そのうえで、「周波数の許容偏差」を読むと、全く意味がわからない。

ググってみたり、よく理解に努めようとして要約すると以下のようになるようだ。

  • 特性周波数 → 外部から測定できる周波数 (実際出てる電波の周波数)
  • 割当周波数 → 免許状に書かれているやつ。アマチュアの場合帯域が広いのでイメージしずらい。許可された帯域の中央の周波数
  • 基準周波数 → 無線機に表示されている周波数

こう考えたうえで

五十九 「周波数の許容偏差」とは、発射によつて占有する周波数帯の中央の周波数の割当周波数からの許容することができる最大の偏差又は発射の特性周波数の基準周波数からの許容することができる最大の偏差をいい、百万分率又はヘルツで表わす。

は言葉のイメージさえ掴めれば、あとよく読めば実用上(?)十分に理解できるレベルになる

  • 発射した電波と割当周波数とを比べた値 (発射した電波が占有する周波数帯の中央の周波数、割当周波数)
  • 外部から観測できる周波数と無線機が表示している周波数を比べた値 (特性周波数、基準周波数)

が、一定の許容範囲にあること。現実と理想を比べてる。搬送波ありの信号で考えたら言葉さえわかれば言ってることは難しくない。

しかし、「発射によつて占有する周波数帯の中央の周波数」と「特性周波数」の違いがわかりにくい。AM (A3E) の場合はどちらも一緒になりそうだけど、単側波帯の場合は違いそう。USB の場合上にずれるのかな。調べてもよくわからなかった。