Skip to content

sctg-development/rust-photoacoustic

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

800 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Code Comments Documentation codecov Rust React License

πŸ”¬ Rust-Photoacoustic

Flexible Gas Analyzer using Laser Photoacoustic Spectroscopy

A comprehensive software and hardware platform for high-precision gas concentration measurement using differential Helmholtz resonator photoacoustic spectroscopy.


πŸ“‹ Table of Contents


🌟 Overview

Rust-Photoacoustic is a complete platform for laser photoacoustic spectroscopy (LPAS), designed for real-time gas concentration measurement with laboratory-grade precision. The system provides:

  • ppb-level sensitivity (parts per billion) for trace gas detection
  • Real-time processing with <10ms latency
  • Multi-platform support (Linux, macOS, Windows)
  • Industrial integration via Modbus TCP and REST API
  • Modern web interface for visualization and control

Development Philosophy

This project follows a transparent continuous integration approach where development happens openly in the main branch. Tests are designed and implemented in real-time, ensuring code functionality aligns with project objectives.

⚠️ Status: Active development - APIs may change between commits.


✨ Key Features

mindmap
  root((Rust-Photoacoustic))
    Signal Processing
      Real-time FFT
      Butterworth filters
      Differential subtraction
      Lock-in detection
      Python integration
    Hardware Control
      USB-HID interface
      I2C/SPI protocols
      Thermal regulation
      DDS modulation
    Web Interface
      Real-time streaming
      OAuth2/JWT security
      6 languages + RTL
      Interactive graphs
    Industrial
      Modbus TCP server
      Redis Pub/Sub
      Kafka streaming
      REST API
Loading

Performance Metrics

Metric Value Notes
Sampling Rate 48 kHz Stereo, 16-bit
FFT Resolution 4096 points Configurable 256-8192
Processing Latency < 10 ms Real-time streaming
Web Streaming 60 fps SSE with compression
ADC Resolution 16-bit Β±7.8 Β΅V @ PGA=16
DDS Resolution 0.004 Hz 28-bit frequency register
Temperature Control Β±0.1Β°C PID regulation

πŸ—οΈ Architecture

flowchart TB
    subgraph Hardware["πŸ”§ Hardware Layer"]
        MIC["Microphones A/B"]
        LASER["QCL/DFB Laser"]
        TEC["TEC Controllers"]
        NTC["NTC Thermistors"]
    end

    subgraph LaserSmart["⚑ Laser+Smart Interface"]
        USB["USB-HID"]
        ADC["4Γ— ADS1115<br/>16-bit ADC"]
        DAC["LTC2641<br/>12-bit DAC"]
        DDS["AD9833<br/>DDS Modulator"]
    end

    subgraph Backend["πŸ¦€ Rust Backend"]
        ACQ["Acquisition<br/>Daemon"]
        PROC["Processing<br/>Graph Engine"]
        THERM["Thermal<br/>Regulation"]
        API["REST API<br/>+ SSE"]
        MODBUS["Modbus<br/>Server"]
    end

    subgraph Frontend["βš›οΈ React Frontend"]
        DASH["Dashboard"]
        AUDIO["Audio<br/>Analyzer"]
        GRAPH["Processing<br/>Graph Editor"]
        THERMAL["Thermal<br/>Monitor"]
    end

    subgraph External["🌐 External Systems"]
        SCADA["SCADA/PLC"]
        REDIS["Redis"]
        KAFKA["Kafka"]
    end

    MIC --> ADC
    LASER --> DAC
    TEC --> DAC
    NTC --> ADC
    
    ADC --> USB
    DAC --> USB
    DDS --> USB
    USB --> ACQ
    
    ACQ --> PROC
    PROC --> API
    PROC --> MODBUS
    THERM --> API
    
    API --> DASH
    API --> AUDIO
    API --> GRAPH
    API --> THERMAL
    
    MODBUS --> SCADA
    PROC --> REDIS
    PROC --> KAFKA
Loading

πŸš€ Quick Start

Prerequisites

  • Rust 1.75 or later
  • Node.js 20+ (for frontend)
  • Python 3.10+ (optional, for Python drivers)

Installation

# Clone the repository
git clone https://github.com/sctg-development/rust-photoacoustic.git
cd rust-photoacoustic

# Build the backend
cd rust
cargo build --release

# Install frontend dependencies
cd ../web
npm install

# Start the application
cd ../rust
cargo run --release -- --server

Quick Test

# Run with a test audio file
cargo run -- --input-file examples/test_signal.wav --frequency 2000

# Start server on custom port
cargo run -- --server --web-port 9000

# Enable verbose logging
cargo run -- --server -v

πŸ“ Project Structure

