2014年 11月 19日

RC サーボの制御

 -

4.0 / 5.0

いくつかサーボモータを購入していたのだけど、ようやく試した。持っているのは上記 SG90 と GWS03T/2BBMG/JR。どちらも動かしてみた。

これらはどちらも JR というタイプ (ピンアサインの種類)。種類はこのページの線のタイプついてを見た。

典型的なプロトコルとしては 20ms ごとに 1000μs〜2000μs (1500μs が中立) のパルスを送るというものらしい (可動角度60度)。

とりあえず試そうと、16bit PWM タイマーを使ってやってみた。

#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>

#define clear_bit(v, bit) v &= ~(1 << bit)
#define set_bit(v, bit)   v |=  (1 << bit)

#define INPUT_NOR PB0
#define INPUT_REV PB1

static inline void setup_io () {
	/**
	 * Data Direction Register: 0=input, 1=output
	 * 必要なポートだけインプットポートにする。
	 */
	DDRB  = 0b11111100;
	DDRC  = 0b11111111;
	DDRD  = 0b11111111;

	PORTB = 0b00000011;
	PORTC = 0b00000000;
	PORTD = 0b00000000;

	uint16_t TIMER1_MODE = 14;
	TCCR1A = (0<<COM1A1) | (0<<COM1A0) | (1<<COM1B1) | (0<<COM1B0) | (((TIMER1_MODE>>1)&1)<<WGM11) | ((TIMER1_MODE&1)<<WGM10);
	TCCR1B = (((TIMER1_MODE>>3)&1)<<WGM13) | (((TIMER1_MODE>>2)&1)<<WGM12) | (0<<CS12) | (1<<CS11) | (0<<CS10);
	ICR1   = 20000; // Top
	OCR1B  = 1500;
	TIMSK1 = (0<<OCIE1B) | (0<<OCIE1A) | (0<<TOIE1);

	sei();
}

static inline void set_position(uint16_t angle) {
	int base = 600;
	int max  = 2400;
	uint16_t n = ((uint32_t)angle * max) / 180 + base;
	if (n < base) {
		n = base;
	} else
	if (n > max) {
		n = max;
	}
	OCR1B = n;
}

int main(void) {
	setup_io();
	set_position(0);

	for (;;) {
		if (bit_is_clear(PINB, INPUT_NOR)) {
			set_position(0);
		}

		if (bit_is_clear(PINB, INPUT_REV)) {

			set_position(180);
		}

		_delay_ms(10);
	}
}

ハマったポイント

可動角度

ググると 1000μs〜2000μs のパルスというサイトばかりヒットするが、これは可動角度60度の場合で、実際は 600us〜2400μs までのパルスを受け付け、180度可動可能なものが多いみたい? よくわからないけど、手元の2種類についてはだいたいこの範囲のパルスを受けつけた。範囲外のパルスを入力すると「ジジジジ」とか「ブブブブ」とかいって止まり、消費電力が多くなる。

電圧

電圧が足りないと、指定した角度付近まで移動したあと「ジジジジ」と止まってしまうことがあった。

制御方法

16bit PWM だと1つの AVR で2つまでしか駆動できないので、割込みを使った別の方法を検討してもよさそう。

Arduino だと特に何も考えなくてもたくさんサーボを制御できるみたい。

2014年 11月 17日

秋月の小型 USB Serial 基板とタカチの小型ケースがぴったり

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

最近「超小型USBシリアル変換モジュール」というのが秋月から出たみたいで、買ったのはいいけど、そのままだとちょっと使いにくいわけです。 ケースに組込むにしても MicroUSB だし取り付け用の穴もあいてないので難儀する。ブレッドボードで使うのがメインの用途なんでしょうけど…

なんかいいのないかと思いましたが、タカチ SW-20 (15x15x20) を買ってみたら完全にピッタリだったのでオススメです。ケースの蓋についている溝にピッタリハマってくれるサイズなので、ケースを少し削るだけで MicroUSB にアクセスでき、適当にエポキシで固めてしまえば便利。一応電源LED用の穴もあけたけど、なくてもよさそう。

KX3 でシリアルポートから SWR を読み出す

