Skip to content

PiMaV/thunder-optics-o-py

Repository files navigation

Thunder Optics O-Series — Python Driver & Live Viewer

A minimal, dependency-light Python interface for the Thunder Optics O-series spectrometer (O / OR / ORT1 / ORT2) together with a live-view GUI for real-time measurements, dark/reference handling, and sensitivity calibration against known illuminants.

Brought to you by M.E.S.S. — Mattern Engineering & Software Solutions.


Mini GUI

Features

  • USB spectrometer communication — direct bulk transfer via PyUSB / libusbK, implementing the documented AA 55 | Len | Cmd | Data | Chk frame protocol.
  • Python interface — a thin ThunderSpectrometer class with acquire(integration_ms), pixel count, and wavelength-polynomial calibration read from the device.
  • Live spectrum view GUI — matplotlib-based, with:
    • integration-time and averaging sliders
    • pause / auto-Y / log-Y / peak-finder toggles
    • dark capture, reference capture, transmission / absorbance modes
    • overlay of literature reference curves (D65, AM1.5G, CIE-A, blackbodies)
    • one-click instrument-response calibration against a known illuminant
    • CSV export of the currently displayed spectrum

No database, no framework, no extras. Three files of logic, one GUI, one driver class.


Installation

Requires Python 3.10+.

Recommended: uv

uv gives you a fully reproducible environment from uv.lock and is significantly faster than pip on slow storage (SD cards, etc.).

git clone <repo-url>
cd Spectrometer_Handheld
uv sync
uv run python main.py

That's it. uv sync creates .venv/, installs the exact pinned versions from uv.lock, and uv run picks up that environment automatically.

Install uv itself via curl -LsSf https://astral.sh/uv/install.sh | sh (Linux / macOS) or powershell -c "irm https://astral.sh/uv/install.ps1 | iex" (Windows).

Alternative: plain pip

python -m venv .venv
# Windows:
.venv\Scripts\activate
# Linux / macOS:
source .venv/bin/activate

pip install -r requirements.txt

requirements.txt is autogenerated from uv.lock and pins the same versions. Regenerate with uv export --no-hashes --no-annotate -o requirements.txt.

System-level dependency

On Linux / macOS you also need a libusb runtime (sudo apt install libusb-1.0-0 / brew install libusb). On Windows, see the driver note below.


Windows USB driver workaround

On Windows 11 the stock driver delivered with the device may fail to install (typically a 32/64-bit packaging conflict). The working fallback is to bind libusbK to both USB interfaces (MI_00 and MI_01) of the device using Zadig:

  1. Run Zadig as Administrator, enable Options → List All Devices.
  2. Select optosky (Interface 0), choose libusbK, install.
  3. Select optosky (Interface 1), choose libusbK, install.

Device IDs: VID 0x0483 / PID 0x6666.

After that, both vendor software and this Python interface work. A fully screenshotted walkthrough is in USB_Problem/win11_driver_fix.md.


Usage

Run the live viewer

uv run python main.py

or, if you prefer plain venv:

python main.py
# or equivalently
python spectrum_viewer.py

Keyboard shortcuts inside the viewer:

Key Action
space Pause / resume
d Dark on/off
r Reference on/off
b Cycle library curve
k Calibrate / clear
m Cycle display mode
l Log Y on/off
p Peak labels on/off
a Auto-Y on/off
c Save current CSV
q Quit

Minimal Python example

from thunder_spectro import ThunderSpectrometer

with ThunderSpectrometer() as spec:
    print("Pixels      :", spec.pixel_count)
    print("Coefficients:", spec.coefficients)
    print(f"Wavelength  : {spec.wavelengths[0]:.2f} ... "
          f"{spec.wavelengths[-1]:.2f} nm")

    spectrum = spec.acquire(integration_time_ms=10)
    print("min/max/mean:", spectrum.min(), spectrum.max(), spectrum.mean())

spec.wavelengths is a numpy array matching spectrum pixel-for-pixel, computed from the cubic polynomial the device reports at startup.


Project structure

Spectrometer_Handheld/
├── main.py                 # entry point (runs the viewer)
├── spectrum_viewer.py      # matplotlib live-view GUI
├── thunder_spectro.py      # USB driver (PyUSB)
├── reference_spectra.py    # D65 / AM1.5G / CIE-A / blackbody curves
├── pyproject.toml          # project metadata + dependency spec (uv)
├── uv.lock                 # exact version pins for reproducible installs
├── requirements.txt        # pip fallback, autogenerated from uv.lock
├── LICENSE                 # MIT
├── README.md
└── USB_Problem/
    ├── win11_driver_fix.md # Zadig / libusbK workaround walkthrough
    └── screenshots/

Current status

Early-stage, experimental, but functional.

  • Tested on Windows 11 (64-bit) against a Thunder Optics ORT1 (product page) with Hamamatsu S11639 sensor (2048 px, ~350–1050 nm).
  • Acquisition, dark subtraction, reference capture, transmission, absorbance, and sensitivity calibration all work end-to-end.
  • Interfaces are intentionally minimal so the protocol stays easy to read and extend.

Limitations

  • Windows driver quirk — libusbK must be bound manually via Zadig the first time.
  • Hardware-dependent — the driver targets Thunder Optics O-series devices (VID 0x0483 / PID 0x6666). Other vendors using the same STM32 VID will not be compatible.
  • Qualitative library curves — the included D65 / AM1.5G / CIE-A / blackbody curves are meant for visual comparison and single-point sensitivity calibration. For quantitative photometry you must supply your own calibrated reference source.
  • No scipy dependency — the peak finder is deliberately simple (local-max + prominence). Fine for live display, not a replacement for proper peak fitting.

Future work

  • Optional CLI batch-acquisition (no GUI) for headless logging.
  • Better peak fitting (Gaussian / Voigt) behind an optional scipy dependency.
  • Re-usable calibration files (save/load response_*.csv directly from the GUI, not only on every Calib press).
  • Linux / macOS smoke tests.
  • Raspberry Pi kiosk mode (fullscreen auto-start via systemd user service).

Contributions via issues / PRs are welcome — small, focused changes preferred.


License

Released under the MIT License. See LICENSE.


Developed and maintained by Philipp Mattern Mattern Engineering & Software Solutions (M.E.S.S.)mess.engineering

About

Python driver and live-view GUI for the Thunder Optics O-series spectrometer.

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages