{"id":28260866,"url":"https://github.com/sctg-development/rust-photoacoustic","last_synced_at":"2026-03-16T21:33:05.285Z","repository":{"id":293406867,"uuid":"983936143","full_name":"sctg-development/rust-photoacoustic","owner":"sctg-development","description":null,"archived":false,"fork":false,"pushed_at":"2025-06-13T05:37:01.000Z","size":4812,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-06-13T06:36:44.870Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sctg-development.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-05-15T06:30:05.000Z","updated_at":"2025-06-13T05:37:04.000Z","dependencies_parsed_at":"2025-05-15T07:31:50.529Z","dependency_job_id":"4bf1c7c2-f56f-43a6-ad97-52eaf79b6aa6","html_url":"https://github.com/sctg-development/rust-photoacoustic","commit_stats":null,"previous_names":["sctg-development/rust-photoacoustic"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/sctg-development/rust-photoacoustic","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sctg-development%2Frust-photoacoustic","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sctg-development%2Frust-photoacoustic/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sctg-development%2Frust-photoacoustic/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sctg-development%2Frust-photoacoustic/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sctg-development","download_url":"https://codeload.github.com/sctg-development/rust-photoacoustic/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sctg-development%2Frust-photoacoustic/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":260028224,"owners_count":22947900,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-05-20T05:11:09.687Z","updated_at":"2026-03-16T21:33:05.277Z","avatar_url":"https://github.com/sctg-development.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"![Code](https://tokeisrv.sctg.eu.org/b1/github.com/sctg-development/rust-photoacoustic?type=Rust,TypeScript,TSX,C\u0026category=code)\n![Comments](https://tokeisrv.sctg.eu.org/b1/github.com/sctg-development/rust-photoacoustic?type=TSX,Rust,TypeScript\u0026category=comments\u0026color=abdbe3)\n![Documentation](https://tokeisrv.sctg.eu.org/b1/github.com/sctg-development/rust-photoacoustic?type=Markdown\u0026label=doc\u0026color=e28743)\n[![codecov](https://codecov.io/github/sctg-development/rust-photoacoustic/branch/main/graph/badge.svg)](https://codecov.io/github/sctg-development/rust-photoacoustic)\n![Rust](https://img.shields.io/badge/Rust-1.75+-orange.svg)\n![React](https://img.shields.io/badge/React-19.x-blue.svg)\n![License](https://img.shields.io/badge/License-SCTG--NC--1.0-green.svg)\n\n# 🔬 Rust-Photoacoustic\n\n**Flexible Gas Analyzer using Laser Photoacoustic Spectroscopy**\n\nA comprehensive software and hardware platform for high-precision gas concentration measurement using differential Helmholtz resonator photoacoustic spectroscopy.\n\n---\n\n## 📋 Table of Contents\n\n- [Overview](#-overview)\n- [Key Features](#-key-features)\n- [Architecture](#-architecture)\n- [Quick Start](#-quick-start)\n- [Project Structure](#-project-structure)\n- [Configuration](#-configuration)\n- [Physical Principles](#-physical-principles)\n- [Signal Processing Pipeline](#-signal-processing-pipeline)\n- [Technology Stack](#-technology-stack)\n- [API Reference](#-api-reference)\n- [Hardware Interface](#-hardware-interface)\n- [Development](#-development)\n- [Documentation](#-documentation)\n- [License](#-license)\n\n---\n\n## 🌟 Overview\n\nRust-Photoacoustic is a complete platform for laser photoacoustic spectroscopy (LPAS), designed for real-time gas concentration measurement with laboratory-grade precision. The system provides:\n\n- **ppb-level sensitivity** (parts per billion) for trace gas detection\n- **Real-time processing** with \u003c10ms latency\n- **Multi-platform support** (Linux, macOS, Windows)\n- **Industrial integration** via Modbus TCP and REST API\n- **Modern web interface** for visualization and control\n\n### Development Philosophy\n\nThis 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.\n\n\u003e ⚠️ **Status**: Active development - APIs may change between commits.\n\n---\n\n## ✨ Key Features\n\n```mermaid\nmindmap\n  root((Rust-Photoacoustic))\n    Signal Processing\n      Real-time FFT\n      Butterworth filters\n      Differential subtraction\n      Lock-in detection\n      Python integration\n    Hardware Control\n      USB-HID interface\n      I2C/SPI protocols\n      Thermal regulation\n      DDS modulation\n    Web Interface\n      Real-time streaming\n      OAuth2/JWT security\n      6 languages + RTL\n      Interactive graphs\n    Industrial\n      Modbus TCP server\n      Redis Pub/Sub\n      Kafka streaming\n      REST API\n```\n\n### Performance Metrics\n\n| Metric | Value | Notes |\n|--------|-------|-------|\n| **Sampling Rate** | 48 kHz | Stereo, 16-bit |\n| **FFT Resolution** | 4096 points | Configurable 256-8192 |\n| **Processing Latency** | \u003c 10 ms | Real-time streaming |\n| **Web Streaming** | 60 fps | SSE with compression |\n| **ADC Resolution** | 16-bit | ±7.8 µV @ PGA=16 |\n| **DDS Resolution** | 0.004 Hz | 28-bit frequency register |\n| **Temperature Control** | ±0.1°C | PID regulation |\n\n---\n\n## 🏗️ Architecture\n\n```mermaid\nflowchart TB\n    subgraph Hardware[\"🔧 Hardware Layer\"]\n        MIC[\"Microphones A/B\"]\n        LASER[\"QCL/DFB Laser\"]\n        TEC[\"TEC Controllers\"]\n        NTC[\"NTC Thermistors\"]\n    end\n\n    subgraph LaserSmart[\"⚡ Laser+Smart Interface\"]\n        USB[\"USB-HID\"]\n        ADC[\"4× ADS1115\u003cbr/\u003e16-bit ADC\"]\n        DAC[\"LTC2641\u003cbr/\u003e12-bit DAC\"]\n        DDS[\"AD9833\u003cbr/\u003eDDS Modulator\"]\n    end\n\n    subgraph Backend[\"🦀 Rust Backend\"]\n        ACQ[\"Acquisition\u003cbr/\u003eDaemon\"]\n        PROC[\"Processing\u003cbr/\u003eGraph Engine\"]\n        THERM[\"Thermal\u003cbr/\u003eRegulation\"]\n        API[\"REST API\u003cbr/\u003e+ SSE\"]\n        MODBUS[\"Modbus\u003cbr/\u003eServer\"]\n    end\n\n    subgraph Frontend[\"⚛️ React Frontend\"]\n        DASH[\"Dashboard\"]\n        AUDIO[\"Audio\u003cbr/\u003eAnalyzer\"]\n        GRAPH[\"Processing\u003cbr/\u003eGraph Editor\"]\n        THERMAL[\"Thermal\u003cbr/\u003eMonitor\"]\n    end\n\n    subgraph External[\"🌐 External Systems\"]\n        SCADA[\"SCADA/PLC\"]\n        REDIS[\"Redis\"]\n        KAFKA[\"Kafka\"]\n    end\n\n    MIC --\u003e ADC\n    LASER --\u003e DAC\n    TEC --\u003e DAC\n    NTC --\u003e ADC\n    \n    ADC --\u003e USB\n    DAC --\u003e USB\n    DDS --\u003e USB\n    USB --\u003e ACQ\n    \n    ACQ --\u003e PROC\n    PROC --\u003e API\n    PROC --\u003e MODBUS\n    THERM --\u003e API\n    \n    API --\u003e DASH\n    API --\u003e AUDIO\n    API --\u003e GRAPH\n    API --\u003e THERMAL\n    \n    MODBUS --\u003e SCADA\n    PROC --\u003e REDIS\n    PROC --\u003e KAFKA\n```\n\n---\n\n## 🚀 Quick Start\n\n### Prerequisites\n\n- **Rust** 1.75 or later\n- **Node.js** 20+ (for frontend)\n- **Python** 3.10+ (optional, for Python drivers)\n\n### Installation\n\n```bash\n# Clone the repository\ngit clone https://github.com/sctg-development/rust-photoacoustic.git\ncd rust-photoacoustic\n\n# Build the backend\ncd rust\ncargo build --release\n\n# Install frontend dependencies\ncd ../web\nnpm install\n\n# Start the application\ncd ../rust\ncargo run --release -- --server\n```\n\n### Quick Test\n\n```bash\n# Run with a test audio file\ncargo run -- --input-file examples/test_signal.wav --frequency 2000\n\n# Start server on custom port\ncargo run -- --server --web-port 9000\n\n# Enable verbose logging\ncargo run -- --server -v\n```\n\n---\n\n## 📁 Project Structure\n\n```plaintext\nrust-photoacoustic/\n├── rust/                          # 🦀 Rust Backend\n│   ├── src/\n│   │   ├── main.rs               # Application entry point\n│   │   ├── lib.rs                # Library exports\n│   │   ├── acquisition/          # Audio signal acquisition (CPAL)\n│   │   ├── preprocessing/        # Digital filters, differential\n│   │   ├── spectral/             # FFT, spectral analysis\n│   │   ├── processing/           # Processing graph engine (~3000 lines)\n│   │   ├── visualization/        # Web server, API, OAuth2\n│   │   ├── thermal_regulation/   # PID controllers\n│   │   ├── modbus/               # Modbus TCP server\n│   │   ├── daemon/               # Acquisition daemon\n│   │   ├── config/               # Configuration management\n│   │   ├── photoacoustic/        # Core domain logic\n│   │   └── utility/              # Helpers, certificate generation\n│   ├── auth-macros/              # Procedural macros for auth\n│   ├── examples/                 # Usage examples\n│   ├── tests/                    # Integration tests\n│   └── Cargo.toml\n│\n├── web/                           # ⚛️ React Frontend\n│   ├── src/\n│   │   ├── pages/                # Route pages\n│   │   │   ├── index.tsx         # Dashboard\n│   │   │   ├── audio.tsx         # Audio analyzer\n│   │   │   ├── thermal.tsx       # Thermal monitor\n│   │   │   └── graph.tsx         # Processing graph editor\n│   │   ├── components/           # Reusable UI components\n│   │   ├── hooks/                # Custom React hooks\n│   │   │   ├── useAudioStream.ts # Audio streaming (~2000 lines)\n│   │   │   └── useProcessingGraph.ts\n│   │   ├── authentication/       # Auth0/OIDC integration\n│   │   ├── locales/              # i18n translations (6 languages)\n│   │   └── contexts/             # React contexts\n│   └── package.json\n│\n├── hardware/                      # ⚡ Hardware Designs\n│   └── 6C47543F-DEE8-4421-881E-CF5E1C8FF55D/  # Laser+Smart\n│       ├── *.SchDoc              # Altium schematics\n│       ├── components/           # JLCPCB component library\n│       └── doc/                  # Hardware documentation\n│\n├── docs/                          # 📚 Documentation\n│   ├── COMPLETE_TECHNICAL_DOCUMENTATION.md\n│   ├── acquisition_daemon_guide_en.md\n│   ├── jwt_tokens.md\n│   └── ...\n│\n└── .github/                       # 🔄 CI/CD\n    └── workflows/\n        ├── ci.yml\n        ├── code-quality.yml\n        └── release-multiarch.yml\n```\n\n---\n\n## ⚙️ Configuration\n\n### Configuration File\n\nThe application uses YAML configuration. Create `config.yaml`:\n\n```yaml\n# Audio acquisition settings\nacquisition:\n  sample_rate: 48000              # Hz\n  buffer_size: 4096               # samples\n  channels: 2                     # stereo (A/B microphones)\n\n# Signal processing settings\nprocessing:\n  excitation_frequency: 2000.0    # Hz (laser modulation)\n  filter_bandwidth: 100.0         # Hz (bandpass filter)\n  fft_size: 4096                  # FFT window size\n  window_function: hann           # hann, blackman_harris, hamming\n  averaging_count: 10             # spectra to average\n\n# Web server settings\nvisualization:\n  port: 8080\n  address: \"127.0.0.1\"\n  name: \"LaserSmartApiServer/0.1.0\"\n  hmac_secret: \"your-secure-jwt-secret-key\"\n  # Optional: Base64-encoded SSL certificates\n  # cert: \"LS0tLS1CRUdJTi...\"\n  # key: \"LS0tLS1CRUdJTi...\"\n\n# Modbus TCP server (industrial integration)\nmodbus:\n  enabled: true\n  address: \"0.0.0.0\"\n  port: 5020\n\n# Thermal regulation (PID control)\nthermal_regulation:\n  enabled: true\n  setpoint: 25.0                  # °C\n  kp: 1.0                         # Proportional gain\n  ki: 0.1                         # Integral gain\n  kd: 0.05                        # Derivative gain\n\n# Processing graph (hot-reloadable)\nprocessing_graph:\n  nodes:\n    - id: \"audio_input\"\n      type: \"AudioSource\"\n      config:\n        device: \"default\"\n    - id: \"bandpass\"\n      type: \"ButterworthFilter\"\n      config:\n        filter_type: \"bandpass\"\n        low_cutoff: 1900.0\n        high_cutoff: 2100.0\n        order: 4\n    - id: \"fft\"\n      type: \"FFTAnalyzer\"\n      config:\n        size: 4096\n```\n\n### Command Line Options\n\n```bash\n# Core options\n--config \u003cpath\u003e           # Configuration file path (default: config.yaml)\n--server                  # Start in server mode\n--input-device \u003cname\u003e     # Audio input device (e.g., hw:0,0)\n--input-file \u003cpath\u003e       # Analyze WAV file instead of live audio\n\n# Processing parameters\n--frequency \u003cHz\u003e          # Excitation frequency (default: 2000)\n--bandwidth \u003cHz\u003e          # Filter bandwidth (default: 100)\n--window-size \u003csamples\u003e   # FFT size (default: 4096)\n--averages \u003ccount\u003e        # Spectra to average (default: 10)\n\n# Server options\n--web-port, -p \u003cport\u003e     # Web server port (default: 8080)\n--web-address \u003caddr\u003e      # Bind address (default: 127.0.0.1)\n--hmac-secret \u003csecret\u003e    # JWT signing secret\n\n# Modbus options\n--modbus-enabled          # Enable Modbus server\n--modbus-address \u003caddr\u003e   # Modbus bind address\n--modbus-port \u003cport\u003e      # Modbus port (default: 5020)\n\n# Logging\n--verbose, -v             # Debug logging\n--quiet, -q               # Suppress all output\n--show-config-schema      # Print JSON schema and exit\n```\n\n### SSL Certificates\n\nCertificates are auto-generated during build for development. For production:\n\n1. Place certificates in `resources/` directory\n2. Or specify base64-encoded in config:\n\n```yaml\nvisualization:\n  cert: |\n    LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0t...\n  key: |\n    LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0t...\n```\n\n---\n\n## 🔬 Physical Principles\n\n### Photoacoustic Spectroscopy\n\n```mermaid\nsequenceDiagram\n    participant L as Modulated Laser\n    participant G as Gas Sample\n    participant M as Microphone\n    participant S as Signal Processing\n\n    L-\u003e\u003eG: Pulsed IR radiation (f = 2 kHz)\n    Note over G: Molecular absorption\u003cbr/\u003eH₂O, CO₂, CH₄...\n    G-\u003e\u003eG: Thermal expansion\u003cbr/\u003e(photoacoustic effect)\n    G-\u003e\u003eM: Acoustic wave\n    M-\u003e\u003eS: Electrical signal\n    S-\u003e\u003eS: FFT at excitation frequency\n    Note over S: Amplitude ∝ concentration\n```\n\n**Key equations:**\n\n- Photoacoustic signal: $S_{PA} = \\alpha \\cdot P_L \\cdot C \\cdot Q$\n  - $\\alpha$: absorption coefficient (cm⁻¹)\n  - $P_L$: laser power (W)\n  - $C$: gas concentration\n  - $Q$: cell quality factor\n\n- Helmholtz resonance: $f_0 = \\frac{c}{2\\pi}\\sqrt{\\frac{A}{V \\cdot L}}$\n  - $c$: speed of sound\n  - $A$: neck cross-section\n  - $V$: cavity volume\n  - $L$: effective neck length\n\n### Differential Detection\n\nTwo microphones (A and B) enable common-mode noise rejection:\n\n$$S_{diff} = S_A - S_B$$\n\nThis cancels:\n- Ambient acoustic noise\n- Electronic interference\n- Temperature fluctuations\n\n---\n\n## 🔄 Signal Processing Pipeline\n\n```mermaid\ngraph LR\n    subgraph Acquisition\n        A1[Mic A] --\u003e |48kHz/16-bit| B1[Buffer A]\n        A2[Mic B] --\u003e |48kHz/16-bit| B2[Buffer B]\n    end\n    \n    subgraph Preprocessing\n        B1 --\u003e C1[Bandpass\u003cbr/\u003eFilter]\n        B2 --\u003e C2[Bandpass\u003cbr/\u003eFilter]\n        C1 --\u003e D[Differential\u003cbr/\u003eA - B]\n        C2 --\u003e D\n    end\n    \n    subgraph Analysis\n        D --\u003e E[Windowing\u003cbr/\u003eHann/Blackman]\n        E --\u003e F[FFT\u003cbr/\u003e4096 pts]\n        F --\u003e G[Peak\u003cbr/\u003eDetection]\n    end\n    \n    subgraph Output\n        G --\u003e H1[REST API]\n        G --\u003e H2[Modbus]\n        G --\u003e H3[SSE Stream]\n    end\n```\n\n### Processing Nodes Available\n\n| Node Type | Description | Parameters |\n|-----------|-------------|------------|\n| `AudioSource` | Audio input acquisition | device, sample_rate |\n| `WavFileSource` | WAV file reader | path, loop |\n| `ButterworthFilter` | IIR bandpass/lowpass/highpass | order, cutoff frequencies |\n| `Differential` | Channel subtraction | - |\n| `FFTAnalyzer` | Spectral analysis | size, window, overlap |\n| `PeakDetector` | Frequency/amplitude extraction | threshold, range |\n| `Averager` | Temporal averaging | count |\n| `PythonNode` | Custom Python processing | script_path |\n\n---\n\n## 🛠️ Technology Stack\n\n### Backend (Rust)\n\n| Category | Technology | Version |\n|----------|------------|---------|\n| Web Framework | Rocket | 0.5.1 |\n| Async Runtime | Tokio | 1.45 |\n| Audio | CPAL | 0.17 |\n| FFT | RustFFT | 6.4 |\n| Auth | jsonwebtoken + oxide-auth | 10.2 |\n| Modbus | tokio-modbus | 0.17 |\n| Python | PyO3 | 0.27 |\n| Serialization | Serde | 1.0 |\n\n### Frontend (TypeScript/React)\n\n| Category | Technology | Version |\n|----------|------------|---------|\n| Framework | React | 19.2 |\n| Build Tool | Vite | 7.3 |\n| UI Library | HeroUI | 2.x |\n| Charts | Chart.js | 4.5 |\n| Flow Editor | ReactFlow | 11.x |\n| Audio Viz | AudioMotion | 4.5 |\n| i18n | i18next | 25.x |\n| Auth | Auth0 / OIDC | 2.x |\n\n### Hardware (Laser+Smart)\n\n| Component | Part Number | Function |\n|-----------|-------------|----------|\n| MCU | ATmega32U4 | USB-HID controller |\n| ADC | ADS1115 ×4 | 16-bit, I²C, 860 SPS |\n| DAC | LTC2641 | 12-bit, SPI |\n| DDS | AD9833 | Frequency synthesis |\n| GPIO | MCP23017 | I²C expander |\n| Reference | REF5040 | 4.096V precision |\n\n---\n\n## 📡 API Reference\n\n### Authentication\n\nThe API supports OAuth2 with PKCE and JWT bearer tokens:\n\n```bash\n# Get OAuth2 authorization\nGET /oauth/authorize?client_id=\u003cid\u003e\u0026redirect_uri=\u003curi\u003e\u0026response_type=code\u0026code_challenge=\u003cchallenge\u003e\n\n# Exchange code for token\nPOST /oauth/token\nContent-Type: application/x-www-form-urlencoded\ngrant_type=authorization_code\u0026code=\u003ccode\u003e\u0026code_verifier=\u003cverifier\u003e\n\n# Access protected endpoints\nGET /api/v1/spectrum\nAuthorization: Bearer \u003cjwt_token\u003e\n```\n\n### REST Endpoints\n\n| Method | Endpoint | Description |\n|--------|----------|-------------|\n| GET | `/api/v1/status` | System status |\n| GET | `/api/v1/spectrum` | Current spectrum data |\n| GET | `/api/v1/spectrum/stream` | SSE spectrum stream |\n| GET | `/api/v1/config` | Current configuration |\n| PUT | `/api/v1/config` | Update configuration |\n| GET | `/api/v1/graph` | Processing graph state |\n| PUT | `/api/v1/graph` | Update processing graph |\n| GET | `/api/v1/thermal` | Thermal sensor readings |\n| PUT | `/api/v1/thermal/setpoint` | Set temperature target |\n\n### Modbus Registers\n\n| Address | Type | Description |\n|---------|------|-------------|\n| 0-1 | Float32 | Excitation frequency (Hz) |\n| 2-3 | Float32 | Signal amplitude |\n| 4-5 | Float32 | Phase (degrees) |\n| 6-7 | Float32 | Temperature (°C) |\n| 100+ | Float32[] | Spectrum data |\n\n### OpenAPI Documentation\n\nInteractive API documentation available at:\n- **RapiDoc**: `https://localhost:8080/rapidoc`\n- **Swagger**: `https://localhost:8080/swagger`\n\n---\n\n## ⚡ Hardware Interface\n\n### Laser+Smart Board\n\nThe Laser+Smart interface board provides:\n\n- **4× 16-bit ADC channels** (ADS1115) for microphone and sensor inputs\n- **12-bit DAC** (LTC2641) for laser power control\n- **DDS synthesizer** (AD9833) for laser modulation (0.004 Hz resolution)\n- **16 GPIO** (MCP23017) for auxiliary control\n- **USB-HID** interface (no drivers required)\n\n### Connection Diagram\n\n```\n┌─────────────────────────────────────────────┐\n│              Laser+Smart Board              │\n├──────────────┬──────────────┬───────────────┤\n│   ADC0-1     │    DAC       │     DDS       │\n│  Mic A/B     │  Laser PWR   │  Modulation   │\n│   ±2.048V    │   0-4.096V   │  100Hz-14kHz  │\n├──────────────┼──────────────┼───────────────┤\n│   ADC2-3     │    GPIO      │     USB       │\n│  NTC Sensors │  TEC Control │  HID to Host  │\n│   ±2.048V    │   8 outputs  │   Full Speed  │\n└──────────────┴──────────────┴───────────────┘\n```\n\n---\n\n## 💻 Development\n\n### Building from Source\n\n```bash\n# Development build\ncargo build\n\n# Release build with optimizations\ncargo build --release\n\n# With Python driver support\ncargo build --features python-driver\n\n# Static build (musl)\ncargo build --release --features static --target x86_64-unknown-linux-musl\n```\n\n### Running Tests\n\n```bash\n# Unit tests\ncargo test\n\n# Integration tests\ncargo test --test '*'\n\n# With coverage\ncargo tarpaulin --out Html\n\n# Frontend tests\ncd web \u0026\u0026 npm test\n```\n\n### Development Server\n\n```bash\n# Backend with hot-reload (requires cargo-watch)\ncargo watch -x 'run -- --server -v'\n\n# Frontend dev server\ncd web \u0026\u0026 npm run dev\n\n# Full stack with proxy\ncd web \u0026\u0026 npm run dev:env\n```\n\n---\n\n## 📚 Documentation\n\n- **[Complete Technical Documentation](COMPLETE_TECHNICAL_DOCUMENTATION.md)** - Comprehensive guide for all audiences\n- **[Acquisition Daemon Guide](acquisition_daemon_guide_en.md)** - Audio acquisition system\n- **[JWT Tokens](jwt_tokens.md)** - Authentication details\n- **[Hardware Analysis](../hardware/doc/driver-analysis-doc.md)** - Laser+Smart interface\n\n---\n\n## 📜 License\n\nThis project is licensed under the **SCTG Non-Commercial License 1.0**.\n\n- ✅ Free for research and education\n- ✅ Open source contributions welcome\n- ❌ Commercial use requires separate license\n\nSee [LICENSE](../LICENSE) for details.\n\n---\n\n## 🤝 Contributing\n\nContributions are welcome! Please read our contributing guidelines before submitting pull requests.\n\n1. Fork the repository\n2. Create a feature branch (`git checkout -b feature/amazing-feature`)\n3. Commit your changes (`git commit -m 'Add amazing feature'`)\n4. Push to the branch (`git push origin feature/amazing-feature`)\n5. Open a Pull Request\n\n---\n\n## 📧 Contact\n\n- **Author**: Ronan Le Meillat\n- **Organization**: SCTG Development\n- **Repository**: [github.com/sctg-development/rust-photoacoustic](https://github.com/sctg-development/rust-photoacoustic)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsctg-development%2Frust-photoacoustic","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsctg-development%2Frust-photoacoustic","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsctg-development%2Frust-photoacoustic/lists"}