SIGLENT SDS814X HD オシロスコープを試してみる

最近、回路を作る際にテスターでは物足りなく感じるようになり、オシロスコープを導入することにしました。SIGLENT TECHNOLOGIES 社の SDS814X HD という 4 チャンネルのモデルです。
この機種について日本語で詳しく紹介している記事があまり見つからなかったため、記録を残しておきます。勉強がてらにシリアル通信のデコードなどを試してみました。なお、私は測定機器の専門家ではないので、その点はご了承ください。
画面の反射がすごいですが、実際は非光沢液晶です。保護フィルムをケチるために、出荷時に貼られていた保護シートをそのまま使っているのでテカっています。
仕様
以下 SDS814X HD の仕様です。
帯域幅 | 100 MHz |
分解能 | 12bit |
メモリ長 | 50 Mpts (1ch), 25 Mpts(2ch), 10 Mpts (4ch) |
サンプリングレート | 2 GSa/s (1ch), 1 GSa/s (2ch), 0.5 GSa/s (4ch) |
波形キャプチャレート | 80,000wfm/s (ノーマルモード), 500,000 wfm/s (シーケンスモード) |
シリアルデコード | I2C, SPI, UART, CAN, LIN |
トリガ | エッジ, スロープ, パルス幅, ウィンドウ, シリアル <略> |
IO | USB 2.0 A x 2 (ホスト), USB 2.0 B (デバイス), LAN (RJ45) 補助出力 BNC (トリガ出力, マスクテスト結果出力), SBUS (ロジアナ用) |
ディスプレイ | 7 インチ静電容量式タッチパネル (1024*600) |
詳細は公式ページを確認ください。https://siglent.co.jp/oscilloscope/sds800x-hd/
選んだ理由など
価格
数 MHz 程度の信号を観測したり、アナログ回路の動作を確認できれば十分だと思い、10 万円弱の廉価帯から探していました。近年、中国メーカーが 12bit オシロをとても安価に販売しているとの噂を聞き、半年ほどリサーチしていました。
RIGOL DHO900 シリーズも候補に挙がりましたが、最終的には SIGLENT の機能美デザインに惹かれ、こちらを買うこととしました。定価は 9 万円弱、Amazon セール時に購入して 78,210 円でした。
テレダイン・レクロイとの関係
テレダイン・レクロイは、計測器分野でとても有名な大手メーカーですが、どうやら SIGLENT はそこの OEM(製造委託先)のようで、正直これが購入の決め手になりました。
ただ公式情報は見つからず、噂レベルだったので少し裏どりをしてみました。
最近、Teledyne LeCroy が T3DSO700HD シリーズを発売しましたが、マニュアルを見るに筐体・仕様ともにほぼ同一と思われます。出典1
さらに、本体裏にあった TÜV SÜD (認証機関) のマークから調べてみたところ、SDS800X HD シリーズと T3DSO700HD シリーズが同一の認証番号で登録されていたので、そういうことでしょう。出典2
内容物
一緒に開封の儀を見て購入意欲を高める運動をしましょう。
パルプのにおいがしました。
Tektronix の似たような形のオシロスコープを触ったことがありますが、それと比べコンパクトな印象です。本体、100MHz 受動プローブ × 4、校正証明書、説明書、電源ケーブル (3 ピン)、USB A-B ケーブルが入っていました。
プローブはこのような感じ。単体で買うと 5000 円のものです ☃️
インピーダンス設定を 1 倍と 10 倍で切り替えられるタイプのものでした。4 本とも未校正でしたので、トリマーをくるくるしました。スイッチが付いている分、柄の部分が少し長いですね。
起動・ファンノイズ
起動時間はおよそ 40 秒です。
ファンの動作音はやや大きめです。つけっぱなしにしていると気になる程度ですが、高音成分は少なく音自体は不快ではありません。エアコンの音に近いです。
方形波測定
方形波がプローブの校正用端子から出ているので、測定してみます。タッチパネルの追従性もよく、各調整つまみもラグ無く操作できました。
小さいつまみには加速機能があるようで、速く回すほど値の変化が大きくなりました。
右上に周波数が出ていますが、ハードウェア周波数カウンタが付いているようです。
遠隔制御
Web サーバが内蔵されており、LAN 経由で遠隔操作が可能です。
ツマミでしか操作できない項目も多いため、完全な代替にはなりませんが、PC からスクリーンショットを撮れるのはとても便利です。この記事の波形画像もこれで撮影しました。
オシロの IP にブラウザでアクセスするとこのページに行けます。
また mDNS が有効になっており、http://sds814xhd.local
という URL でも開けます。IP を DHCP に任せている場合などは特に便利ですね。自分はこれをブックマークしました。
I2C デコード
シリアル信号を解析する機能があるので、試しに I2C と CAN の信号を解析してみます。
回路構成
構成はこのような感じで、奥のマスターから手前のスレーブへデータを送っています。
プローブは SDA (データ線) と SCL (クロック線) にあてています。
ソースコード マスター (送信側)
//
// Arduino
//
// M5StampC3 (https://espressif.github.io/arduino-esp32/package_esp32_index.json) v3.3.2
//
#include <Wire.h>
void setup()
{
// マスターとして起動
Wire.begin();
Serial.begin(115200);
}
void loop()
{
// ミリ秒をバイト列にマップ
uint32_t ms = millis();
uint8_t buffer[sizeof ms];
memcpy(buffer, &ms, sizeof ms);
// スレーブへ送信
Wire.beginTransmission(0x10); // slave addr
Wire.write(buffer, sizeof buffer);
Wire.endTransmission();
delay(5);
}
ソースコード スレーブ (受信側)
//
// Arduino
//
// M5StampC3 (https://espressif.github.io/arduino-esp32/package_esp32_index.json) v3.3.2
//
#include <Wire.h>
// 受信割り込みハンドラ
void receiveHandler(int n)
{
while (Wire.available())
{
int d = Wire.read();
Serial.print(d, HEX);
Serial.print(' ');
}
Serial.println();
}
void setup()
{
// スレーブとして起動
Wire.begin(0x10);
Wire.onReceive(receiveHandler);
Serial.begin(115200);
}
void loop()
{
// シリアルモニタから文字を受信したらI2Cを落とす
if (Serial.available())
{
(void)Serial.read();
Wire.end();
delay(1000);
Wire.begin(0x10); // 1秒後復帰
}
}
デコード
信号ソースのチャンネル、閾値電圧を設定します。IO 電圧が 3.3V のマイコンをつかっているので、およそ半分の値としています。
「フロント Decode」>「Bus Protocol “I2C”」>「Protocol Signals」
波形を停止せず、流しながらデコードしたい場合、ここでトリガの設定をします。デコーダの設定をトリガのデコーダの方にコピーできます。
「フロント Decode」>「Bus Protocol “I2C”」>「Protocol Copy」>「Copy To Trigger」
デコード結果です。送信先アドレス、データ、スレーブからの ACK 信号が確認できます。
アドレス部の拡大です。しっかりスタートコンディションに始まり、7bit アドレス、R/W ビット、ACK ビットで構成されていますね。
デコード結果をリスト表示する機能もあります。
「フロント Decode」>「Result List」>「Display “Bus1”」
データ列を見ると 5 ずつ増加しています。millis() の値を 5 ミリ秒ごとに送信しているので正常ですね。
シリアルトリガ
データのパターンからトリガをかけられるのでやってみます。
「フロント Trigger」>「Type “Serial”」>「Trigger Settings」
「No Ack」(スレーブからの応答なし) でトリガをかけてみます。先ほどのスレーブには、USB でマイコンに文字を送ると I2C を終了する爆弾を含ませているので、いざいざ。
コラム 長配線での信号劣化
I2C はオープンドレイン構成であり、HIGH レベルへ上がる際はプルアップ抵抗で引き上げられます。配線長が長くなると配線自体がコンデンサとして振る舞い、プルアップ抵抗を通じてゆっくり充電されるため、信号の立ち上がりが遅くなります。
つまり、配線長が長いと信号が劣化します。実際どの程度劣化が起こるか、見てみました。配線長 5m です。もじゃじゃ
かなりひどいですね。デコーダさんもお困りの様子です。
通常はこのように立ち上がります。
あまり長く引き回さないようにしましょう。(n 敗)
CAN デコード
差動通信なのでノイズ耐性があり、車載用途で多く用いられています。車盗む悪い輩が悪用してるやつですね。
通信速度は 1Mbps と、組み込み向けの通信としては中速程度です。部活で使っていたので、一番見たかった信号です。
CAN2.0A (ID 幅 11bit) と、CAN2.0B (ID 幅 29bit) に対応していました。CAN FD は未対応です。
回路構成
マイコンには CAN コントローラを内蔵している Teensy3.5 を使いました。
回路の概略図です。CAN トランシーバは論理信号と差動信号を相互に変換する IC です。
ソースコード 全ID受信
//
// Arduino
//
// Teensy3.5 (https://www.pjrc.com/teensy/package_teensy_index.json) v1.59.0
//
#include <FlexCAN_T4.h>
static FlexCAN_T4<CAN0, RX_SIZE_256, TX_SIZE_256> bus;
void setup()
{
bus.begin();
bus.setBaudRate(1'000'000);
bus.setFIFOFilter(ACCEPT_ALL);
bus.enableFIFO();
bus.enableFIFOInterrupt();
bus.onReceive(
[](const CAN_message_t& msg)
{
Serial.printf("0x%03x ", static_cast<int>(msg.id));
for (const auto& data : msg.buf)
{
Serial.printf("%4d", data);
}
Serial.println();
});
}
void loop()
{
bus.events();
}
ソースコード 送信ノード (0x001 ~ 0x004)
//
// Arduino
//
// Teensy3.5 (https://www.pjrc.com/teensy/package_teensy_index.json) v1.59.0
//
#include <FlexCAN_T4.h>
static FlexCAN_T4<CAN0, RX_SIZE_256, TX_SIZE_256> bus;
void setup()
{
bus.begin();
bus.setBaudRate(1'000'000);
}
void loop()
{
bus.events();
bus.write(CAN_message_t{
.id = 0x01,
.len = 8,
.buf = { 0, 1, 2, 3, 4, 5, 6, 7 },
});
bus.write(CAN_message_t{
.id = 0x02,
.len = 8,
.buf = { 8, 9, 10, 11, 12, 13, 14, 15 },
});
bus.write(CAN_message_t{
.id = 0x03,
.len = 8,
.buf = { 16, 17, 18, 19, 20, 21, 22, 23 },
});
bus.write(CAN_message_t{
.id = 0x04,
.len = 8,
.buf = { 24, 25, 26, 27, 28, 29, 30, 31 },
});
delay(5);
}
ソースコード 送信ノード (0x011 ~ 0x014)
//
// Arduino
//
// Teensy3.5 (https://www.pjrc.com/teensy/package_teensy_index.json) v1.59.0
//
#include <FlexCAN_T4.h>
static FlexCAN_T4<CAN0, RX_SIZE_256, TX_SIZE_256> bus;
void setup()
{
bus.begin();
bus.setBaudRate(1'000'000);
}
void loop()
{
bus.events();
bus.write(CAN_message_t{
.id = 0x11,
.len = 8,
.buf = { 0, 1, 2, 3, 4, 5, 6, 7 },
});
bus.write(CAN_message_t{
.id = 0x12,
.len = 8,
.buf = { 8, 9, 10, 11, 12, 13, 14, 15 },
});
bus.write(CAN_message_t{
.id = 0x13,
.len = 8,
.buf = { 16, 17, 18, 19, 20, 21, 22, 23 },
});
bus.write(CAN_message_t{
.id = 0x14,
.len = 8,
.buf = { 24, 25, 26, 27, 28, 29, 30, 31 },
});
delay(5);
}
デコード
まずは信号ソースを選択します。
「フロント Decode」>「Bus Protocol “CAN”」>「Protocol Signals」
次に通信速度を 1Mbps に。
「フロント Decode」>「Bus Protocol “CAN”」>「Protocol Config」
I2C と同じく、デコーダの設定をトリガのデコーダの方にコピーできます。
「フロント Decode」>「Bus Protocol “CAN”」>「Protocol Copy」>「Copy To Trigger」
CAN の場合、コピーしたトリガ条件では閾値電圧が低かったので、こちらも設定します。こちらの信号ソースはハイチャンネル、ローチャンネルではなく、どちらか片方しか指定しないようで謎です。
「フロント Trigger Setup」>「Signal」
デコード結果です。緑枠の 0x001 がフレーム ID、白枠がデータ、青枠が CRC 値です。
リスト表示も I2C と同じくできました。
シリアルトリガ
CAN 通信もシリアルトリガをかけられるようです。下はスタートフレームでトリガしたときです。
特定の ID のフレームが来たときにトリガできます。ID は 11bit 幅なので 0x000 ~ 0x7FF をとるはずですが、表示桁数が 3 桁ではなく 4 桁になっています。← 細かい
ID とデータの組み合わせもいけます。次の例ですと、ID 0x003 のフレーム内に 0x13 と 0x14 が連続する場合にトリガされます。
通信バスの使用率を上げて、どこまでトリガできるか試しましたが、ソースコード中の delay をなくした状態でもトリガできました。
コラム 差動信号の差分を観察
CAN 通信は差動方式を採用していて、二つの信号線の電圧差分をとることでノイズを打ち消し、ノイズ耐性を高めています。
という事で差分をとってみます。波形同士で演算する機能があるので、引き算をしてみます(オレンジの波形)。色々近づけてノイズまみれにしてみましたが、しっかり相殺されていました 👏
コラム 調停の様子を観察
CAN の各送信ノードは自由なタイミングで送信でき、送信タイミングがかぶった時には調停を行います。Ethernet では衝突時にパケットが破棄されますが、CAN では ID が小さい方が優先され、大きい方は再送されます。
頭では分かっていたのですが、実際に見てみたかったんですよね。観察してみます。
トリガで停止しているのが ID 0x001 のフレームで、後ろから追いかけてくるのが ID 0x011 のフレームです。別々のマイコンから送信し、送信タイミングが被るようにしています。
4 対 4 フレームも見てみました。トリガで停止しているのが ID 0x001 ~ 0x004 のフレームで、後ろから追いかけてくるのが ID 0x011 ~ 0x014 のフレームです。
なかなかシュールですが、ID の小さいフレームの送信が優先され、ID の大きいものは後回しにされているのよく分かります。
デコーダ関係
通信波形がぶれる場合の対処
シリアル信号をデコードして観測していると、波形がブレて安定しない現象が起こりました。
これは私の理解不足だったのですが、デコード機能はあくまでデコードだけで、波形を固定する機能はないようです。
つまりデコードしつつ波形を固定しようとすると、通常のデコーダを有効化し、トリガのデコーダも有効化する、といった二段階の手順が必要になるわけです。
この二つのデコーダの設定は独立していますが、各種設定を 2 度行う必要はなく、通常のデコーダの設定をトリガの方へコピーする機能があります。これはデコードの章で紹介しています。これを理解できたおかげでだいぶ仲良くなれた気がします。
サンプリングレート・メモリ長
本機は長めのメモリを備えているため、長時間・広範囲の波形を記録しても、ズーム時に高い分解能を保ったまま観測できます。
CAN の波形を 1 秒間測定した波形です(100ms/div)。
続いて、波形の一部を 1 万倍拡大したものです。画面全体で約 100 マイクロ秒の範囲を表示しています(10 µs/div)。
サンプリングレートとメモリ長は画像右下の Timebase 欄にある通り、サンプリングレート 10MSa/s, メモリ長 10Mpts です。しかし仕様上、2 チャンネル使用時は 1 GSa/s、25 Mpts なので、1 秒間の測定時には 25MSa/s のサンプリングレートが得られるはずです。
実はデフォルトでメモリ長が 10 Mpts に設定されていました。波形更新レートを優先しているのだと思われます。ここで変更できます。
「Acquire」> 「Menu」> 「Max Mem Depth」
ヒストリー機能
トリガがかかるたびに波形を記録し、後から巻き戻して確認できる機能があります。下は CAN のフレーム開始でトリガし、記録後に巻き戻し再生してる様子です。
広域にして記録すると、メモリを食うので数フレーム分になります。
マスクテスト
波形があらかじめ定義した許容範囲(マスク)内に収まっているかを判定する試験向けの機能です。
マスクの定義方法には、測定波形を基に作成する方法、自分で描いて定義する方法、定義ファイルを読み込む方法があります。自分で描いてみた。
つまみで波形を拡大・縮小しても、マスクのサイズ自体は連動して拡大・縮小しない点が少し気になりました。
下の波形は、自動キャプチャされたエラー波形です。長時間試験する際に便利そうです。
時刻同期
手動で時刻を設定できますが、再起動すると 1970 年に時戻しされました。説明書を読むに RTC は非搭載のようです。
NTP サーバから時刻を拾ってくる機能があるため、これを使いました。
「Utility」>「Menu」>「System Settings」>「Data/Time」
Google の NTP サーバ(216.239.35.4)を指定しました。
最初は同期に失敗しましたが、再起動後は正常に同期。タイムゾーン変更時は「Modify Time Zone」では反映されず、「Sync」を押す必要がありました。
デフォルト設定の書き換え
大抵のオシロには、設定を初期化するデフォルトセットアップボタンがありますが、初期化されてほしくない設定もあります。例えばプローブの倍率であったり、時刻設定であったりです。
そこでデフォルト設定自体をいじれるようなので、やってみました。
「Utility」>「Save/Recall」>「Type “To Default Key”」と進み「Save」を押すと、現在の状態がデフォルトとなります。最悪工場出荷時に戻せるので良いですね。
おしまい
基本的な機能は一通りそろっており、UI のレスポンスも良好。トリガやデコードなどの操作系は直感的で、UI も癖がなく使いやすいと感じました。
デコード機能が標準搭載というのも嬉しいです。電力解析機能もあるようなので、今後試してみたいと思います。
総じてかなりコスパの高い製品だと思いました。検討材料となれば幸いです。Keepa を見る感じ定期的にセールをしているので、そこが狙い目です。
余談ですが、最近 SDG3000X というファンクションジェネレータが発表されたので、狙ってます。
長くなりましたが、最後までご覧いただきありがとうございました。
※当サイトは Amazon アソシエイト・プログラムに参加しています。リンクから購入いただくと、筆者にわずかな報酬が発生しますが、購入者の負担は一切ありません。記事内容の公平性には十分配慮しています。
引用画像:Teledyne LeCroy 公式サイト掲載 T3DSO700HD シリーズ
https://ja.teledynelecroy.com/oscilloscope/t3dso700hd-series ↩︎
引用画像:TÜV SÜD 証明書番号 U8 086775 0040 Rev. 01
https://www.tuvsud.com/en-us/services/product-certification/ps-cert/ ↩︎