rust-photoacoustic/
β”œβ”€β”€ rust/                          # πŸ¦€ Rust Backend
β”‚   β”œβ”€β”€ src/
β”‚   β”‚   β”œβ”€β”€ main.rs               # Application entry point
β”‚   β”‚   β”œβ”€β”€ lib.rs                # Library exports
β”‚   β”‚   β”œβ”€β”€ acquisition/          # Audio signal acquisition (CPAL)
β”‚   β”‚   β”œβ”€β”€ preprocessing/        # Digital filters, differential
β”‚   β”‚   β”œβ”€β”€ spectral/             # FFT, spectral analysis
β”‚   β”‚   β”œβ”€β”€ processing/           # Processing graph engine (~3000 lines)
β”‚   β”‚   β”œβ”€β”€ visualization/        # Web server, API, OAuth2
β”‚   β”‚   β”œβ”€β”€ thermal_regulation/   # PID controllers
β”‚   β”‚   β”œβ”€β”€ modbus/               # Modbus TCP server
β”‚   β”‚   β”œβ”€β”€ daemon/               # Acquisition daemon
β”‚   β”‚   β”œβ”€β”€ config/               # Configuration management
β”‚   β”‚   β”œβ”€β”€ photoacoustic/        # Core domain logic
β”‚   β”‚   └── utility/              # Helpers, certificate generation
β”‚   β”œβ”€β”€ auth-macros/              # Procedural macros for auth
β”‚   β”œβ”€β”€ examples/                 # Usage examples
β”‚   β”œβ”€β”€ tests/                    # Integration tests
β”‚   └── Cargo.toml
β”‚
β”œβ”€β”€ web/                           # βš›οΈ React Frontend
β”‚   β”œβ”€β”€ src/
β”‚   β”‚   β”œβ”€β”€ pages/                # Route pages
β”‚   β”‚   β”‚   β”œβ”€β”€ index.tsx         # Dashboard
β”‚   β”‚   β”‚   β”œβ”€β”€ audio.tsx         # Audio analyzer
β”‚   β”‚   β”‚   β”œβ”€β”€ thermal.tsx       # Thermal monitor
β”‚   β”‚   β”‚   └── graph.tsx         # Processing graph editor
β”‚   β”‚   β”œβ”€β”€ components/           # Reusable UI components
β”‚   β”‚   β”œβ”€β”€ hooks/                # Custom React hooks
β”‚   β”‚   β”‚   β”œβ”€β”€ useAudioStream.ts # Audio streaming (~2000 lines)
β”‚   β”‚   β”‚   └── useProcessingGraph.ts
β”‚   β”‚   β”œβ”€β”€ authentication/       # Auth0/OIDC integration
β”‚   β”‚   β”œβ”€β”€ locales/              # i18n translations (6 languages)
β”‚   β”‚   └── contexts/             # React contexts
β”‚   └── package.json
β”‚
β”œβ”€β”€ hardware/                      # ⚑ Hardware Designs
β”‚   └── 6C47543F-DEE8-4421-881E-CF5E1C8FF55D/  # Laser+Smart
β”‚       β”œβ”€β”€ *.SchDoc              # Altium schematics
β”‚       β”œβ”€β”€ components/           # JLCPCB component library
β”‚       └── doc/                  # Hardware documentation
β”‚
β”œβ”€β”€ docs/                          # πŸ“š Documentation
β”‚   β”œβ”€β”€ COMPLETE_TECHNICAL_DOCUMENTATION.md
β”‚   β”œβ”€β”€ acquisition_daemon_guide_en.md
β”‚   β”œβ”€β”€ jwt_tokens.md
β”‚   └── ...
β”‚
└── .github/                       # πŸ”„ CI/CD
    └── workflows/
        β”œβ”€β”€ ci.yml
        β”œβ”€β”€ code-quality.yml
        └── release-multiarch.yml

βš™οΈ Configuration

Configuration File

The application uses YAML configuration. Create config.yaml:

# Audio acquisition settings
acquisition:
  sample_rate: 48000              # Hz
  buffer_size: 4096               # samples
  channels: 2                     # stereo (A/B microphones)

# Signal processing settings
processing:
  excitation_frequency: 2000.0    # Hz (laser modulation)
  filter_bandwidth: 100.0         # Hz (bandpass filter)
  fft_size: 4096                  # FFT window size
  window_function: hann           # hann, blackman_harris, hamming
  averaging_count: 10             # spectra to average

# Web server settings
visualization:
  port: 8080
  address: "127.0.0.1"
  name: "LaserSmartApiServer/0.1.0"
  hmac_secret: "your-secure-jwt-secret-key"
  # Optional: Base64-encoded SSL certificates
  # cert: "LS0tLS1CRUdJTi..."
  # key: "LS0tLS1CRUdJTi..."