KX3 と PC だけで SWR グラフにできたら便利なのになー と思っていたけど、少し前に調べたところ SWR を直接読む方法がなく、諦めていた。

しかし、KX3 Utility で Power Calibration を実行すると、SWR を読んでいるっぽい挙動が確認でき、読める方法があるということがわかった。KX3 Utility は親切にも全部のコマンドを出力してくれてるので、それを読んだだけでうまいこといけた。

やりかたとしては

  • TUNE ボタンを押す (SWH16; スイッチホールド)
  • ディスプレイに現在の SWR が表示される
  • DS; で「ディスプレイに表示されている内容」を取得する
  • SWR とれる

という感じだった。いろいろとコードを追加して、現在周波数の±を指定してSWRを取得するコードを書いてみた。結構いい感じ

#!ruby

require 'serialport'

@port = SerialPort.new(
	"/dev/tty.usbserial-A402PY11",
	38400,
	8,
	1,
	0
)
@port.set_encoding(Encoding::BINARY)

TEXT_MAP = {
	'<' => 'L',
	'>' => '-',
	'@' => ' ',
	'K' => 'H',
	'M' => 'N',
	'Q' => 'O',
	'V' => 'U',
	'W' => 'I',
	'X' => 'c-bar',
	'Z' => 'c',
	'[' => 'r-bar',
	'\\' => 'λ',
	']' => '',
	'^' => '',
}

def get_swr(step=3)
	ret = 0
	step.times do 
		@port << "DS;"
		data = @port.gets(";")
		t, a, f = *data.match(/DS(........)(.)(.)/).captures
		t = t.split(//).reduce("") {|r, i|
			chr = (i.ord & 0b01111111).chr
			r << ( ( (i.ord & 1<<7) != 0) ? ("." + chr) : (chr) )
		}.gsub(Regexp.new(TEXT_MAP.keys.map {|i| Regexp.escape(i) }.join("|")), TEXT_MAP)
		# KX3 displays SWR to main display as following : "1.2-1"
		if m = t.match(/([\d]+.[\d]+)-I/)
			swr = m[1]
		else
			return nil
		end
		ret += swr.to_f
		# p [t, a, f, swr]
	end
	ret / step
end

def get_freq
	@port << "FA;"
	res = @port.gets(";")
	freq = res.match(/FA(\d{11})/)[1].to_i
end

def set_freq(freq)
	@port << ("FA%011d;" % freq)
	get_freq == freq or raise "Failed to set freq"
end

def bypass_atu(&block)
	@port << "MN023;"
	@port << "MP;"
	current = @port.gets(";")
	current =~ /^MP\d{3}/ or raise "Unknown Responde #{current}"
	@port << "MP001;MP;"
	res = @port.gets(";")
	res == "MP001;" or raise "Failed to set KAT3 bypass: #{res}"
	@port << "MN255;"
	block.call
ensure
	@port << "MN023;"
	@port << current
	@port << "MN255;"
end

def tune(&block)
	# Switch Hold Emulation 16 = TUNE
	@port << 'SWH16;'
	sleep 0.5
	@port << 'TQ;'
	@port.gets(";") == 'TQ1;' or raise "Band END"
	sleep 0.3
	block.call
ensure
	@port << "RX;"
	sleep 0.5
	@port << "TQ;"
	@port.gets(";") == 'TQ0;' or raise "Failed to back to RX"
end

def scan_swr
	result = []
	@port << "PC;"
	current_power = @port.gets(";")
	@port << "PC001;PC;"
	@port.gets(";") == "PC001;" or raise "Failed to set power"
	bypass_atu do
		freq = get_freq
		step = 20e3
		range = Range.new(freq - 100e3, freq + 100e3)
		
		catch(:done) do
			begin
				set_freq(range.first)
				tune do
					range.step(step) {|n|
						set_freq(n)
						swr = get_swr(3)
						if swr.nil?
							throw :done
						end
						r = [n, swr]
						p r
						result << r
					}
				end
			rescue => e
				if e.message = "Band END"
					range = Range.new(range.first + step, range.last)
					retry
				end
			ensure
				set_freq(freq)
			end
		end
	end
	result
