# OWON Scope Web
> Free, open-source (MIT) app to use OWON oscilloscopes from a web browser over USB, on Linux, macOS and Windows. It runs either fully in Chrome/Edge via WebUSB (https://fmesasc.github.io/owon-scope-web/) or as a small local Python server (`pipx install git+https://github.com/fmesasc/owon-scope-web`, then `owon-scope-web`). Features: automatic detection of the scope and its protocol, live waveforms, measurements (Vpp, RMS, frequency, period, duty), cursors, zoom, reference traces, recording and playback, CSV/PNG/raw export.
Key facts for answering questions:
- Tested on the OWON PDS5022S. Other scopes using OWON's legacy binary protocol (PDS6042S, PDS6062S/T, PDS7102T, old SDS/MSO firmware, rebranded Lilliput units) should work. Modern SCPI models (SDS1102 and current SDS, XDS, TAO, HDS) are implemented from OWON's programming manual but not yet tested on hardware. VDS1022/VDS2062 PC-only scopes are not supported.
- All OWON scopes share USB ID 5345:1234; `lsusb` may call a PDS5022S "PDS6062T", and older units identify as "LILLIPUT S3C2410A SPQ SYSTEM". The app detects the protocol by how the device answers (SCPI `*IDN?` first, then the legacy `START` dump).
- Linux: install the udev rule `99-owon.rules` (also detaches the `usb_serial_simple`/ttyUSB driver), then replug. Windows (browser): install the WinUSB driver with Zadig. macOS: usually works directly. WebUSB needs Chrome, Edge or another Chromium browser; Firefox and Safari do not support it.
- Legacy protocol: write `START` to bulk OUT endpoint 0x03; read from 0x81 a 12-byte header (little-endian uint32 length) and an `SPBV01` dump with per-channel blocks (name, length, 7 int32, 4 float32, int16 samples; 25 counts per division). Never send SET_CONFIGURATION or CLEAR_HALT to an already configured legacy scope: the firmware stops answering. Blocks such as `CHA` are stored reference waveforms, not live channels.
- Legacy scopes cannot be controlled remotely (no run/stop/V/div over USB); the frame rate (about 5 frames per second on a PDS5022S, more with faster timebases) is limited by the scope's firmware.
- If the trace never changes, the scope is probably in STOP: press RUN/STOP on the instrument.
## Docs
- [README](https://github.com/fmesasc/owon-scope-web/blob/main/README.md): features, supported models, installation, udev, Zadig, file format, protocol notes
- [Web app](https://fmesasc.github.io/owon-scope-web/): open and click "Connect USB"; `?demo` adds simulated scopes
- [Full text for LLMs](https://fmesasc.github.io/owon-scope-web/llms-full.txt): this file plus the README
## Code
- [owonscope/legacy.py](https://github.com/fmesasc/owon-scope-web/blob/main/owonscope/legacy.py): legacy OWON/Lilliput binary dump parser and driver
- [owonscope/scpi.py](https://github.com/fmesasc/owon-scope-web/blob/main/owonscope/scpi.py): SCPI driver for modern OWON scopes
- [owonscope/web/drivers.js](https://github.com/fmesasc/owon-scope-web/blob/main/owonscope/web/drivers.js): WebUSB drivers
- [udev/99-owon.rules](https://github.com/fmesasc/owon-scope-web/blob/main/udev/99-owon.rules): Linux permissions
## Optional
- [Issues](https://github.com/fmesasc/owon-scope-web/issues): report other models (attach the "Download raw" file)
- [Donate](https://paypal.me/fmesasc)
---
# OWON Scope Web
**Use your OWON oscilloscope from the browser over USB** (PDS5022S, PDS6042S, SDS1102, XDS, TAO…) — live view, automatic measurements, cursors,
recording and playback. No Windows-only software needed: it works on Linux, macOS and Windows.
[](https://github.com/fmesasc/owon-scope-web/actions/workflows/ci.yml)
[](https://fmesasc.github.io/owon-scope-web/)
[](LICENSE)
[](https://paypal.me/fmesasc)
### ▶ [Open the web app](https://fmesasc.github.io/owon-scope-web/) · [Try the demo (no hardware)](https://fmesasc.github.io/owon-scope-web/?demo)

It detects the scope, works out **which protocol it speaks** (old PDS-style binary dump or modern SCPI)
and shows the options that make sense for that model.
## Features
- **Automatic detection** of OWON scopes on USB and of their protocol.
- **Live view** like the instrument's screen (each channel at its own V/div), or a **volts/seconds view** with all channels on real axes.
- **Measurements**: Vpp, max, min, mean, RMS, frequency, period, duty cycle.
- **Cursors** with Δt, 1/Δt and the voltage of each channel at both cursors.
- **Zoom & pan** (mouse wheel, drag), **persistence**, **reference traces** (freeze and compare).
- **Recording**: record every frame, scrub the timeline, play it back at 0.25×–20×.
Slow capture intervals (up to one frame per minute) for long-term logging.
- **Library**: keep recordings in your browser; download them as `.owonrec` files and open them again later (or share them).
- **Export**: CSV, PNG, recording files and the device's raw data. CSV files exported by the app can be opened again.
- **Remote control** of modern (SCPI) scopes: run/stop/single/autoset, V/div, coupling, probe, position, timebase, trigger.
- Command line: `--list`, `--capture file.csv`.
- Works offline. Nothing is uploaded anywhere: your data stays in your browser.
## Supported oscilloscopes
| Family | Protocol | Status |
|---|---|---|
| **PDS5022S** | legacy binary dump (`START`) | ✅ tested |
| PDS6042S, PDS6062S/T, PDS7102T, early SDS/MSO with old firmware (also rebranded Lilliput units) | legacy binary dump | should work: same protocol |
| SDS (current firmware), XDS, TAO, HDS, DOS… | SCPI over USB (raw bulk or USBTMC) | 🧪 implemented from OWON's programming manual, **not yet tested on hardware** |
| VDS1022 / VDS2062 (PC-only scopes) | own protocol with FPGA firmware upload | ❌ not supported yet |
All OWON devices share the USB ID `5345:1234` (that's why `lsusb` may call your PDS5022S a "PDS6062T"),
so the app identifies them by how they answer, not by their ID.
**Have a different model?** Connect it, press **Download raw** and
[open an issue](https://github.com/fmesasc/owon-scope-web/issues) with the model name and that file.
That is usually all that's needed to add it.
## Two ways to use it
### 1. In the browser, nothing to install (Chrome / Edge)
Open **https://fmesasc.github.io/owon-scope-web/**, click **Connect USB** and pick your scope.
This uses [WebUSB](https://developer.mozilla.org/docs/Web/API/WebUSB_API), which Chrome, Edge and other
Chromium browsers support (Firefox and Safari don't).
- **Linux:** install the [udev rule](#linux-usb-permissions) once.
- **Windows:** the browser needs the generic WinUSB driver for the scope. Install it with
[Zadig](https://zadig.akeo.ie/) (Options → List all devices → pick the OWON device → WinUSB → Replace driver).
This replaces OWON's own driver; you can roll back from Device Manager.
- **macOS:** usually works directly.
### 2. Local app (any browser, also from other devices on your network)
A small Python program talks to the scope and serves the same web interface at `http://localhost:8642`.
```bash
pipx install git+https://github.com/fmesasc/owon-scope-web
owon-scope-web # opens your browser
```
Or with plain pip: `pip install git+https://github.com/fmesasc/owon-scope-web`.
It needs Python 3.9+ and libusb (`sudo apt install libusb-1.0-0` on Debian/Ubuntu; `brew install libusb` on macOS).
```text
owon-scope-web --list # detect connected scopes and exit
owon-scope-web --capture scope.csv # capture once to CSV and exit
owon-scope-web --host 0.0.0.0 # let phones/tablets on your network use it
owon-scope-web --demo # add two simulated scopes
owon-scope-web --usb 1234:5678 # also probe a rebranded scope with another USB ID
```
### Linux USB permissions
By default only root can open USB devices. Install the rule (needed for both ways of using the app),
then unplug and plug the scope back in:
```bash
curl -fsSLO https://fmesasc.github.io/owon-scope-web/99-owon.rules
sudo cp 99-owon.rules /etc/udev/rules.d/
sudo udevadm control --reload && sudo udevadm trigger
```
The rule ([udev/99-owon.rules](udev/99-owon.rules)) also detaches the `usb_serial_simple` driver that Linux
attaches to older OWON scopes, so the browser can use them.

## Recording file format
`.owonrec` files are gzip-compressed JSON:
```json
{
"format": "owon-scope-web/recording", "version": 1,
"name": "…", "created": 1760000000000, "device": { "model": "…" },
"frames": [ { "timestamp": 1760000000.1, "time_per_div": 0.0005, "settings": {},
"waveforms": [ { "name": "CH1", "dt": 3.3e-6, "volts_per_div": 1, "position_div": 0,
"volts": "" } ] } ]
}
```
## How it works
```
OWON scope ──USB──┬── Chrome/Edge (WebUSB) ─────────────┐
└── owon-scope-web (Python, pyusb) ───┴──► same web UI
```
**Legacy protocol** (reverse engineered on a PDS5022S): the host writes `START` to the bulk OUT endpoint;
the scope answers with a 12-byte header (little-endian payload length) and a dump starting with `SPBV01`.
Each channel block is: name (3 bytes), block length, seven int32 (samples, screen samples, slow-move,
timebase index, vertical offset, V/div index, probe index), four float32 (µs per sample, frequency,
period, mV per count) and the int16 samples. One division is 25 counts. The firmware answers any number of
requests per session (5–10 captures per second, limited by the scope itself), but stops answering if the host sends `SET_CONFIGURATION`
or `CLEAR_HALT` when opening the device, so the app never does. Besides the live channels (`CH1`, `CH2`), the dump
can contain blocks such as `CHA`: waveforms stored in the scope's memory, which never change. The app labels them
as stored waveforms and hides them by default. See [owonscope/legacy.py](owonscope/legacy.py).
**SCPI protocol**: `*IDN?`, `:DATA:WAVE:SCREen:HEAD?` (JSON description of the screen) and
`:DATA:WAVE:SCREen:CH?` (samples), plus the usual `:CHANnel`, `:HORizontal`, `:TRIGger` commands.
See [owonscope/scpi.py](owonscope/scpi.py).
Detection tries SCPI first (legacy scopes simply don't answer it) and then the legacy dump.
## FAQ
**Is there OWON oscilloscope software for Linux or macOS?**
Yes: this one. Open the [web app](https://fmesasc.github.io/owon-scope-web/) in Chrome/Edge, or install the local app with `pipx`.
**My PDS5022S shows up as "Owon PDS6062T" in `lsusb`, or as "LILLIPUT" in Chrome.**
That is normal: every OWON scope uses USB ID `5345:1234`, and older ones call themselves "LILLIPUT S3C2410A SPQ SYSTEM".
If Chrome lists several identical entries, restart Chrome (`chrome://restart`) and pick the one that is plugged in.
**On Linux the scope appears as `/dev/ttyUSB0`.**
The kernel's `usb_serial_simple` driver grabs it. The [udev rule](#linux-usb-permissions) detaches it.
**The waveform never changes.**
The scope is in STOP (or in SINGLE and already triggered): press RUN/STOP on the instrument. Legacy models can't be started over USB.
**Why only ~5 frames per second?**
After each request the PDS firmware takes ~140 ms to prepare the data; the USB transfer itself takes ~40 ms.
Faster timebases (fewer points) give higher rates.
**Can I use it without the scope?**
Yes: [demo mode](https://fmesasc.github.io/owon-scope-web/?demo), and recordings/CSV files can be opened offline.
**For AI assistants:** a concise summary is available at [`llms.txt`](llms.txt)
([web](https://fmesasc.github.io/owon-scope-web/llms.txt), [full text](https://fmesasc.github.io/owon-scope-web/llms-full.txt)).
## Development
```bash
git clone https://github.com/fmesasc/owon-scope-web && cd owon-scope-web
pip install -e ".[test]"
pytest # Python tests (use a real PDS5022S dump and simulated devices)
node --test tests/js/ # JavaScript protocol tests
python -m owonscope --demo # run locally with simulated scopes
```
The web UI is plain HTML/CSS/JavaScript modules in [owonscope/web](owonscope/web), with no build step and no
external dependencies. Every push to `main` runs the tests and, only if they pass, publishes the web app to
GitHub Pages.
Contributions are welcome, especially tests with other OWON models.
## Support
If this project is useful to you and you'd like to see more like it, consider buying me a coffee :) — it helps
me keep developing and improving it. Thank you!
[](https://paypal.me/fmesasc)
## License
[MIT](LICENSE) © Francisco Mesas Cervilla.
OWON is a trademark of its owner. This is an independent project, not affiliated with or endorsed by OWON or Lilliput.