Skip to content

Friedjof/MultiGeiger

Β 
Β 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

MultiGeiger πŸ›°οΈ

Build Status Documentation Status

The MultiGeiger is an ESP32-based radioactivity measurement device designed for citizen science projects. It features a modern web interface, multiple connectivity options (WiFi, LoRa, BLE), and environmental sensors for comprehensive environmental monitoring.

✨ Key Features

  • πŸ“Š Radiation Measurement - Accurate detection using Geiger-MΓΌller tubes with real-time CPM/CPS/Β΅Sv/h display
  • 🌐 Modern Web Interface - Single-page application (SPA) with live updates and responsive design
  • πŸ” Secure Access - Session-based authentication protects configuration and OTA updates
  • πŸ“‘ Multiple Connectivity - WiFi, LoRaWAN/TTN, BLE, MQTT with TLS support
  • 🌑️ Environmental Sensors - Optional temperature, humidity, pressure, and air quality monitoring (BMP280/BME280/BME680)
  • ☁️ Cloud Integration - MQTT + TTN/LoRaWAN forwarding with OpenSenseMap compatibility
  • ⏰ Time Synchronization - Automatic browser-to-device time sync for accurate timestamps
  • πŸ”‹ Low Power Design - Optimized for battery operation with deep sleep support

πŸš€ Quick Start

Default Credentials:

WiFi Access Point:

  • SSID: MultiGeiger-XXXXXX (last 6 digits of MAC address)
  • Password: ESP32Geiger

Web Interface Login:

  • Username: admin
  • Password: admin
  • ⚠️ Change these immediately in the Settings page!

Steps:

  1. πŸ”Œ Power on your MultiGeiger device
  2. πŸ“Ά Connect to the WiFi access point MultiGeiger-XXXXXX
  3. 🌐 Open http://192.168.4.1 in your browser
  4. πŸ“Š View live data on the Dashboard (no login required)
  5. βš™οΈ Click "Settings" β†’ Login with admin/admin β†’ Configure device
  6. πŸ” Important: Change password in Settings β†’ Authorization section!

πŸ–₯️ Web Interface

The MultiGeiger features a modern, single-page web application (SPA) with session-based authentication, real-time updates, and a mobile-optimized design:

Dashboard Status Settings
Dashboard Status Settings
Real-time monitoring:
β€’ πŸ“ˆ Live radiation levels
β€’ 🌑️ Environmental data
β€’ ⏱️ Uptime & system info
β€’ ⚠️ HV error warnings
Connectivity status:
β€’ πŸ“Ά WiFi signal strength
β€’ πŸ“‘ MQTT connection
β€’ πŸ›°οΈ LoRa transmissions
β€’ πŸ“² BLE advertising
Secure configuration:
β€’ πŸ” Login-protected access
β€’ πŸ“Ά WiFi setup
β€’ πŸ“‘ MQTT & LoRa credentials
β€’ βš™οΈ Device settings

Key Features

  • πŸ” Session Authentication - Secure login with HttpOnly cookies (30min session timeout)
  • πŸ”„ Live Updates - Real-time polling (2s interval) for instant feedback
  • ⏰ Time Sync - Automatic browser-to-device time synchronization
  • 🎨 Modern UI - Clean, responsive design built with vanilla JavaScript (no frameworks!)
  • πŸ“± Mobile-First - Touch-friendly interface optimized for smartphones and tablets
  • πŸ§ͺ Mock API - Local development mode with simulated device data

Access Points:

Default Login:

  • Username: admin
  • Password: admin
  • ⚠️ Change these immediately after first setup!

πŸ” Security & Authentication

Session-Based Authentication

Protected endpoints (configuration, OTA updates) require login:

  • Session Management: HttpOnly cookies with 30-minute sliding expiration
  • CSRF Protection: SameSite=Lax cookie attribute
  • AP Mode: Authentication skipped (WiFi password provides access control)
  • Default Credentials: admin / admin (⚠️ Change immediately!)

Protected Endpoints

  • /config - Configuration page
  • /api/config - Configuration API (GET/POST)
  • /api/config/ping - Heartbeat for session keep-alive
  • /update - OTA firmware upload

Security Best Practices

  1. βœ… Change default password immediately after first setup
  2. βœ… Use strong credentials (min. 8 characters, mixed case + numbers)
  3. βœ… Enable WiFi encryption (WPA2 or better)
  4. ⚠️ HTTP only - ESP32 doesn't support HTTPS (use VPN for remote access)
  5. πŸ”’ AP Mode Security - Strong AP password acts as first authentication layer

API Access

Login:

curl -X POST http://multigeiger.local/api/auth/login \
  -H "Content-Type: application/json" \
  -d '{"username":"admin","password":"admin"}' \
  -c cookies.txt

Authenticated Request:

curl http://multigeiger.local/api/config \
  -b cookies.txt

πŸ“‘ Connectivity Options

WiFi πŸ“Ά

Standard 802.11 b/g/n connectivity for:

  • Web interface access
  • MQTT data publishing
  • OTA firmware updates

LoRaWAN πŸ›°οΈ

Long-range connectivity via The Things Network (TTN v3):

  • Activation Mode: ABP (Activation By Personalization)
  • Frequency Plan: EU868 (868.1 MHz)
  • Payload: 10 bytes (radiation data) + 5 bytes (environmental data)
  • Compatibility: Works with single-channel gateways (e.g., Dragino LG01-N)

Note: MultiGeiger uses ABP instead of OTAA to ensure compatibility with single-channel LoRaWAN gateways which cannot reliably handle OTAA join procedures.

See LoRa Setup Guide for TTN configuration.

MQTT πŸ“¨

Publish data to any MQTT broker (Mosquitto, HiveMQ, etc.):

  • Protocols: MQTT 3.1.1, MQTT over TLS
  • Topics: Configurable (default: multigeiger/<chip-id>/data)
  • Payload: JSON format with all sensor readings
  • QoS: Configurable (0, 1, or 2)

Bluetooth Low Energy (BLE) πŸ“²

Local data access for mobile apps and nearby devices.

🌐 Cloud Integration & Data Forwarding

The MultiGeiger can send data to various platforms. Beyond direct uploads, you can leverage TTN's MQTT server to forward data to additional services.

TTN MQTT Server πŸ”„

The Things Network provides an MQTT server that pushes real-time uplink messages. You can use this to forward MultiGeiger data to other platforms like OpenSenseMap.

Setup:

  1. πŸ”‘ Create an API key in your TTN Application:

    • Go to Applications β†’ Your Application β†’ API keys
    • Click + Add API key
    • Grant rights: Read application traffic
    • Copy the generated key
  2. πŸ“‘ Connect to TTN MQTT broker:

    • Host: <region>.cloud.thethings.network (e.g., eu1.cloud.thethings.network)
    • Port: 8883 (TLS) or 1883 (plain)
    • Username: <application-id>@ttn
    • Password: <api-key>
    • Topic: v3/<application-id>/devices/+/up
  3. πŸ”€ Forward data using Node-RED, n8n, or custom scripts

OpenSenseMap Integration πŸ—ΊοΈ

Forward TTN data to OpenSenseMap for public visualization:

OpenSenseMap Integration

Step 1: Create OpenSenseMap Sensor

  1. Register at https://opensensemap.org/
  2. Create a new senseBox (manual configuration)
  3. Add a sensor for radiation (phenomenon: "Ionizing Radiation", unit: "Β΅Sv/h")
  4. Note your senseBoxId and sensorId

Step 2: n8n Workflow for Data Forwarding

Use n8n (or Node-RED) to subscribe to TTN MQTT and forward to OpenSenseMap:

n8n Workflow: TTN to OpenSenseMap

n8n Code Node Example:

const senseBoxId = '<your-sensebox-id>';  // Your Box-ID from OpenSenseMap
const sensorId = '<your-sensor-id>';      // Your Sensor-ID for radiation

// Extract decoded payload from TTN
const rawValue = $input.first().json.message.uplink_message.decoded_payload.uSvph;
const roundedValue = parseFloat(rawValue.toFixed(3));  // Round to 3 decimals

