はじめに
ドローンや無人移動体のフライトコントローラーとして世界中で使われている「Pixhawk」。
通常、そのデータを確認するには専用ソフト(Mission PlannerやQGroundControl)をPCにインストールします。
しかし最近、「ブラウザ(ChromeやEdge)から直接シリアル通信ができる」というWeb Serial APIの存在を知り、ふと思いました。
「これを使えば、ブラウザだけでPixhawkの中身が覗けるんじゃね?」
今回はその検証の第1弾として、インストール不要・ブラウザのみでPixhawkの生データを受信するところまでを実践してみます。
Web Serial APIとは
ひとことで言えば、「OSの壁を越えて、ブラウザからハードウェアを直接制御できる技術」です。
これまではセキュリティの観点からブラウザがPCのハードウェアに直接触れることは制限されてきましたが、このAPIの登場により、WebアプリからArduinoやPixhawkといったデバイスを制御することが可能になりました。
実装:最小限のコードで繋いでみる
まずは、Pixhawkから送られてくる「生データ」を表示するための、シンプルなHTMLとJavaScriptを準備しました。
実装のポイント
1.ボーレートの設定: PixhawkのUSBポートは通常 115200 で通信しています。
2.バイナリの可視化: Pixhawkはデータをバイナリ(数値の列)で送ってくるため、JavaScriptで16進数の文字列に変換して表示させています。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>Pixhawk Web Serial Connect</title>
<style>
body { font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; background: #f4f4f9; padding: 30px; }
.card { background: white; border-radius: 8px; box-shadow: 0 2px 10px rgba(0,0,0,0.1); padding: 20px; max-width: 800px; margin: auto; }
h1 { color: #333; font-size: 1.5rem; }
.controls { margin: 20px 0; display: flex; gap: 10px; align-items: center; }
button { padding: 10px 20px; border: none; border-radius: 4px; cursor: pointer; font-weight: bold; transition: 0.3s; }
/* 接続ボタンのスタイル */
.btn-primary { background: #007bff; color: white; }
.btn-primary:hover { background: #0056b3; }
/* 切断ボタンのスタイル */
.btn-danger { background: #dc3545; color: white; }
.btn-danger:hover { background: #a71d2a; }
#clearBtn { background: #6c757d; color: white; }
.status { font-weight: bold; margin-left: 10px; }
.status.connected { color: #28a745; }
.status.disconnected { color: #dc3545; }
#console { background: #1e1e1e; color: #00ff00; padding: 15px; height: 400px;
overflow-y: scroll; font-family: 'Consolas', monospace; font-size: 13px; border-radius: 4px; }
.info { font-size: 0.9rem; color: #666; margin-top: 10px; }
</style>
</head>
<body>
<div class="card">
<h1>Pixhawk 接続テスト (Web Serial API)</h1>
<div class="controls">
<button id="connectBtn" class="btn-primary">Pixhawkに接続</button>
<button id="clearBtn">表示をクリア</button>
<span id="statusLabel" class="status disconnected">未接続</span>
</div>
<div id="consoleText">受信待機中...</div>
<div id="console"></div>
<div class="info">
※PixhawkをUSBで繋ぎ、Mission Planner等を閉じてから「接続」を押してください。<br>
※115200bpsで通信を開始します。
</div>
</div>
<script>
const connectBtn = document.getElementById('connectBtn');
const clearBtn = document.getElementById('clearBtn');
const consoleDiv = document.getElementById('console');
const statusLabel = document.getElementById('statusLabel');
let port;
let reader;
let keepReading = true;
// ボタン1つで接続と切断を切り替える
connectBtn.addEventListener('click', async () => {
if (port) {
// 切断処理
keepReading = false;
if (reader) await reader.cancel();
await port.close();
port = null;
// UIを元に戻す
statusLabel.innerText = "未接続";
statusLabel.className = "status disconnected";
connectBtn.innerText = "Pixhawkに接続";
connectBtn.className = "btn-primary";
return;
}
try {
port = await navigator.serial.requestPort();
await port.open({ baudRate: 115200 });
statusLabel.innerText = "接続済み";
statusLabel.className = "status connected";
connectBtn.innerText = "切断する";
connectBtn.className = "btn-danger";
keepReading = true;
readLoop();
} catch (err) {
console.error(err);
alert("接続に失敗しました: " + err.message);
}
});
async function readLoop() {
while (port && port.readable && keepReading) {
reader = port.readable.getReader();
try {
while (true) {
const { value, done } = await reader.read();
if (done) break;
const hexString = Array.from(value)
.map(b => b.toString(16).padStart(2, '0').toUpperCase())
.join(' ');
const span = document.createElement('div');
span.textContent = `[${new Date().toLocaleTimeString()}] ${hexString}`;
consoleDiv.appendChild(span);
if (consoleDiv.childNodes.length > 100) {
consoleDiv.removeChild(consoleDiv.firstChild);
}
consoleDiv.scrollTop = consoleDiv.scrollHeight;
}
} catch (err) {
console.error("読み取りエラー:", err);
} finally {
reader.releaseLock();
}
}
}
clearBtn.addEventListener('click', () => {
consoleDiv.innerHTML = '';
});
</script>
</body>
</html>
動作確認:ブラウザに流れる「生データ」
PixhawkをUSBでPCに繋ぎ、作成したページで「接続」ボタンを押すと……。
![]() | ![]() |
出ました!
黒いコンソール画面に、16進数の数字がザーッと流れ始めました。
この中には、機体の傾き、高度、GPSの状態といったあらゆる情報が詰まっています。
よく見るとデータの先頭に FD という文字が混ざっているのがわかります。これは MAVLink v2 という通信プロトコルの開始合図。ブラウザが正しくPixhawkの信号を捉えている証拠です。
まとめ
専用ソフトを一切立ち上げることなく、「ただWebページを開くだけ」でPixhawkとの通信に成功しました。
「ブラウザだけで動く」ということは、OSを問わず、URLを共有するだけで誰でも同じ解析ツールが使えるようになるということです。
注意点
1.ブラウザの制限(Safariは未対応)
ここが一番のポイントです。Mac標準の Safariは、Web Serial APIをサポートしていません。Macユーザーには「ChromeかEdgeを使ってください」と伝える必要があります。
2.ドライバー不要だが「認識名」が違う
Windowsでは「COM3」のように表示されますが、Macでは /dev/cu.usbmodem… のような名前で認識されます。Web Serial APIの選択ダイアログにはちゃんと出てくるので、それを選択すればOKです。
| ブラウザ | OS (Windows/Mac/Linux) | 対応状況 |
|---|---|---|
| Google Chrome | Windows / Mac | OK |
| Microsoft Edge | Windows / Mac | OK |
| Firefox | Windows / Mac | NG (非対応) |
| Safari | Mac | NG (非対応) |