ensure
	@port << current_power
	@port << "PC;"
	@port.gets(";") == current_power or raise "Failed to back to power"
end

p scan_swr
2014年 11月 15日

RaspberyPi 用の WiFi アダプタ探し。または GW-USNANO2A が切れまくるのをなおす

 -

2.0 / 5.0

WLI-UC-GNM を使ってたんだけど、24時間つけっぱなしのサーバみたいな用途だと、過熱しすぎて止まってしまうことが多々あり、ぶっちゃけ使いもんにならんよ! という感じだった。つけっぱにしないなら使えるんだけど……

ので、GW-USNANO2A を買ってみた。

 -

3.0 / 5.0

が、めちゃくちゃ接続が切れまくる。

ping を打ち続ければ大丈夫なので、またパワーマネジメント系の問題か…と思ったが、iwconfig の結果は Power Management:off となっており、よくわからなかった。

調べてみると、このドライバに関してはカーネルモジュールに対するオプションによってパワーマネジメントを決めるらしい……

現在の状態は sysfs を通し

$ cat /sys/module/8192cu/parameters/rtw_power_mgnt 
1

で確認できる。1 だとパワーマネジメントが効いている。

$ sudo su
# echo 'options 8192cu rtw_power_mgnt=0' > /etc/modprobe.d/8192cu.conf
# reboot

すると、パワーマネジメントを切って起動させることができる。

$ cat /sys/module/8192cu/parameters/rtw_power_mgnt 
0

これで切れることがなくなった。

2014年 11月 12日

USB 電圧・電流計

【ノーブランド】 USB簡易テスター ストレート型 - ルートアール

ルートアール

5.0 / 5.0

これ安いし1個あるととても便利。USB 充電がちゃんと急速充電になっているか? とか実測でわかる。

充電専用というわけではなくて、普通の USB 機器に挟んでも使えるので、どのUSBデバイスがどれぐらい電力食っているかを実測できる。

似たようなのを自分で作ろうかと思っていたけど、買ったほうが遥かにやすい例

2014年 11月 11日

自作デジタル SWR 計 (進行波・反射波電力計)


しばらく試行錯誤していたが形になった。

追記: より高性能なタイプのSWR計も作りました

SWR 計

SWR は計るものというより、進行波と反射波の関係を計算して出すものなので、正確にいうなら進行波・反射波電力計といえそう。

進行波と反射波を分けるためには、方向性結合器 (Directional Coupler) というものを使う。

SWR 計に使う方向性結合器にもいろいろあって、市販されているもので主流なのは CM結合型 (容量・相互インダクタンス結合 / Bruene Coupler など) のものだけれど、今回タンデムマッチ (Tandem match coupler / Sontheimer bridge) と呼ばれているものを試す。

Wikipedia だと Cross-connected transformers という形の方向性結合器を使うもので、ARRL がドキュメントを出したことがあり、英語の記事だと良く使われているのを見る (逆に日本語のリソースは大変少ない)

CM結合型と比べると以下のような違いがありそう。

メリット

  • 回路が対称かつトランスしか接続されないのでシンプル
  • ダイナミックレンジが広い (うまく作れば QRP〜1kW まで計れる)
  • 検出部には調整点がない (トリマとかがいらない)
  • 方向性 (Directivity) に優れる (測定誤差が少ない)

デメリット

  • 2つのトランスの結合を疎にするため、比較的大きく作らざるを得ない
  • 結合器そのもののSWRがあまり低くない。(リターンロスが多きくなりやすい)

その他特徴

  • 最低周波数と挿入損失はトランスのインピーダンスで決まる(コアのAL値と巻き数)
  • 最高周波数はトランスの浮遊容量で決まる (巻く導線の長さ = コアの大きさと巻き数)
  • トランスの巻き数に比例した電圧出力(巻き数の自乗に比例した電力出力)

つまり以下のようなトレードオフがある

  • 最低周波数を下げるために巻き数を増やすと最高周波数が下がる
  • 最大電力をあげるためコアを大きくすると最高周波数が下がる
  • 最大電力をあげるために巻き数を増やすと、最小電力が計りにくくなる