const data = { value: roundedValue };

// POST to OpenSenseMap ingress API
const response = await this.helpers.httpRequest({
  method: 'POST',
  url: `https://ingress.opensensemap.org/boxes/${senseBoxId}/${sensorId}`,
  headers: {
    'Content-Type': 'application/json'
  },
  body: data,
  options: {
    response: { fullResponse: true }
  }
});

return [{ json: {
  status: response.statusCode,
  data: data
}}];

Workflow Overview:

  1. πŸ“¨ MQTT Trigger Node: Subscribe to TTN uplink topic
  2. πŸ”§ Code Node: Extract and transform payload
  3. 🌐 HTTP Request: POST to OpenSenseMap API

Direct Uploads πŸ“€

Legacy HTTP uploads (sensor.community/madavi/custom) have been removed. Use MQTT or TTN/LoRaWAN forwarding pipelines for cloud ingestion.

πŸ”§ Development & Building

Requirements πŸ“‹

  • PlatformIO: For ESP32 firmware compilation
  • Python 3.11+: For build tools and documentation
  • uv: Modern Python package manager (pip install uv)

Makefile Commands πŸ› οΈ

The project uses a Makefile for common tasks:

make setup     # prepare config + docs venv
make build     # build web assets + compile firmware
make flash     # upload firmware
make monitor   # serial console
make docs      # build Sphinx docs
make clean     # clean build artifacts
make release v=1.23.0  # tag + push release (injects VERSION/core.hpp)

More details and additional targets: see docs/source/development.rst.

Project Structure πŸ“

MultiGeiger/
β”œβ”€β”€ src/                     # ESP32 firmware (C++)
β”‚   β”œβ”€β”€ app/                 # Application logic
β”‚   β”œβ”€β”€ comm/                # Communication modules
β”‚   β”‚   β”œβ”€β”€ wifi/            # WiFi, HTTP, mDNS
β”‚   β”‚   β”œβ”€β”€ lora/            # LoRaWAN (LMIC)
β”‚   β”‚   └── mqtt/            # MQTT client
β”‚   β”œβ”€β”€ sensors/             # Geiger tube, BMP280/BME280/BME680
β”‚   └── main.cpp             # Entry point
β”œβ”€β”€ web/                     # Web interface (Single-Page Application)
β”‚   β”œβ”€β”€ index.html           # SPA entry point (Dashboard + Status + Settings)
β”‚   β”œβ”€β”€ src/                 # JavaScript/CSS sources
β”‚   β”‚   β”œβ”€β”€ main.js          # Entry point & initialization
β”‚   β”‚   β”œβ”€β”€ app.js           # Main application class (MultiGeigerApp)
β”‚   β”‚   └── style.css        # Responsive UI styles
β”‚   β”œβ”€β”€ public/              # Static assets
β”‚   β”‚   └── mock/api.js      # Mock API for local development
β”‚   β”œβ”€β”€ vite.config.js       # Vite build configuration
β”‚   └── package.json         # Web dependencies
β”œβ”€β”€ docs/                    # Sphinx documentation
β”‚   β”œβ”€β”€ source/              # reStructuredText files
β”‚   β”œβ”€β”€ images/              # Screenshots
β”‚   └── assembly/            # Assembly PDFs
β”œβ”€β”€ tools/                   # Build & data tools
β”‚   β”œβ”€β”€ ttn_fetcher/         # TTN data downloader
β”‚   β”‚   β”œβ”€β”€ fetch_ttn_data.py    # CLI tool
β”‚   β”‚   β”œβ”€β”€ ttn_daemon.py        # Background daemon
β”‚   β”‚   └── README.md        # TTN fetcher docs
β”‚   └── mqtt_logger/         # MQTT to SQLite logger
β”œβ”€β”€ scripts/                 # Helper scripts
β”‚   └── web_to_header.py     # dist/ β†’ gzip Header (genutzt im Makefile)
β”œβ”€β”€ .github/                 # CI/CD workflows
β”‚   └── workflows/
β”‚       └── build.yml        # Automated builds
β”œβ”€β”€ platformio.ini           # PlatformIO configuration
β”œβ”€β”€ Makefile                 # Build automation
└── README.md                # This file

