SDカードなどを接続したとき、使ってもいない写真.appがいちいち起動してだいぶ鬱陶しいです。以下のコマンドで止めることができました。
defaults -currentHost write com.apple.ImageCapture disableHotPlug -bool YES
昔は Image Capture.app の環境設定からデフォルトの設定が変えられたはずなんですが、El Capitan ではその機能が消滅していて、GUI で変更する方法がないようです。クソですね。
SDカードなどを接続したとき、使ってもいない写真.appがいちいち起動してだいぶ鬱陶しいです。以下のコマンドで止めることができました。
defaults -currentHost write com.apple.ImageCapture disableHotPlug -bool YES
昔は Image Capture.app の環境設定からデフォルトの設定が変えられたはずなんですが、El Capitan ではその機能が消滅していて、GUI で変更する方法がないようです。クソですね。
普段からほとんど常時に「バカにされている」と感じている。基本的には特定の誰かというわけではない。ただしコンテキストによっては特定の誰かの顏が頭に浮かんでいることもある。とはいえそれも、特定の誰かが事実として常に罵倒してくるわけではない。
普通に生きていると、自分の意見というのは、ほとんど尊重されない。自分の中でこの感覚が消化された結果「バカにされている」という主観ができあがるのだろうと思う。
「尊重されなさ」はあらゆることで感じられる。
煙草、特に路上喫煙に殺意(文字通り。)が沸くのはなぜかといえば、臭い煙に困っている自分が尊重されていないと感じるからだと思う。ここで大事なのは、実際にそれをしている喫煙者が尊重してくれないということではなく、そういう喫煙者の存在を許していて、なおかつ自分の存在を許さない(と主観的に感じる)社会が尊重してくれない、ということである。
社会に自分が尊重されていないというのは、自分の存在が否定されていることと同じことです。
自分の中で全ての「尊重されなさ」は社会と通じて繋がっている。仕事で尊重されなくても、道を歩いていて尊重されなくても、それらは繋がっており、自分の中で消化され、バカにされたと感じるわけです。
なんとなく思いたったので Twitter 使うのをやめてみることにします。ここ最近のこと考えてみると、特に Twitter を使っていて得るものはないのではないか、という気がしてきました。
何か思うことがあれば日記として書こうと思います。
はてブもやめて、日記にリンクと思うところを書いたほうがいいかもしれません。そのリンクは日記に書くほどのことなのかを一旦考えてみてもいい気がします。
この日記は tech タグか photo タグ、またはアマゾンの商品リンクが含まれている場合しか Atom フィードにコンテンツを出さないようになっています。なので、クソのような日記エントリをいくら書いても誰にも迷惑になるようなことはありません。
日記はそもそも情報としての価値は低いですから、フィードリーダーで読むようなものではないという気がします。「ウェブサイトを開いて読む」というコンテキストが共有されていないと、変なことを言いだす人もいるので (メディアによって読み手が受けとるイメージが変わってしまい、フィードリーダーだと押し付けがましくなる)、このようになっています。
こういう変な仕様のブログシステムというのはASPではまずありえませんから、やはり自分でブログシステムを作っておくというは、良いと思います。
IrKit を cron から読んで朝起きたとき部屋が暖かくなるようにしていましたが、暖くなってきたので、一旦止めました。
cron の有効無効を手動でやっててアホらしいので温度センサーと連携したいところです。
定本トランジスタ回路の設計 続 (定本シリーズ) cho45
一回図書館で借りて一通り読んだのですが、トランジスタ回路の定番パターンと設計方法が一通りまとまっているのがほかになく、参照したいと思うことが多々あるので、買うことにしました。
これこそ電子書籍でPDFになっていてほしいのですが、Tech Villageにはないようです。改訂してPDFにして欲しいです。
ebay で800円ぐらいで買ったものです。
この手のモジュールにはAD9851(源クロック6倍周波数逓倍器付き)のものとAD9850のものがあり、さらに基板のタイプが2つあります。AD9850/AD9851は制御方法も含めてほとんど互換なので、源クロックとチップだけ違うものが出回っているみたいです。
試してみたのはおそらく古いタイプのもので、ブレッドボードには直接挿すことができないので、ちょっと面倒くさいタイプです。
周波数の設定・パワーダウンモードへの移行・設定位相(2台以上のDDSでsin/cos作る場合に使う)を40bitレジスタにまとめて突っ込む形になっています。
この40bitレジスタはパラレルモードとシリアルモードで設定でき、ググると大抵の例でシリアルモードを使ってるみたいです。
ただ、リセット直後はパラレルモードで起動するので、シリアルモードに変えてやる必要があります。といっても、D0=1 D1=1 D2=0 にした状態で、W_CLK パルスを送り、すぐ FQ_UD パルスを送るとシリアルモードに入るということになっています。
このモジュールの場合、ジャンパでD0=1 D1=1 D2=0 を設定できるようになっており、デフォルトでジャンパしてあるので、W_CLK と FQ_UD パルスをマイコンから送るだけで初期化できます。
ライブラリみたいにしてあるのもありましたが、結局自分で書きました。
入手したモジュールは125MHzが源クロックでした。
#include <Arduino.h>
#include <Wire.h>
template <uint32_t CLKIN>
class AD9850 {
static constexpr double PHASE_FACTOR = 0x100000000 / (double)CLKIN;
const uint16_t PIN_DATA;
const uint16_t PIN_FQ_UD;
const uint16_t PIN_W_CLK;
const uint16_t PIN_RESET;
void serial_write(uint32_t freq, uint8_t phase, bool powerdown) {
// freq (delta phase)
for (int i = 0; i < 32; i++) {
digitalWrite(PIN_DATA, (freq>>i) & 1);
digitalWrite(PIN_W_CLK, HIGH); delayMicroseconds(4);
digitalWrite(PIN_W_CLK, LOW); delayMicroseconds(4);
}
// control bits
digitalWrite(PIN_DATA, LOW);
digitalWrite(PIN_W_CLK, HIGH); delayMicroseconds(4);
digitalWrite(PIN_W_CLK, LOW); delayMicroseconds(4);
digitalWrite(PIN_W_CLK, HIGH); delayMicroseconds(4);
digitalWrite(PIN_W_CLK, LOW); delayMicroseconds(4);
// powerdown
digitalWrite(PIN_DATA, powerdown ? HIGH : LOW);
digitalWrite(PIN_W_CLK, HIGH); delayMicroseconds(4);
digitalWrite(PIN_W_CLK, LOW); delayMicroseconds(4);
// phase
for (int i = 0; i < 5; i++) {
digitalWrite(PIN_DATA, (phase>>i) & 1);
digitalWrite(PIN_W_CLK, HIGH); delayMicroseconds(4);
digitalWrite(PIN_W_CLK, LOW); delayMicroseconds(4);
}
digitalWrite(PIN_FQ_UD, HIGH); delayMicroseconds(4);
digitalWrite(PIN_FQ_UD, LOW); delayMicroseconds(4);
}
public:
AD9850(
uint16_t data,
uint16_t fq_ud,
uint16_t w_clk,
uint16_t reset
) :
PIN_DATA(data),
PIN_FQ_UD(fq_ud),
PIN_W_CLK(w_clk),
PIN_RESET(reset)
{
pinMode(PIN_DATA, OUTPUT);
pinMode(PIN_FQ_UD, OUTPUT);
pinMode(PIN_W_CLK, OUTPUT);
pinMode(PIN_RESET, OUTPUT);
}
/**
* W0 ... W31 -> Freq (LSB first)
* W32, W33 -> Control (for factory test)
* W34 -> Power-Down
* W35 ... W39 -> Phase (LSB first)
*/
void reset() {
// ensure low
digitalWrite(PIN_DATA, LOW);
digitalWrite(PIN_FQ_UD, LOW);
digitalWrite(PIN_W_CLK, LOW);
// reset
digitalWrite(PIN_RESET, HIGH); delay(1);
digitalWrite(PIN_RESET, LOW); delay(1);
// reset to serial mode
// Pins of D0, D1 = HIGH, D2 = LOW for serial mode
digitalWrite(PIN_W_CLK, HIGH); delayMicroseconds(4);
digitalWrite(PIN_W_CLK, LOW); delayMicroseconds(4);
digitalWrite(PIN_FQ_UD, HIGH); delayMicroseconds(4);
digitalWrite(PIN_FQ_UD, LOW); delayMicroseconds(4);
}
void set_frequency(uint32_t frequency) {
set_frequency(frequency, 0);
}
void set_frequency(uint32_t frequency, uint8_t phase) {
uint32_t deltaPhase = PHASE_FACTOR * frequency;
serial_write(deltaPhase, phase, 0);
}
void powerdown() {
serial_write(0, 0, 1);
}
};
AD9850<125000000> ad9850(9, 10, 11, 12);
void setup() {
Serial.begin(9600);
ad9850.reset();
ad9850.set_frequency(10e6);
}
void loop() {
} 商品説明だと40MHz まで出せると書いてありました。たしかに出せることは出せるようです。
このモジュールの出力には7次のローパスフィルタがついています。これはAD9851のデータシート通りの定数のフィルタのようで、70MHzぐらいにカットオフ周波数ががあるみたいです。
なおローパスフィルタの後の出力インピーダンスは200Ωになっているみたいです。
AD9850自体の出力は電流出力で、12ピンについている抵抗でフルスケールの出力電流が決まることになっています。このモジュールでは3.9kΩが実装されており、10mA フルスケールの出力に設定されています。200Ωで10mW(10dBm)。実際使う場合バッファして50Ω出力とする必要はありそうです。
片方だけにローパスフィルタが入っており、もう片方の出力は200Ωで電圧変換されて直接ピンヘッダに出ています。ということで差動出力には使えません。
AD9850 DDS モジュール に続き AD9851 で、別基板バージョンのものです。
ジャンパとかが一切ない簡略版?なのか進化版?でしょうか。
D0, D1 は 10kΩでプルアップされているので、これらは自分でプルアップする必要はありません。D2 を GND に接続するだけでシリアルモードに入れる実装になっています。
#include <Arduino.h>
#include <Wire.h>
template <uint32_t CLKIN, bool MULTIPLIER>
class AD9851 {
static constexpr double PHASE_FACTOR = 0x100000000 / (double)(CLKIN * (MULTIPLIER ? 6 : 1));
const uint16_t PIN_DATA;
const uint16_t PIN_FQ_UD;
const uint16_t PIN_W_CLK;
const uint16_t PIN_RESET;
void serial_write(uint32_t freq, uint8_t phase, bool powerdown) {
// freq (delta phase)
for (int i = 0; i < 32; i++) {
digitalWrite(PIN_DATA, (freq>>i) & 1);
digitalWrite(PIN_W_CLK, HIGH); delayMicroseconds(4);
digitalWrite(PIN_W_CLK, LOW); delayMicroseconds(4);
}
// control bits
digitalWrite(PIN_DATA, MULTIPLIER ? HIGH : LOW);
digitalWrite(PIN_W_CLK, HIGH); delayMicroseconds(4);
digitalWrite(PIN_W_CLK, LOW); delayMicroseconds(4);
digitalWrite(PIN_DATA, LOW);
digitalWrite(PIN_W_CLK, HIGH); delayMicroseconds(4);
digitalWrite(PIN_W_CLK, LOW); delayMicroseconds(4);
// powerdown
digitalWrite(PIN_DATA, powerdown ? HIGH : LOW);
digitalWrite(PIN_W_CLK, HIGH); delayMicroseconds(4);
digitalWrite(PIN_W_CLK, LOW); delayMicroseconds(4);
// phase
for (int i = 0; i < 5; i++) {
digitalWrite(PIN_DATA, (phase>>i) & 1);
digitalWrite(PIN_W_CLK, HIGH); delayMicroseconds(4);
digitalWrite(PIN_W_CLK, LOW); delayMicroseconds(4);
}
digitalWrite(PIN_FQ_UD, HIGH); delayMicroseconds(4);
digitalWrite(PIN_FQ_UD, LOW); delayMicroseconds(4);
}
public:
AD9851(
uint16_t data,
uint16_t fq_ud,
uint16_t w_clk,
uint16_t reset
) :
PIN_DATA(data),
PIN_FQ_UD(fq_ud),
PIN_W_CLK(w_clk),
PIN_RESET(reset)
{
pinMode(PIN_DATA, OUTPUT);
pinMode(PIN_FQ_UD, OUTPUT);
pinMode(PIN_W_CLK, OUTPUT);
pinMode(PIN_RESET, OUTPUT);
}
/**
* W0 ... W31 -> Freq (LSB first)
* W32, W33 -> Control (for factory test)
* W34 -> Power-Down
* W35 ... W39 -> Phase (LSB first)
*/
void reset() {
// ensure low
digitalWrite(PIN_DATA, LOW);
digitalWrite(PIN_FQ_UD, LOW);
digitalWrite(PIN_W_CLK, LOW);
// reset
digitalWrite(PIN_RESET, HIGH); delay(1);
digitalWrite(PIN_RESET, LOW); delay(1);
// reset to serial mode
// Pins of D0, D1 = HIGH, D2 = LOW for serial mode
digitalWrite(PIN_W_CLK, HIGH); delayMicroseconds(4);
digitalWrite(PIN_W_CLK, LOW); delayMicroseconds(4);
digitalWrite(PIN_FQ_UD, HIGH); delayMicroseconds(4);
digitalWrite(PIN_FQ_UD, LOW); delayMicroseconds(4);
}
void set_frequency(uint32_t frequency) {
set_frequency(frequency, 0);
}
void set_frequency(uint32_t frequency, uint8_t phase) {
uint32_t deltaPhase = PHASE_FACTOR * frequency;
serial_write(deltaPhase, phase, 0);
}
void powerdown() {
serial_write(0, 0, 1);
}
};
AD9851<30000000, true> ad9851(9, 10, 11, 12);
void setup() {
Serial.begin(9600);
ad9851.reset();
ad9851.set_frequency(10e6);
}
void loop() {
} AD9851 とほぼ同じですが、6倍の周波数逓倍器がの有効無効化のビットがあるので、その部分だけ実装を変えてあります。
購入したモジュールは 30MHz の源発振のものなので、逓倍後は 180MHz になります。
40MHz ぐらいから出力が低くなります。
逓倍している分スプリアスが多いようです。
ebay で見つけて買ったやつシリーズです。表題のようなものを買ったので動かしました。
https://github.com/adafruit/Adafruit_LED_Backpack が割とよくできていて、これ使えばすぐに動かせました。
#include <Arduino.h>
#include <Wire.h>
// https://github.com/adafruit/Adafruit_LED_Backpack
#include "Adafruit_LEDBackpack.h"
// Adafruit_LEDBackpack matrix = Adafruit_LEDBackpack();
Adafruit_8x8matrix matrix = Adafruit_8x8matrix();
void setup() {
Serial.begin(9600);
Serial.println("begin");
matrix.begin(0x70);
matrix.setBrightness(10);
matrix.setTextSize(1);
matrix.setTextWrap(false);
matrix.setRotation(1);
}
void loop() {
char* message = const_cast<char*>("Hello, World!\n");
int16_t x, y;
uint16_t w, h;
// getTextBounds は \n で終わってないと width を正しく計算しない。
matrix.getTextBounds(message, 0, 0, &x, &y, &w, &h);
Serial.println("getTextBounds: ");
Serial.print(" x = "); Serial.println(x);
Serial.print(" y = "); Serial.println(y);
Serial.print(" w = "); Serial.println(w);
Serial.print(" h = "); Serial.println(h);
Serial.println("");
for (int16_t x = 8; x >= -(int16_t)w; x--) {
matrix.clear();
matrix.setCursor(x, 0);
matrix.print(message);
matrix.writeDisplay();
delay(50);
}
}
BMP180 搭載のモジュールを ebay で買ってみたので試しました。約$2。どの気圧計にしろ温度計が必要で内部補正には使われていたりしますがだいたい内部用で外から値がとれません。このモジュールは温度もI2C経由で測れて一石二鳥モジュールです。
こんな感じのモジュールで、BMP180 以外に実装があります。これは 3.3V レギュレータで、5V 供給しても大丈夫なようになっています。(I2C のロジックレベル変換は簡易的ですが)。なので 5V の Arduino でも使えます。
BMP085 というものと互換性があるみたいで (BMP085はディスコン) それ用のライブラリがそのまま使えます。
#include <Arduino.h>
#include <Wire.h>
#include <Adafruit_BMP085.h>
// https://github.com/adafruit/Adafruit-BMP085-Library
Adafruit_BMP085 bmp;
void setup() {
Serial.begin(9600);
int ok = bmp.begin();
if (!ok) {
Serial.println("bmp.begin() failed.");
for (;;);
}
}
void loop() {
Serial.print("Temperature = ");
Serial.print(bmp.readTemperature());
Serial.println(" *C");
Serial.print("Pressure = ");
Serial.print(bmp.readPressure() / 100.0);
Serial.println(" hPa");
Serial.println();
delay(1000);
} Temperature = 19.40 *C Pressure = 1011.48 Pa Temperature = 19.40 *C Pressure = 1011.47 Pa
ebay で買ったシリーズです。$3 ぐらいで買いました。以下らへんのモジュールとよく似たものです。
MQ-135 のほかすこし実装 (LM393など) があります。LM393 はコンパレータで、基板上の半固定で設定した閾値でデジタル出力できるようになっています。アナログ出力は MQ-135 直結です。
空気の汚染度に感度があるセンサーで、ベンジン・アルコール・煙などに反応しやすいと書いてあります。CO2 にもある程度反応するみたいで、ググると poor man's CO2 センサーとしても一定の人気があるみたいです。
自分としては、換気扇ごしに外からタバコの煙が自宅に入ってくることがあってほとほと不愉快なので、どんな時間帯にそういう状況になるかをつきとめたいというモチベーションがありますが、そういう用途に使えるかはわかりません。というかテストのためにタバコを買うのも絶対に嫌なのでテスト不可能です。
MQ-135 自体がデータシートでプリヒートを24時間以上求めています。常時起動してないとダメですね。とはいえ1時間ぐらいで値はほぼ安定しているようには見えます。
MQ-135のデータシート的には10kΩ〜47kΩの負荷抵抗を想定しているみたいですが、このモジュールは 102 (1kΩ) の抵抗が負荷抵抗になっているように見えますので、普通に使うより感度が低くなりそうです。
ググると頑張って ppm 単位の絶対値出力を出そうという試みがあるのですが、素人がキャリブレーションしようがない (他の正確な絶対値センサーが必要) ので、基本的には相対的な値を範囲を一定期間モニタリングしたうえで値を把握して使うほかない気がします。
意外と反応が良くて、臭いがあるとすぐ変化が出力されます。
神道の文献は、たとえ最古の古事記(712年)であっても、仏教伝来(遅くとも6世紀半ば)後に書かれたものであるので、そもそも「仏教に影響されていない神道」というものを記録している文献はない。すなわち仏教抜きで神道を考えるというというのはそもそも現代では無理。
「復古神道」は名前に反して江戸時代の新興宗教であって、儒教・仏教色を排すという意味ではかえってそれらの影響をうけている。
C++ はながいこと食わず嫌いだった。とにかく「難しい」というイメージだけ先行していた。
しかし、あくまで better C として使う限りでは難しくないし、可読性が上がるので、 C++ を使わない手はないという気持ちになった。
C を書いていると、だいたいは書いたコードがそのままバイナリに翻訳されている感があり、安心感がある。struct はメモリ上の配置そのままだし、関数だって単に処理のまとまりに名前がついてて、呼び出しもとに自動的に戻ってくるラベルなだけだ。
C++ になるとオブジェクト指向に概念が入ってきて、これが実際どのようにコンパイルされるかに不安が出てくる。クラスはメモリ上でどう表現されているのか、メソッドディスパッチはどのように行われているか?
もちろん知っている人にとっては簡単な話で
ということで、virtual を使わない限りでは、C++ の class は C で struct 定義と、その第一引数にその sturct ポインタをとる関数郡でしかなく、これは C でよくやるオブジェクト指向のプリミティブな実装とよく似ている。
このようなCのコードは
#include <stdio.h>
typedef struct {
unsigned counter;
} my_counter;
void my_counter_init(my_counter* this) {
this->counter = 0;
}
void my_counter_incr(my_counter* this) {
this->counter++;
}
unsigned my_counter_get_count(my_counter* this) {
return this->counter;
}
int main() {
my_counter counter;
my_counter_init(&counter);
printf("%d\n", my_counter_get_count(&counter));
my_counter_incr(&counter);
printf("%d\n", my_counter_get_count(&counter));
} このようなC++のコードとほとんど同じバイナリが出力される
#include <cstdio>
class my_counter {
unsigned counter;
public:
my_counter(); // void init();
void incr();
unsigned get_count();
};
my_counter::my_counter() {
this->counter = 0;
}
void my_counter::incr() {
this->counter++;
}
unsigned my_counter::get_count() {
return this->counter;
}
int main() {
my_counter counter;
printf("%d\n", counter.get_count());
counter.incr();
printf("%d\n", counter.get_count());
} テンプレートは、複数の型に対する処理を1回でまとめて書けるという仕組みなので、原理的には、扱う型が増えるほど、出力バイナリに関数本体が増えていくことになる。
しかし一方で、テンプレートをコンパイル時計算のために使うような場合は、コンパイル時に解決されるコードがほとんどになり、出力バイナリは書いたコードの見た目の多さに反してかなり少なくなることもある
ということで、テンプレートが使われているからといってバイナリサイズが肥大化するというわけではない。
この書きかたで本当に最適化されたコードに出てくるの? という不安がある。これは難しくて、コンパイラが優秀でも、当然プログラマがちゃんと const を付けてコンパイラに意図を伝えないと、完全に最適化されたコードにはならない (インライン化されないとか)。
C にはない概念がある分、const の付けかたが複雑で、ベターCとして使おうと思うと一番ハマる。
一方で、テンプレートメタプログラミングでコンパイル時に計算することができるので、コンパイラが判断できないような高度な最適化を自力でやることができる。
組込みのコードはどうしてもマジックナンバーが多くなりやすく、C で書くとマクロだらけになる。Cのマクロは文字列展開なので型がなく、当然マジックナンバーにも型を付与できない。組込みは実行時デバッグのコストが高いので、コンパイル時に見つけることができるエラーは全てコンパイル時に見付けたいが、Cではそこまでのことができない。
浮動小数点まわりについてはMCUでは非常に重い処理になるので、できるだけ事前計算した係数をつかってMCU上では整数演算にしてしまうなどの最適化をしたくなる。こういうときCのマクロだけで書くのはとても厳しい。C++ であればコンパイル時に浮動小数点計算を行って定数展開できるので、あきらかに有利になる。
浮動小数点に限らず、高いレイヤーでの最適化はコンパイラは知るよしもないので手でやる必要がある。その際C++のTMPは非常に強力に使える。
測定中、10MHz 付近に急激な落ちこみが観測されることがあって気になっていました。そういうものなのかなとも思ったのですが、調べてみたら同じような問題にあたっている人がいて、まぁよく考えたらそういうものではないよなという感じです。
これは簡単に再現することができます。TGとSAを同軸で直結させて、TGを有効にし、10MHz 付近を拡大することで、変な落ちこみを見ることができます。
以下の画像がそうですが、明かに1dB 落ちこみがあるのがわかると思います。
あるいは、掲示板中にもありますが 10μH と 33pF ぐらいを直列に接続し、バンドパスフィルタを構成した上で 10MHz 付近を見ると、スカートが不自然になっているので非常に目立ちます。 冒頭の画像はこの方法での再現です。直結よりもわかりやすくおかしいことがわかります。
広いスパンで見ているときや、広いダイナミックレンジで見ているときには気付きにくいかもしれませんが、フィルタのようなものを測定するときはかなり気になる挙動だと思います。
10MHz 付近はアマチュア無線でも使う帯域ですし、基準信号付近ですから余計気になります。位相雑音がどうとかよりも致命的な問題でしょう。
ファームウェアの 1.15 が1月22日にリリースされており、これにある程度の修正が含まれています。
最新のファームウェアは http://int.rigol.com/Support/SoftDownload/3 からダウンロードできます。
Product Series → Spectrum Analyzer → DSA815 Firmware_00.01.15.01.00 というのをダウンロードします。DSA815(DSP)update.rar というやつです。
DSA815update.sys を USB メモリのルートディレクトリにコピーして、DSA815 のフロントUSBポートに接続し、Storage の画面でこのファイルを選択したあと、Sys Update を選択すると、アップデートが開始されます。数分で終わり、再起動すると最新のファームウェアで起動します。
↑ 使ったUSBメモリです。自宅にUSBメモリがなく、SDカードリーダーとSDカードで代用しようと思いましたが、DSA815 では認識されませんでした。純粋な USB メモリじゃないとダメなようです。ググってみると、メーカー的にはできるだけ容量が少ないほうが信頼性が高いということになっているみたいです。とはいえ現時点で新品はもはら8GB未満は売ってません。これは USB 3.0 メモリですが、DSA815 は USB 3.0 に対応してないので、古くてもなんでもいいはずです (信頼性は別として)。
見ての通りです。直結の場合では不連続部分はわかりません。一方バンドパスフィルタで見たときはすこし不連続な部分が残っているようにみえます。
ということで、完全には解決しません。挙動的にはまるめ誤差みたいなのが発生しているような感じますが実装がどうなっているかはわかりません。
とはいえ、このように修正が入るので、現状の状態は Rigol のエンジニアは把握しており、直すつもりはあるようです。ファームウェアアップデートだけですめばいいんですが……
DSA815-TG には3年保証がついているのですが、ファームウェアアップデート時にどのような扱いになるか不安になりました。(そもそも国内販売版のものが国際版と完全に同一であるかの確証もない)
国内のリゴルジャパンへメールで確認をとったところ、すぐに返信していただけました。
とのことで、アップグレードしても大丈夫そうです。
購入直後スクリーンショットをLAN経由でとれるようにしましたが 1.15 になって、TCPソケット経由でのコマンド解釈がすこし厳密になって動かなくなったので直しました。
あと、スクリーンショットをとるコマンドは最後にリモートモードを解除するコードを入れていたのですが、動かなくなりました。リモートからコマンドを実行すると必ずリモートモードになってしまって若干鬱陶しいのでなんとかしたいのですが、こちらの原因はよくわかってません。
どうやらスリープを挟まないとダメな模様
また、デフォルトで mDNS での DNS-SD の機能が無効になってみたいです。HTTP 経由でアクセスして設定しないと DNS-SD のクエリに応答しません。
アップグレード後は 00.01.15 です。
スペアナがあったらやってみたかったことの1つとしてコモンモードフィルタ(RFチョーク)の評価というのがあります。だいたいトロイダルコアを使って作っており、トロイダルコアは再現性が高いので計算通りにやれば実用性能はでるはずなのですが、ちゃんと作れているか?はやはりはかってみなければわかりません。
スペアナがなくてもハムバンドでダミーロードを使いつつ高周波電流を頑張って測るという方法で一応検証はできるのですが、面倒くさすぎるので結局グラフ化したりまでしたことはありません。面倒くささが勝りすぎます。
その点スペアナがあれば一瞬で…… という気持ちがありました (実際は適切な治具がないと正確に測るのはやはり難しいのですが……)
大地経由での電流がコモンモード電流なので、フィルタのホットとコールドをショートして、TG のホットをフィルタを通してスペアナの入力にし、TG とスペアナのコールド側をショートさせれば計れそうです。要は単にRFチョークとして測定します。
なおコモンモードフィルタはだいたい-30dB ぐらいあれば十分な性能といえるらしいです。
まずワニグチクリップをトラッキングジェネレータとスペアナ入力に直付けし、ホットコールドをそれぞれショートさせます。
この状態でTGの出力レベルを0dBmに設定し、ノーマライズします。(なおビビリなので外付けのアッテネータは入れてませんが内蔵アッテネータは10dB入れたままです) それなりに出力がないとノイズに測定結果が隠れてしまうので気をつけます。
ノーマライズされた状態でホット側をはずしてアイソレーションを確認します。-30dB 以上なければ測定の意味がないので、アイソレーションがとれてなさそうなら諦めてスパンを狭くして再度ノーマライズからやりなおします (意味がない結果が見えていると混乱するため)。
TG 側にワニグチクリップをつけたりして配線長を増やすと50MHz〜は容易にアイソレーションがとれなくなるので注意します。以下はオープンの状態のアイソレーションです。
この状態でフィルタに接続して測ります。フィルタの入力側(TG側)の線長が長いとこれまたアイソレーションがとれないので誤差の原因になりますが、排除するのが難しいです。シールドケースに入れて測るしかない気がしますが、今回は用意できてないので多少飛びこみがあります。
今回計ったのはキットものの http://www.ddd-daishin.sakura.ne.jp/ddd/dcf/dcf-rf-29l3/kit-dcf-rf-29l3-ver2.htm これです。スペック的には 50MHz ぐらいまでは -30dB 余裕でとれるみたいなグラフがあります。
一応このように雑に測った感じでも 50MHz ぐらいまでは -30dB ぐらいになっているように見えます。(0〜100MHzのスパンなので真ん中が50MHzです)。とはいえ -40dB までとれている範囲はそれほどないです。
ついでに挿入損失も測りました。
入出力インピーダンス50Ωとして、例えばインピーダンスZを直列挿入した場合、入力側にかかる電圧は出力電圧を、挿入インピーダンス と入力インピーダンスで分圧した形になる。
なので、入力電圧は になる。dB で表わすと
RIGOL (リゴル) 1.5GHzスペクトラム・アナライザ(トラッキング・ジェネレータ機能付) 【国内正規品】,DSA815-TG cho45
やっぱスペアナは欲しいよなあと思いはじめて数ヶ月、決心がついたので買いました。技術力が低いので本当に金額に見合うぶんだけの活用ができるかは微妙ですが「見えないものが見えるようになる」というメリットに抗えませんでした。
スペアナといっても現状ではいくつも選択肢があります。USB 接続のものはハードのインターフェイスがいらない分をスペックにコストをかけられるので、スペック的には良さそうです。
DSA815-TG は位相雑音(ゆらぎ/時間ドメインでのジッタ)が多いというのが大きな欠点の一つのようです。高純度の信号の測定ができないことを意味しますが、この欠点がどれぐらい今後に影響してくるのかまだわかっていません。
しかしやはり欠点はあってもスタンドアロン型のもののほうが使い勝手は良さそうです。電源入れれば使えるというのは大事に感じます。USB 接続してアプリを立ちあげてという手順は地味にだるいのです。そういうところを考えると、スペックが良くても使う頻度が少なくなってしまうのは一番損になりますから、スタンドアロンのものにしました。
この機種は数年前までは15万前後で買えたみたいですが、円安進行のためか、かなり値上りしています。悔しいところですが諦めて18万ぐらいで買いました。当然トラッキングジェネレータ付きです。
思ったよりも反応が良くて使いやすいです。
UIを日本語設定にすることができますが、この手の中華製品にありがちなひどい明朝フォントになったりはせず、普通に使えるレベルだと思います。とはいえ英語設定で使ってますが…
10dB アッテネータはマトモなやつを1つ買いました。追加でいくつか安いアッテネータを注文しています。
スペクトラム・アナライザによる高周波測定―高調波,不要輻射,変調,ひずみ,位相ノイズ,伝送特 (計測器BASIC) cho45
この本は買う前に読んでいました。アマゾンではなく、CQ出版社のサイトから PDF を買ってます。
あとはリターンロスブリッジ (VSWR ブリッジ) が欲しいので作るかどうするか、という感じです。
方向性結合器は自分の欲しい周波数帯・耐電力のものは全く売っていないので作るしかありません。一度作っていますが、もっといいのを作りたいところです。
とはいえ50MHzまでならアンテナアナライザーもあるので、そこまで必要でもないかなという気がします。
まず測定画面のスクリーンショット(ハードコピー)ができないとかなり不便なので、ここから解決しました。
プログレスを出しつつスクリーンショットをダウンロードしてこれます。ダウンロードしたあとは imagemagick の convertコマンドで png に変換し、optipng コマンドで最適化します。
ダウンロード部分にはライブラリ依存が一切ないので Ruby さえ動けば bmp ダウンロードはどこでも動きますし、LAN 経由なので一切ドライバなどが必要ないのが良いところです。
png 変換時には imagemagick コマンドと optipng コマンドが必要です。
DSA815 には USB 経由での GPIB 通信と、LAN ケーブル経由での VXI-11 (というよりは、LXIの一部)がサポートされています。
このへん、用語がいっぱいあるので整理しとくと
「というよりは、LXIの一部」と書きました。DSA815 はドキュメントには書いてないのですが、生のTCPソケット経由での通信もできるようになっていて、実はこれが一番簡単です。LXI の仕様では生TCPソケットの通信はポート5025を使うような記述がありますが、DSA815 では 5555 ポートです。
:PRIV:SNAP?
を送ると、11バイトのヘッダ(ファイル長を含む)とビットマップファイルが送られてきます。この :PRIV:SNAP? は隠しコマンドのようで、公式の Programming Reference にはありません。PRIV は Private の略なんでしょう。別のクライアントの通信からわかったので微妙なところです。
という表示のもの。
スイッチング周波数が高く、かなり小さい。(スイッチング周波数が高いほどコイルが小さくできるため。ただしスイッチング損が増えるので効率が犠牲になりやすい)。裏面に実装はなく、写っている部品で全て。
注意が必要で、普通と逆(左まわり)で電圧があがる。だから安いのか?
5V → 12V 昇圧での効率
2.5W → 2.2W 88%
5.0W → 4.73W → 94.6%
10W → 8.42W → 84.2%
これ以降出力低下
コイルが結構発熱する。
値段の割に効率が良く、小さいので結構汎用的に使えそう。2V〜 昇圧可能なのも嬉しい。NiMH 2本で昇圧したいときはベストといってもいいんじゃないかという気がする。
http://www.suosemi.com/ 深圳市硕芯科技有限公司という会社のもの
オン抵抗 80mΩ パワーMOSFETがビルトインされている。
フロスをどうしてもサボってしまうので、11月ぐらいに買ってみました。だいたい使用感はわかったかなと思うのと、歯科での指導を挟んだのでで感想を書いておきます。
フロスが面倒で買ったのですが、ジェットウォッシャーではフロスの代わりにはなりませんでした。結局歯間の狭いところ(自分はほぼ隣同士の歯がくっついています)の歯垢は落とせないみたいです。かなり念入りにジェットウォッシャーを使ってからでも、フロスを使うとまださらに歯垢がとれます。歯科でのチェックでも、フロス使用時は95%〜ぐらいの歯垢除去率だったのが、ジェットウォッシャーだけの場合80%〜ぐらいまで落ちていました。
歯科のでチェックは歯石(磨き残しが続いて歯垢が固まった状態=恒常的に磨けていない箇所)も見るんですが、サボりがちのフロスでもひどいことにはならないので、サボりがちであってもフロスのほうがマシみたいです。
まぁそりゃそうだろという感じではあります。これは歯間ブラシの代替であって、フロスの代替ではありません。歯間が狭い人には向いてないのでしょう。
食べカスはすごい勢いで落ちてくるので気持ちが良いです。まぁフロスでも落ちるんですが、フロスの場合、糸にヘバりついてくる感じなので使用感が悪いという気持ちの問題があります。
冬の冷い水をすぐに使ってジェットウォッシャーをするとかなりつらいです。知覚過敏の人には苦行になります。
あらかじめて汲んでおいて室温にするとか、お湯でやるとかする必要があります……
とはいえ、やらないよりはマシだと思うので、フロスと併用することにします。結局手順が増えてるだけじゃないかという……
「独自拡張のような形でIEEE802.11のフレームを飛ばして」と書きましたが、実際のWiFiパケットは見ておらず、真偽に疑問があったので、キャプチャして確認しました。
結論からいうとその通りのようで、Management frame (ビーコンとかと一緒) を Vendor-specific な形式で使っているようです。Wireshark だと Malformed Packet となってしまうのが謎ですが…
ただ、Vendor Specific Content にあたる部分に、esp_now_send で渡したバイト列以外にもヘッダみたいなのがついています。これはよくわかりません。