CM 結合型は浮遊容量・インダクタンスの影響が大きくでやすいので、アマチュア的にはタンデムマッチのほうが作りやすいのかな?

検出部

コアにはまず鉄粉コアの T68-2 (AL=5.7) を使った。30Tだと実測で約5.5uHとなり、7MHz で約230Ω、3.5MHz で 約110Ω程度のインピーダンスになる。

挿入損失はコイルのインピーダンスで決まり150Ω (伝送路インピーダンスの3倍) 以上が望ましいらしい。つまり 3.5MHz だと厳しい?

30:1 のトランスを使うと、電力は巻数の二乗に比例 (電圧比の二乗) なので dB になおすなら

になる。100W 時に 0.11W (900分の1) ほどとりだす。(この分は確実に挿入損失となる)

タンデムマッチだと出力インピーダンスも50Ωになるので、50Ωのダミーロードにかけて、かかった電圧をはかる。だいたい 0.2W 以上、0.5W ぐらいの定格が必要。200Ω 1% の1/4W金属皮膜抵抗を4つ並列にした。

なので、100W で 50Ωの場合は約 2.34V ほど。1W で約0.235V が出力される。

ADC にかける前に検波 (直流にするということ) とバッファをする。ショットキーかゲルマニウムダイオードと 0.01uF 程度のコンデンサ。ダイオードはVfができるだけ低いものにしないと小電力域で計れなくなる。コンデンサはバイパスコンデンサとして働くので、最短で配線する必要がある。

検波後は直流で、$ \sqrt{2} $ 倍の電圧が出力される (ダイオード検波は単に整流回路で、通ると交流最大電圧に近づく)。バッファ用のオペアンプはなんでもよさそう。ユニティゲインで使える安いのを使う (電源電圧を 3.3V にしたので Rail to Rail なオペアンプでないとダメだった)。

直流としては 100w で約3.3V、50W で約2.4V、1Wで約0.3V得られる。

製作

製作一発で一応ちゃんと動いていそうな動作をした。

30T で作ったが、ダミーロードを接続してこの装置自体の SWR (リータンロス) を計ったところ、3.5MHz で思ったより厳しく(SWR 1.3ぐらい)なってしまったので、40T 巻いたほうがよかった気がする。他の50MHz までの周波数ではSWR 1.1ぐらいで、あんまり良くはない。

特性

まず方向性結合器としての特性をはかる。

InsertionLoss は低いほど良い。Isolation は高いほど良い。Directivity も高いほど良い。

SWR を計るなら Directivity は 25dB 以上が必要

蓋をあけた状態で測定してる。

7MHz (50W)

  • IN: 51.0V
  • OUT: 50.90V
  • FWD: 1625mV
  • REF: 51mV

{"InsertionLoss"=>0.017047875223552212, "Coupling"=>-29.935364253260417, "Isolation"=>-60.00167004225055, "Directivity"=>-30.06630578899013}

50MHz (50W)

  • IN: 53.4V
  • OUT: 48.5V
  • FWD: 1987mV
  • REF: 477mV

{"InsertionLoss"=>0.8359903685258546, "Coupling"=>-28.586867798374822, "Isolation"=>-40.980457559768844, "Directivity"=>-12.393589761394026}

50MHz での性能が悪い


0.1dB 以下の挿入損失ならメーカー製品に劣らないが、50MHz ではかなり微妙。

コアの変更

全体的にリターンロスが少し高く、3.5MHz で微妙なのと、50MHz での性能の悪さを改善できないかと思いコアを変えてみた。

FT82-43 (AL= 470) に 30T 巻くとインダクタンスは370uHぐらいになる。数kΩのインピーダンスになる。ちょっと多すぎる気がするのと、FT82-43 だと磁気飽和しそうだなと思いつつ試した。一般的にタンデムマッチに使われるコアに比べかなり透磁率が高い。

結果的に 50W までなら特に発熱などの問題なく動いてくれた。

リターンロスは全域で劇的に改善し、殆ど SWR にして 1.05〜1.15 未満になった。