πŸ“Š Data Tools

TTN Data Fetcher πŸ“‘

Download and archive LoRaWAN uplink data from TTN Storage Integration API:

cd tools/ttn_fetcher

# Install dependencies
pip install -r requirements.txt

# Create config
cp ttn_config.example.json ttn_config.json
nano ttn_config.json  # Add your TTN API credentials

# Fetch data once
python3 fetch_ttn_data.py --config ttn_config.json

# Run as daemon (poll every 5 minutes)
python3 ttn_daemon.py --config ttn_config.json --interval 300

Features:

  • πŸ’Ύ SQLite database storage with automatic deduplication
  • πŸ“Š Parse decoded payloads (GM counts, CPM, CPS, tube info)
  • πŸ“€ Export to JSON or CSV
  • πŸ”„ Daemon mode with systemd service support
  • πŸ” Query historical data with SQL

See tools/ttn_fetcher/README.md for full documentation.

MQTT Logger πŸ“

Log MQTT data to SQLite database:

cd tools/mqtt_logger
cp .env.example .env
nano .env  # Configure MQTT broker
uv sync
uv run mqtt_logger.py

See tools/mqtt_logger/README.md for details.

πŸ› οΈ Hardware

Supported Boards πŸŽ›οΈ

  • Heltec WiFi Kit 32 (recommended)
  • Heltec Wireless Stick
  • Generic ESP32 (with modifications)

Required Components πŸ”©

  • ☒️ Geiger-MΓΌller tube (various types supported: SBM-20, SBM-19, SI-3BG, etc.)
  • ⚑ High voltage generator (400-500V for GM tube)
  • 🌑️ Optional: BMP280/BME280/BME680 environmental sensor (IΒ²C)
    • BMP280: Temperature + Pressure only
    • BME280: Temperature + Humidity + Pressure
    • BME680: Temperature + Humidity + Pressure + Air Quality (Gas)
  • πŸ“‘ Optional: LoRa module (SX1276/RFM95W for TTN)

See hardware documentation in docs/hardware/ for schematics and PCB files.

Assembly Guide πŸ“–

Download the detailed assembly instructions (German):

πŸ“š Documentation

Online Documentation 🌐

πŸ“– https://multigeiger.readthedocs.org/

Comprehensive documentation with:

  • 🌍 Multi-language support (English + Deutsch) - use the language switcher in the lower right
  • πŸ“Œ Versioned docs (latest, stable, specific releases)
  • πŸ” Full-text search
  • πŸ“± Mobile-optimized

Key Pages πŸ“„

Build Locally πŸ—οΈ

make docs              # Build with Sphinx
make docs-serve        # Serve at http://localhost:8000

Generated docs: docs/build/html/index.html

πŸ—ΊοΈ Community & Resources

🀝 Contributing

Contributions are welcome! πŸŽ‰

  • πŸ› Bug Reports: Open an issue with reproduction steps
  • ✨ Feature Requests: Describe your use case
  • πŸ”§ Pull Requests: Fork, branch, test, and submit

Quality Standards:

  • βœ… Automated CI/CD: GitHub Actions runs builds and tests on all PRs
  • πŸ“ Documentation: Update docs for user-facing changes
  • πŸ§ͺ Testing: Ensure existing functionality works

See .github/README.md for CI/CD details.

πŸ“„ License

See LICENSE file for details.

πŸ‘₯ Authors & Credits

See AUTHORS file for contributors.


Made with ❀️ by the Ecocurious community for citizen science and environmental monitoring

Support the project: ⭐ Star this repo | πŸ› Report bugs | πŸ“– Improve docs | πŸ’‘ Share ideas

About

ESP32-based MultiGeiger firmware with LoRa/MQTT telemetry, web UI, and optional environmental sensing.

Topics

Resources

License

Stars

Watchers

Forks

Languages

  • C++ 57.9%
  • JavaScript 14.3%
  • Python 12.3%
  • HTML 7.5%
  • CSS 6.8%
  • Makefile 1.1%
  • Shell 0.1%