# Modbus TCP server (industrial integration)
modbus:
  enabled: true
  address: "0.0.0.0"
  port: 5020

# Thermal regulation (PID control)
thermal_regulation:
  enabled: true
  setpoint: 25.0                  # Β°C
  kp: 1.0                         # Proportional gain
  ki: 0.1                         # Integral gain
  kd: 0.05                        # Derivative gain

# Processing graph (hot-reloadable)
processing_graph:
  nodes:
    - id: "audio_input"
      type: "AudioSource"
      config:
        device: "default"
    - id: "bandpass"
      type: "ButterworthFilter"
      config:
        filter_type: "bandpass"
        low_cutoff: 1900.0
        high_cutoff: 2100.0
        order: 4
    - id: "fft"
      type: "FFTAnalyzer"
      config:
        size: 4096

Command Line Options

# Core options
--config <path>           # Configuration file path (default: config.yaml)
--server                  # Start in server mode
--input-device <name>     # Audio input device (e.g., hw:0,0)
--input-file <path>       # Analyze WAV file instead of live audio

# Processing parameters
--frequency <Hz>          # Excitation frequency (default: 2000)
--bandwidth <Hz>          # Filter bandwidth (default: 100)
--window-size <samples>   # FFT size (default: 4096)
--averages <count>        # Spectra to average (default: 10)

# Server options
--web-port, -p <port>     # Web server port (default: 8080)
--web-address <addr>      # Bind address (default: 127.0.0.1)
--hmac-secret <secret>    # JWT signing secret

# Modbus options
--modbus-enabled          # Enable Modbus server
--modbus-address <addr>   # Modbus bind address
--modbus-port <port>      # Modbus port (default: 5020)

# Logging
--verbose, -v             # Debug logging
--quiet, -q               # Suppress all output
--show-config-schema      # Print JSON schema and exit

SSL Certificates

Certificates are auto-generated during build for development. For production:

  1. Place certificates in resources/ directory
  2. Or specify base64-encoded in config:
visualization:
  cert: |
    LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0t...
  key: |
    LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0t...

πŸ”¬ Physical Principles

Photoacoustic Spectroscopy

sequenceDiagram
    participant L as Modulated Laser
    participant G as Gas Sample
    participant M as Microphone
    participant S as Signal Processing

    L->>G: Pulsed IR radiation (f = 2 kHz)
    Note over G: Molecular absorption<br/>Hβ‚‚O, COβ‚‚, CHβ‚„...
    G->>G: Thermal expansion<br/>(photoacoustic effect)
    G->>M: Acoustic wave
    M->>S: Electrical signal
    S->>S: FFT at excitation frequency
    Note over S: Amplitude ∝ concentration
Loading

Key equations:

  • Photoacoustic signal: $S_{PA} = \alpha \cdot P_L \cdot C \cdot Q$

    • $\alpha$: absorption coefficient (cm⁻¹)
    • $P_L$: laser power (W)
    • $C$: gas concentration
    • $Q$: cell quality factor
  • Helmholtz resonance: $f_0 = \frac{c}{2\pi}\sqrt{\frac{A}{V \cdot L}}$

    • $c$: speed of sound
    • $A$: neck cross-section
    • $V$: cavity volume
    • $L$: effective neck length

Differential Detection

Two microphones (A and B) enable common-mode noise rejection:

$$S_{diff} = S_A - S_B$$

This cancels:

  • Ambient acoustic noise
  • Electronic interference
  • Temperature fluctuations

πŸ”„ Signal Processing Pipeline

graph LR
    subgraph Acquisition
        A1[Mic A] --> |48kHz/16-bit| B1[Buffer A]
        A2[Mic B] --> |48kHz/16-bit| B2[Buffer B]
    end
    
    subgraph Preprocessing
        B1 --> C1[Bandpass<br/>Filter]
        B2 --> C2[Bandpass<br/>Filter]
        C1 --> D[Differential<br/>A - B]
        C2 --> D
    end
    
    subgraph Analysis
        D --> E[Windowing<br/>Hann/Blackman]
        E --> F[FFT<br/>4096 pts]
        F --> G[Peak<br/>Detection]
    end
    
    subgraph Output
        G --> H1[REST API]
        G --> H2[Modbus]
        G --> H3[SSE Stream]
    end
Loading

Processing Nodes Available

Node Type Description Parameters
AudioSource Audio input acquisition device, sample_rate
WavFileSource WAV file reader path, loop
ButterworthFilter IIR bandpass/lowpass/highpass order, cutoff frequencies
Differential Channel subtraction -
FFTAnalyzer Spectral analysis size, window, overlap
PeakDetector Frequency/amplitude extraction threshold, range
Averager Temporal averaging count
PythonNode Custom Python processing script_path