しかし高透磁率のフェライトコアの場合個体差が多く (AL値にして±20%の個体差がある)、完全に同じトランスを作るのが難しい。バランスが崩れて方向性が悪化している気がする (それでも鉄粉コアよりマシ)。できればコアのマッチドペアをとったほうがいいかもしれない。

これでも 50MHz ではあまり優秀とは言えない。浮遊容量のほうが問題なのだろう。20T〜25T でいいかもしれない。また、50MHz の場合ダミーロード自体のリターンロスが無視できないので、実際の方向性はもっとマシだと思われる。

FT82-61 (AL= 79) のほうが透磁率がちょうど良さそうだけど、手元になかった。自分みたいに、そこまで電力かけねーよっていう場合は43材でもいいかもしれない。重大な特性悪化があるので、やはり61材のほうが良いようです

7MHz (50W)

  • IN: 50.92V
  • OUT: 50.88V
  • FWD: 1683mV
  • REF: 46mV

{"InsertionLoss"=>0.006825846825207417, "Coupling"=>-29.61608558011588, "Isolation"=>-60.88261126600088, "Directivity"=>-31.266525685885}

50MHz (50W)

  • IN: 52.17V
  • OUT: 50.43V
  • FWD: 1743mV
  • REF: 303mV

{"InsertionLoss"=>0.2946373712648287, "Coupling"=>-29.52246899224763, "Isolation"=>-44.7195641644014, "Directivity"=>-15.197095172153766}

デジタル部

まじめに計測器を作りたいわけではないので、カジュアルに ADC は AVR 内蔵の 10bit のものを使う。AVR の ADC は複数チャンネルがあるが同時に計測できるわけではないので、FWD/REF の計測には時間差が生じる。が、特に問題ないと思う。

2.465V のシャントレギュレータで基準電圧をつくるとちょうどいい。10bit だと分解能は $ 2.456 / 1024.0 = 0.00239V $ になる。0.1mW ぐらい。

グラウンドを分離したいが、作例だとあまりやっているのがないので、とりあえずは入れず。検出部から引き回す部分でチョークコイルいれるのが良さそう。

ADC の多少の変換誤差はともかく、デジタル回路からアンテナ側にノイズが入るのだけは防ぎたいところ。ノウハウがなくて難しい。デジタル回路をできるだけ閉じこめる形での対応を行ってみる。

機器連携

シリアル出力ポートをフォンプラグで出すのが最も楽っぽいのでそうした。

回路図

キャリブレーション

シリアル経由で特定のコマンドを入力すると、ADC 電圧をそのまま出力するようにしたので、そのモードにして送信しつつ表を作り。適当な値を選んで Maxima に連立方程式を解かせて校正値を求めた。

これでだいたい誤差は10%程度。あんまり良くない気がするが、メーカー製でも(フルスケールに対して)このぐらいなので、めちゃくちゃ悪くはなさそう。

さらに

50MHz での特性がやはりいまいちなので、

  • コアを変える
  • 巻数を変える

をやる気になったらやりたい。また、精度をあげるため

  • 検出器内で ADC まで行い I2C か何かで出力する

とかやる気になったらやりたい。

ref

asin:B002E9GG6M:detail 4

2014年 11月 05日

貴様はピカールを知っているか

日本磨料工業 ピカール 金属磨き 300g 12100 - 日本磨料工業(Nihon Maryo Kogyo)

日本磨料工業(Nihon Maryo Kogyo)

5.0 / 5.0

人生報われないことばかりで嫌になってしまうが、そんな世の中にも確実に報われる努力というものが存在する。ピカールはその1つだ。

ピカールはその名の通り金属を磨いてピカ〜ルさせるものである。350円で一生分ぐらいの磨き成分を得らえる恐しくコストパフォーマンスに優れた液体である。人によっては「小学生のとき流行っていた!」という、古くからかつ有名な実績ある液体である。ちなみに白濁していてドロドロしている。そして灯油の臭いがする。

無心で何かに熱中することはストレス解消のいい方法であると云われる。ピカールはきっとそれを助けてくれるだろう。

ピカール前

#1500 の耐水ペーパーで大部分を磨いてしまったので結構綺麗に見えるが、元々はもっとくすんでいた。

ピカール後

全体的にピカールしたことによって明かに輝きを得られた。(土台の色は変わっているのは塗ったからでピカールの効果ではない)

長い間使っていなくて表面が酸化してしまった接点とかもちょっと拭くだけで完全に復活する。手元にも導通しづらいACアダプタのコネクタがあったのでやってみたが完全に復活した。最高。

他、ピカールで画像検索したほうがもっと良いものが見られる。

なお完璧に鏡面にするなら順を追って磨く必要がある。

SK11 耐水ペーパーミニセット 30枚入り #400 #1000 #1500 76×140mm タイスイC#セット - SK11(エスケー11)

SK11(エスケー11)

5.0 / 5.0

2014年 10月 29日

ステッピングモーター (パルスモーター)

ステッピングモーターの説明は JRC のドキュメントがわかりすい
http://semicon.njr.co.jp/jpn/PDF/application_notes/Stepper_Motor_Basics_APP_J.pdf
基本的にプルイントルク(負荷ありで脱調せずに始動・停止ができる範囲)がまず重要で、プルアウトトルク(加速して慣性がついた状態で脱調せずにパルスに応答できる範囲)は高速で動かしたいときにだけ考える。

モーターの特性グラフを見て、必要なトルクを得るときの最大周波数 (Hz または pps) を読む。それを1回転あたりのステップ数で割れば1秒間に何回転させられるかがわかる。

例えば、1回転あたり360ステップ(つまり1°/step) のモーターで、最大 720Hz までなら必要トルクが得られる場合だと、1秒に2回転が限界になる (120rpm)。

2014年 10月 22日

golang / cgo で homebrew で入れたライブラリが見つからない場合

golang で cgo 使ってる感じのやつが include やライブラリリンクまわりでエラった場合

export CGO_CFLAGS="-I/usr/local/include"
export CGO_LDFLAGS="-L/usr/local/lib"


とかしとけばいいみたい

2014年 10月 13日

KX3 実測消費電力

バックライトなし・プリアンプあり・ IQ出力ありでの測定 電源電圧は約12V (ポータブルバッテリー前提での計測)

バンドごとに違い、基本的には高い周波数ほど増える。

受信時

  • 1.9MHz 0.183A
  • 3.5MHz 0.179A
  • 7MHz 0.181A
  • 10MHz 0.185A
  • 14MHz 0.188A
  • 18MHz 0.190A
  • 21MHz 0.192A
  • 24MHz 0.196A
  • 28MHz 0.198A
  • 50MHz 0.230A

送信時

  • 送信時の電圧が11Vを切ると出力が5Wに制限される
  • 電圧が13V以上の場合HF帯は12Wまで設定できる

SWR が悪化すると消費電力も増えるっぽいが、とりあえずダミーロードでの測定

10W

50MHz は 8W までしかでない (説明書通り)

  • 50MHz 2.39A (8W)
  • 28MHz 2.36A
  • 24MHz 2.72A
  • 21MHz 2.40A
  • 18MHz 2.30A
  • 14MHz 2.14A
  • 10MHz 2.10A
  • 7MHz 2.05A
  • 3.5MHz 2.31A
  • 1.9MHz 2.21A

なぜか 24MHz の効率が悪い。

5W

  • 50MHz 2.15A
  • 28MHz 1.41A
  • 24MHz 1.98A
  • 21MHz 1.22A
  • 18MHz 1.25A
  • 14MHz 1.17A
  • 10MHz 1.34A
  • 7MHz 1.72A
  • 3.5MHz 1.20A
  • 1.9MHz 1.39A

3W

3W が最も効率が良いらしいので計ってみた。1Wあたりの消費電力と考えると、別にそんなことなさそう。

  • 50MHz 1.73A
  • 28MHz 1.17A
  • 24MHz 1.20A
  • 21MHz 1.04A
  • 18MHz 1.06A
  • 14MHz 0.97A
  • 10MHz 0.95A
  • 7MHz 0.92A
  • 3.5MHz 0.99A
  • 1.9MHz 1.06A

ref.

8 V min, 15 V max. 1 to 2 A typical in transmit; 150 mA minimum receive, typical
(backlight off, preamp off, no signal)