πŸ› οΈ Technology Stack

Backend (Rust)

Category Technology Version
Web Framework Rocket 0.5.1
Async Runtime Tokio 1.45
Audio CPAL 0.17
FFT RustFFT 6.4
Auth jsonwebtoken + oxide-auth 10.2
Modbus tokio-modbus 0.17
Python PyO3 0.27
Serialization Serde 1.0

Frontend (TypeScript/React)

Category Technology Version
Framework React 19.2
Build Tool Vite 7.3
UI Library HeroUI 2.x
Charts Chart.js 4.5
Flow Editor ReactFlow 11.x
Audio Viz AudioMotion 4.5
i18n i18next 25.x
Auth Auth0 / OIDC 2.x

Hardware (Laser+Smart)

Component Part Number Function
MCU ATmega32U4 USB-HID controller
ADC ADS1115 Γ—4 16-bit, IΒ²C, 860 SPS
DAC LTC2641 12-bit, SPI
DDS AD9833 Frequency synthesis
GPIO MCP23017 IΒ²C expander
Reference REF5040 4.096V precision

πŸ“‘ API Reference

Authentication

The API supports OAuth2 with PKCE and JWT bearer tokens:

# Get OAuth2 authorization
GET /oauth/authorize?client_id=<id>&redirect_uri=<uri>&response_type=code&code_challenge=<challenge>

# Exchange code for token
POST /oauth/token
Content-Type: application/x-www-form-urlencoded
grant_type=authorization_code&code=<code>&code_verifier=<verifier>

# Access protected endpoints
GET /api/v1/spectrum
Authorization: Bearer <jwt_token>

REST Endpoints

Method Endpoint Description
GET /api/v1/status System status
GET /api/v1/spectrum Current spectrum data
GET /api/v1/spectrum/stream SSE spectrum stream
GET /api/v1/config Current configuration
PUT /api/v1/config Update configuration
GET /api/v1/graph Processing graph state
PUT /api/v1/graph Update processing graph
GET /api/v1/thermal Thermal sensor readings
PUT /api/v1/thermal/setpoint Set temperature target

Modbus Registers

Address Type Description
0-1 Float32 Excitation frequency (Hz)
2-3 Float32 Signal amplitude
4-5 Float32 Phase (degrees)
6-7 Float32 Temperature (Β°C)
100+ Float32[] Spectrum data

OpenAPI Documentation

Interactive API documentation available at:

  • RapiDoc: https://localhost:8080/rapidoc
  • Swagger: https://localhost:8080/swagger

⚑ Hardware Interface

Laser+Smart Board

The Laser+Smart interface board provides:

  • 4Γ— 16-bit ADC channels (ADS1115) for microphone and sensor inputs
  • 12-bit DAC (LTC2641) for laser power control
  • DDS synthesizer (AD9833) for laser modulation (0.004 Hz resolution)
  • 16 GPIO (MCP23017) for auxiliary control
  • USB-HID interface (no drivers required)

Connection Diagram

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚              Laser+Smart Board              β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚   ADC0-1     β”‚    DAC       β”‚     DDS       β”‚
β”‚  Mic A/B     β”‚  Laser PWR   β”‚  Modulation   β”‚
β”‚   Β±2.048V    β”‚   0-4.096V   β”‚  100Hz-14kHz  β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚   ADC2-3     β”‚    GPIO      β”‚     USB       β”‚
β”‚  NTC Sensors β”‚  TEC Control β”‚  HID to Host  β”‚
β”‚   Β±2.048V    β”‚   8 outputs  β”‚   Full Speed  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

πŸ’» Development

Building from Source

# Development build
cargo build

# Release build with optimizations
cargo build --release

# With Python driver support
cargo build --features python-driver

# Static build (musl)
cargo build --release --features static --target x86_64-unknown-linux-musl

Running Tests

# Unit tests
cargo test

# Integration tests
cargo test --test '*'

# With coverage
cargo tarpaulin --out Html

# Frontend tests
cd web && npm test

Development Server

# Backend with hot-reload (requires cargo-watch)
cargo watch -x 'run -- --server -v'

# Frontend dev server
cd web && npm run dev

# Full stack with proxy
cd web && npm run dev:env

πŸ“š Documentation


πŸ“œ License

This project is licensed under the SCTG Non-Commercial License 1.0.

  • βœ… Free for research and education
  • βœ… Open source contributions welcome
  • ❌ Commercial use requires separate license

See LICENSE for details.


🀝 Contributing

Contributions are welcome! Please read our contributing guidelines before submitting pull requests.

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

πŸ“§ Contact

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Contributors 2

  •  
  •