mirror of
https://github.com/smittix/intercept.git
synced 2026-04-24 06:40:00 -07:00
Add multi-arch build support and detailed antenna guide
Multi-arch Docker builds: - build-multiarch.sh: Cross-compile amd64+arm64 on x64 and push to registry, so RPi5 can docker pull instead of building natively - docker-compose.yml: Add INTERCEPT_IMAGE env var to support pulling pre-built images from a registry instead of local build - README.md: Docker build section rewritten with multi-arch workflow, registry pull instructions, and build script options Weather satellite antenna guide (sidebar panel): - V-Dipole: ASCII diagram, 53.4cm element length, 120 degree angle, materials, orientation, connection instructions - Turnstile/Crossed Dipole: phasing coax length (37cm RG-58), reflector distance (52cm below), RHCP explanation - QFH Quadrifilar Helix: design overview, materials, height (46cm), hemispherical gain pattern - Placement & LNA: outdoor requirements, coax loss figures, LNA mounting position, Nooelec SAWbird+ recommendation, Bias-T - Quick reference table: wavelength, quarter-wave, elevation, duration, polarization, APT/LRPT bandwidth Also added Weather Satellites and ISS SSTV to README features list, SatDump to acknowledgments. https://claude.ai/code/session_01FjLTkyELaqh27U1wEXngFQ
This commit is contained in:
152
README.md
152
README.md
@@ -32,6 +32,8 @@ Support the developer of this open-source project
|
|||||||
- **Vessel Tracking** - AIS ship tracking with VHF DSC distress monitoring
|
- **Vessel Tracking** - AIS ship tracking with VHF DSC distress monitoring
|
||||||
- **ACARS Messaging** - Aircraft datalink messages via acarsdec
|
- **ACARS Messaging** - Aircraft datalink messages via acarsdec
|
||||||
- **Listening Post** - Frequency scanner with audio monitoring
|
- **Listening Post** - Frequency scanner with audio monitoring
|
||||||
|
- **Weather Satellites** - NOAA APT and Meteor LRPT image decoding via SatDump
|
||||||
|
- **ISS SSTV** - Slow-scan TV image reception from the International Space Station
|
||||||
- **Satellite Tracking** - Pass prediction using TLE data
|
- **Satellite Tracking** - Pass prediction using TLE data
|
||||||
- **ADS-B History** - Persistent aircraft history with reporting dashboard (Postgres optional)
|
- **ADS-B History** - Persistent aircraft history with reporting dashboard (Postgres optional)
|
||||||
- **WiFi Scanning** - Monitor mode reconnaissance via aircrack-ng
|
- **WiFi Scanning** - Monitor mode reconnaissance via aircrack-ng
|
||||||
@@ -55,67 +57,106 @@ cd intercept
|
|||||||
sudo -E venv/bin/python intercept.py
|
sudo -E venv/bin/python intercept.py
|
||||||
```
|
```
|
||||||
|
|
||||||
### Docker (Alternative)
|
### Docker
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
git clone https://github.com/smittix/intercept.git
|
git clone https://github.com/smittix/intercept.git
|
||||||
cd intercept
|
cd intercept
|
||||||
docker compose up -d
|
docker compose --profile basic up -d --build
|
||||||
```
|
```
|
||||||
|
|
||||||
> **Note:** Docker requires privileged mode for USB SDR access. See `docker-compose.yml` for configuration options.
|
> **Note:** Docker requires privileged mode for USB SDR access. SDR devices are passed through via `/dev/bus/usb`.
|
||||||
|
|
||||||
### ADS-B History (Optional)
|
#### Multi-Architecture Builds (amd64 + arm64)
|
||||||
|
|
||||||
The ADS-B history feature persists aircraft messages to Postgres for long-term analysis.
|
Cross-compile on an x64 machine and push to a registry. This is much faster than building natively on an RPi.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Start with ADS-B history and Postgres
|
# One-time setup on your x64 build machine
|
||||||
docker compose --profile history up -d
|
docker run --privileged --rm tonistiigi/binfmt --install all
|
||||||
```
|
docker buildx create --name intercept-builder --use --bootstrap
|
||||||
|
|
||||||
Set the following environment variables (for example in a `.env` file):
|
# Build and push for both architectures
|
||||||
|
REGISTRY=ghcr.io/youruser ./build-multiarch.sh --push
|
||||||
```bash
|
|
||||||
INTERCEPT_ADSB_HISTORY_ENABLED=true
|
# On the RPi5, just pull and run
|
||||||
INTERCEPT_ADSB_DB_HOST=adsb_db
|
INTERCEPT_IMAGE=ghcr.io/youruser/intercept:latest docker compose --profile basic up -d
|
||||||
INTERCEPT_ADSB_DB_PORT=5432
|
```
|
||||||
INTERCEPT_ADSB_DB_NAME=intercept_adsb
|
|
||||||
INTERCEPT_ADSB_DB_USER=intercept
|
Build script options:
|
||||||
INTERCEPT_ADSB_DB_PASSWORD=intercept
|
|
||||||
```
|
| Flag | Description |
|
||||||
|
|------|-------------|
|
||||||
### Other ADS-B Settings
|
| `--push` | Push to container registry |
|
||||||
|
| `--load` | Load into local Docker (single platform only) |
|
||||||
Set these as environment variables for either local installs or Docker:
|
| `--arm64-only` | Build arm64 only (for RPi deployment) |
|
||||||
|
| `--amd64-only` | Build amd64 only |
|
||||||
| Variable | Default | Description |
|
|
||||||
|----------|---------|-------------|
|
Environment variables: `REGISTRY`, `IMAGE_NAME`, `IMAGE_TAG`
|
||||||
| `INTERCEPT_ADSB_AUTO_START` | `false` | Auto-start ADS-B tracking when the dashboard loads |
|
|
||||||
| `INTERCEPT_SHARED_OBSERVER_LOCATION` | `true` | Share observer location across ADS-B/AIS/SSTV/Satellite modules |
|
#### Using a Pre-built Image
|
||||||
|
|
||||||
**Local install example**
|
If you've pushed to a registry, you can skip building entirely on the target machine:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
INTERCEPT_ADSB_AUTO_START=true \
|
# Set in .env or export
|
||||||
INTERCEPT_SHARED_OBSERVER_LOCATION=false \
|
INTERCEPT_IMAGE=ghcr.io/youruser/intercept:latest
|
||||||
python app.py
|
|
||||||
```
|
# Then just run
|
||||||
|
docker compose --profile basic up -d
|
||||||
**Docker example (.env)**
|
```
|
||||||
|
|
||||||
```bash
|
### ADS-B History (Optional)
|
||||||
INTERCEPT_ADSB_AUTO_START=true
|
|
||||||
INTERCEPT_SHARED_OBSERVER_LOCATION=false
|
The ADS-B history feature persists aircraft messages to Postgres for long-term analysis.
|
||||||
```
|
|
||||||
|
```bash
|
||||||
To store Postgres data on external storage, set `PGDATA_PATH` (defaults to `./pgdata`):
|
# Start with ADS-B history and Postgres
|
||||||
|
docker compose --profile history up -d
|
||||||
```bash
|
```
|
||||||
PGDATA_PATH=/mnt/usbpi1/intercept/pgdata
|
|
||||||
```
|
Set the following environment variables (for example in a `.env` file):
|
||||||
|
|
||||||
Then open **/adsb/history** for the reporting dashboard.
|
```bash
|
||||||
|
INTERCEPT_ADSB_HISTORY_ENABLED=true
|
||||||
|
INTERCEPT_ADSB_DB_HOST=adsb_db
|
||||||
|
INTERCEPT_ADSB_DB_PORT=5432
|
||||||
|
INTERCEPT_ADSB_DB_NAME=intercept_adsb
|
||||||
|
INTERCEPT_ADSB_DB_USER=intercept
|
||||||
|
INTERCEPT_ADSB_DB_PASSWORD=intercept
|
||||||
|
```
|
||||||
|
|
||||||
|
### Other ADS-B Settings
|
||||||
|
|
||||||
|
Set these as environment variables for either local installs or Docker:
|
||||||
|
|
||||||
|
| Variable | Default | Description |
|
||||||
|
|----------|---------|-------------|
|
||||||
|
| `INTERCEPT_ADSB_AUTO_START` | `false` | Auto-start ADS-B tracking when the dashboard loads |
|
||||||
|
| `INTERCEPT_SHARED_OBSERVER_LOCATION` | `true` | Share observer location across ADS-B/AIS/SSTV/Satellite modules |
|
||||||
|
|
||||||
|
**Local install example**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
INTERCEPT_ADSB_AUTO_START=true \
|
||||||
|
INTERCEPT_SHARED_OBSERVER_LOCATION=false \
|
||||||
|
python app.py
|
||||||
|
```
|
||||||
|
|
||||||
|
**Docker example (.env)**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
INTERCEPT_ADSB_AUTO_START=true
|
||||||
|
INTERCEPT_SHARED_OBSERVER_LOCATION=false
|
||||||
|
```
|
||||||
|
|
||||||
|
To store Postgres data on external storage, set `PGDATA_PATH` (defaults to `./pgdata`):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
PGDATA_PATH=/mnt/usbpi1/intercept/pgdata
|
||||||
|
```
|
||||||
|
|
||||||
|
Then open **/adsb/history** for the reporting dashboard.
|
||||||
|
|
||||||
### Open the Interface
|
### Open the Interface
|
||||||
|
|
||||||
@@ -195,6 +236,7 @@ Created by **smittix** - [GitHub](https://github.com/smittix)
|
|||||||
[acarsdec](https://github.com/TLeconte/acarsdec) |
|
[acarsdec](https://github.com/TLeconte/acarsdec) |
|
||||||
[aircrack-ng](https://www.aircrack-ng.org/) |
|
[aircrack-ng](https://www.aircrack-ng.org/) |
|
||||||
[Leaflet.js](https://leafletjs.com/) |
|
[Leaflet.js](https://leafletjs.com/) |
|
||||||
|
[SatDump](https://github.com/SatDump/SatDump) |
|
||||||
[Celestrak](https://celestrak.org/) |
|
[Celestrak](https://celestrak.org/) |
|
||||||
[Priyom.org](https://priyom.org/)
|
[Priyom.org](https://priyom.org/)
|
||||||
|
|
||||||
|
|||||||
139
build-multiarch.sh
Executable file
139
build-multiarch.sh
Executable file
@@ -0,0 +1,139 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# INTERCEPT - Multi-architecture Docker image builder
|
||||||
|
#
|
||||||
|
# Builds for both linux/amd64 and linux/arm64 using Docker buildx.
|
||||||
|
# Run this on your x64 machine to cross-compile the arm64 image
|
||||||
|
# instead of building natively on the RPi5.
|
||||||
|
#
|
||||||
|
# Prerequisites (one-time setup):
|
||||||
|
# docker run --privileged --rm tonistiigi/binfmt --install all
|
||||||
|
# docker buildx create --name intercept-builder --use --bootstrap
|
||||||
|
#
|
||||||
|
# Usage:
|
||||||
|
# ./build-multiarch.sh # Build both platforms, load locally
|
||||||
|
# ./build-multiarch.sh --push # Build and push to registry
|
||||||
|
# ./build-multiarch.sh --arm64-only # Build arm64 only (for RPi)
|
||||||
|
# REGISTRY=ghcr.io/user ./build-multiarch.sh --push
|
||||||
|
#
|
||||||
|
# Environment variables:
|
||||||
|
# REGISTRY - Container registry (default: docker.io/library)
|
||||||
|
# IMAGE_NAME - Image name (default: intercept)
|
||||||
|
# IMAGE_TAG - Image tag (default: latest)
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
# Configuration
|
||||||
|
REGISTRY="${REGISTRY:-}"
|
||||||
|
IMAGE_NAME="${IMAGE_NAME:-intercept}"
|
||||||
|
IMAGE_TAG="${IMAGE_TAG:-latest}"
|
||||||
|
BUILDER_NAME="intercept-builder"
|
||||||
|
PLATFORMS="linux/amd64,linux/arm64"
|
||||||
|
|
||||||
|
# Parse arguments
|
||||||
|
PUSH=false
|
||||||
|
LOAD=false
|
||||||
|
ARM64_ONLY=false
|
||||||
|
|
||||||
|
for arg in "$@"; do
|
||||||
|
case $arg in
|
||||||
|
--push) PUSH=true ;;
|
||||||
|
--load) LOAD=true ;;
|
||||||
|
--arm64-only)
|
||||||
|
ARM64_ONLY=true
|
||||||
|
PLATFORMS="linux/arm64"
|
||||||
|
;;
|
||||||
|
--amd64-only)
|
||||||
|
PLATFORMS="linux/amd64"
|
||||||
|
;;
|
||||||
|
--help|-h)
|
||||||
|
echo "Usage: $0 [--push] [--load] [--arm64-only] [--amd64-only]"
|
||||||
|
echo ""
|
||||||
|
echo "Options:"
|
||||||
|
echo " --push Push to container registry"
|
||||||
|
echo " --load Load into local Docker (single platform only)"
|
||||||
|
echo " --arm64-only Build arm64 only (for RPi5 deployment)"
|
||||||
|
echo " --amd64-only Build amd64 only"
|
||||||
|
echo ""
|
||||||
|
echo "Environment variables:"
|
||||||
|
echo " REGISTRY Container registry (e.g. ghcr.io/username)"
|
||||||
|
echo " IMAGE_NAME Image name (default: intercept)"
|
||||||
|
echo " IMAGE_TAG Image tag (default: latest)"
|
||||||
|
echo ""
|
||||||
|
echo "Examples:"
|
||||||
|
echo " $0 --push # Build both, push"
|
||||||
|
echo " REGISTRY=ghcr.io/myuser $0 --push # Push to GHCR"
|
||||||
|
echo " $0 --arm64-only --load # Build arm64, load locally"
|
||||||
|
echo " $0 --arm64-only --push && ssh rpi docker pull # Build + deploy to RPi"
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "Unknown option: $arg"
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
# Build full image reference
|
||||||
|
if [ -n "$REGISTRY" ]; then
|
||||||
|
FULL_IMAGE="${REGISTRY}/${IMAGE_NAME}:${IMAGE_TAG}"
|
||||||
|
else
|
||||||
|
FULL_IMAGE="${IMAGE_NAME}:${IMAGE_TAG}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "============================================"
|
||||||
|
echo " INTERCEPT Multi-Architecture Builder"
|
||||||
|
echo "============================================"
|
||||||
|
echo " Image: ${FULL_IMAGE}"
|
||||||
|
echo " Platforms: ${PLATFORMS}"
|
||||||
|
echo " Push: ${PUSH}"
|
||||||
|
echo "============================================"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Check if buildx builder exists, create if not
|
||||||
|
if ! docker buildx inspect "$BUILDER_NAME" >/dev/null 2>&1; then
|
||||||
|
echo "Creating buildx builder: ${BUILDER_NAME}"
|
||||||
|
docker buildx create --name "$BUILDER_NAME" --use --bootstrap
|
||||||
|
|
||||||
|
# Check for QEMU support
|
||||||
|
if ! docker run --rm --privileged tonistiigi/binfmt --install all >/dev/null 2>&1; then
|
||||||
|
echo "WARNING: QEMU binfmt setup may have failed."
|
||||||
|
echo "Run: docker run --privileged --rm tonistiigi/binfmt --install all"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
docker buildx use "$BUILDER_NAME"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Build command
|
||||||
|
BUILD_CMD="docker buildx build --platform ${PLATFORMS} --tag ${FULL_IMAGE}"
|
||||||
|
|
||||||
|
if [ "$PUSH" = true ]; then
|
||||||
|
BUILD_CMD="${BUILD_CMD} --push"
|
||||||
|
echo "Will push to: ${FULL_IMAGE}"
|
||||||
|
elif [ "$LOAD" = true ]; then
|
||||||
|
# --load only works with single platform
|
||||||
|
if echo "$PLATFORMS" | grep -q ","; then
|
||||||
|
echo "ERROR: --load only works with a single platform."
|
||||||
|
echo "Use --arm64-only or --amd64-only with --load."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
BUILD_CMD="${BUILD_CMD} --load"
|
||||||
|
echo "Will load into local Docker"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "Building..."
|
||||||
|
echo "Command: ${BUILD_CMD} ."
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
$BUILD_CMD .
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "============================================"
|
||||||
|
echo " Build complete!"
|
||||||
|
if [ "$PUSH" = true ]; then
|
||||||
|
echo " Image pushed to: ${FULL_IMAGE}"
|
||||||
|
echo ""
|
||||||
|
echo " Pull on RPi5:"
|
||||||
|
echo " docker pull ${FULL_IMAGE}"
|
||||||
|
fi
|
||||||
|
echo "============================================"
|
||||||
@@ -1,14 +1,18 @@
|
|||||||
# INTERCEPT - Signal Intelligence Platform
|
# INTERCEPT - Signal Intelligence Platform
|
||||||
# Docker Compose configuration for easy deployment
|
# Docker Compose configuration for easy deployment
|
||||||
#
|
#
|
||||||
# Basic usage:
|
# Basic usage (build locally):
|
||||||
# docker compose --profile basic up -d
|
# docker compose --profile basic up -d --build
|
||||||
|
#
|
||||||
|
# Basic usage (pre-built image from registry):
|
||||||
|
# INTERCEPT_IMAGE=ghcr.io/user/intercept:latest docker compose --profile basic up -d
|
||||||
#
|
#
|
||||||
# With ADS-B history (Postgres):
|
# With ADS-B history (Postgres):
|
||||||
# docker compose --profile history up -d
|
# docker compose --profile history up -d
|
||||||
|
|
||||||
services:
|
services:
|
||||||
intercept:
|
intercept:
|
||||||
|
image: ${INTERCEPT_IMAGE:-}
|
||||||
build: .
|
build: .
|
||||||
container_name: intercept
|
container_name: intercept
|
||||||
profiles:
|
profiles:
|
||||||
@@ -54,6 +58,7 @@ services:
|
|||||||
# ADS-B history with Postgres persistence
|
# ADS-B history with Postgres persistence
|
||||||
# Enable with: docker compose --profile history up -d
|
# Enable with: docker compose --profile history up -d
|
||||||
intercept-history:
|
intercept-history:
|
||||||
|
image: ${INTERCEPT_IMAGE:-}
|
||||||
build: .
|
build: .
|
||||||
container_name: intercept-history
|
container_name: intercept-history
|
||||||
profiles:
|
profiles:
|
||||||
|
|||||||
@@ -31,39 +31,145 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- Antenna Guide - detailed -->
|
||||||
<div class="section">
|
<div class="section">
|
||||||
<h3>Antenna Guide (137 MHz)</h3>
|
<h3>Antenna Guide</h3>
|
||||||
<div style="font-size: 11px; color: var(--text-dim);">
|
<div style="font-size: 11px; color: var(--text-dim); line-height: 1.5;">
|
||||||
<p style="margin-bottom: 8px; color: var(--accent-cyan);">Weather satellites transmit at ~137 MHz. Your stock SDR antenna likely won't work well at this frequency.</p>
|
|
||||||
|
|
||||||
<div style="margin-bottom: 8px;">
|
<p style="margin-bottom: 10px; color: var(--accent-cyan); font-weight: 600;">
|
||||||
<strong style="color: var(--text-primary);">V-Dipole (Easiest Build)</strong>
|
137 MHz band — your stock SDR antenna will NOT work.
|
||||||
<ul style="margin: 4px 0 0 16px; padding: 0;">
|
</p>
|
||||||
<li>Two elements, ~53.4 cm each (quarter wavelength)</li>
|
<p style="margin-bottom: 10px;">
|
||||||
<li>Spread at 120 angle, laid flat or tilted</li>
|
Weather satellites transmit at 137.1–137.9 MHz. The quarter-wave
|
||||||
<li>Connect to SDR via coax with a BNC/SMA adapter</li>
|
at this frequency is <strong style="color: var(--text-primary);">~53 cm</strong>,
|
||||||
<li>Cost: ~$5 in wire</li>
|
far longer than the small telescopic antenna shipped with most SDRs
|
||||||
|
(tuned for ~1 GHz). You need a purpose-built antenna.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<!-- V-Dipole -->
|
||||||
|
<div style="background: var(--bg-primary); border: 1px solid var(--border-color); border-radius: 4px; padding: 10px; margin-bottom: 10px;">
|
||||||
|
<strong style="color: var(--accent-cyan); font-size: 12px;">V-Dipole (Easiest — ~$5)</strong>
|
||||||
|
|
||||||
|
<div style="margin: 8px 0; padding: 8px; background: var(--bg-tertiary); border-radius: 3px; font-family: 'JetBrains Mono', monospace; font-size: 10px; color: var(--text-secondary); white-space: pre; line-height: 1.3; text-align: center;"> coax to SDR
|
||||||
|
|
|
||||||
|
===+=== feed point
|
||||||
|
/ \
|
||||||
|
/ 120 \
|
||||||
|
/ \
|
||||||
|
/ deg \
|
||||||
|
53.4cm 53.4cm</div>
|
||||||
|
|
||||||
|
<ul style="margin: 6px 0 0 14px; padding: 0;">
|
||||||
|
<li><strong style="color: var(--text-primary);">Element length:</strong> 53.4 cm each (quarter wavelength at 137 MHz)</li>
|
||||||
|
<li><strong style="color: var(--text-primary);">Angle:</strong> 120° between elements (not 180°)</li>
|
||||||
|
<li><strong style="color: var(--text-primary);">Material:</strong> Any stiff wire, coat hanger, or copper rod</li>
|
||||||
|
<li><strong style="color: var(--text-primary);">Orientation:</strong> Lay flat or tilt 30° toward expected pass direction</li>
|
||||||
|
<li><strong style="color: var(--text-primary);">Polarization:</strong> The 120° angle gives partial RHCP match to satellite signal</li>
|
||||||
|
<li><strong style="color: var(--text-primary);">Connection:</strong> Solder elements to coax center + shield, connect to SDR via SMA</li>
|
||||||
|
</ul>
|
||||||
|
<p style="margin-top: 6px; color: var(--text-dim); font-style: italic;">
|
||||||
|
Best starter antenna. Good enough for clear NOAA images with a direct overhead pass.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Turnstile -->
|
||||||
|
<div style="background: var(--bg-primary); border: 1px solid var(--border-color); border-radius: 4px; padding: 10px; margin-bottom: 10px;">
|
||||||
|
<strong style="color: var(--accent-cyan); font-size: 12px;">Turnstile / Crossed Dipole (~$10-15)</strong>
|
||||||
|
|
||||||
|
<div style="margin: 8px 0; padding: 8px; background: var(--bg-tertiary); border-radius: 3px; font-family: 'JetBrains Mono', monospace; font-size: 10px; color: var(--text-secondary); white-space: pre; line-height: 1.3; text-align: center;"> 53.4cm
|
||||||
|
<--------->
|
||||||
|
====+==== dipole 1
|
||||||
|
|
|
||||||
|
====+==== dipole 2
|
||||||
|
<--------->
|
||||||
|
90 deg rotated
|
||||||
|
+ reflector below</div>
|
||||||
|
|
||||||
|
<ul style="margin: 6px 0 0 14px; padding: 0;">
|
||||||
|
<li><strong style="color: var(--text-primary);">Elements:</strong> Two crossed dipoles, each 53.4 cm per side (4 elements total)</li>
|
||||||
|
<li><strong style="color: var(--text-primary);">Angle:</strong> 90° between the two dipole pairs</li>
|
||||||
|
<li><strong style="color: var(--text-primary);">Phasing:</strong> Feed dipole 2 with a 90° delay (quarter-wave coax section ~37 cm of RG-58)</li>
|
||||||
|
<li><strong style="color: var(--text-primary);">Reflector:</strong> Place ~52 cm below elements (ground plane or wire grid)</li>
|
||||||
|
<li><strong style="color: var(--text-primary);">Polarization:</strong> Circular (RHCP) — matches satellite transmission</li>
|
||||||
|
</ul>
|
||||||
|
<p style="margin-top: 6px; color: var(--text-dim); font-style: italic;">
|
||||||
|
Better than V-dipole. The reflector rejects ground noise and the RHCP phasing matches the satellite signal.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- QFH -->
|
||||||
|
<div style="background: var(--bg-primary); border: 1px solid var(--border-color); border-radius: 4px; padding: 10px; margin-bottom: 10px;">
|
||||||
|
<strong style="color: #00ff88; font-size: 12px;">QFH — Quadrifilar Helix (Best — ~$20-30)</strong>
|
||||||
|
|
||||||
|
<div style="margin: 8px 0; padding: 8px; background: var(--bg-tertiary); border-radius: 3px; font-family: 'JetBrains Mono', monospace; font-size: 10px; color: var(--text-secondary); white-space: pre; line-height: 1.3; text-align: center;"> ___
|
||||||
|
/ \ two helix loops
|
||||||
|
| | | twisted 90 deg
|
||||||
|
| | | around a mast
|
||||||
|
\___/
|
||||||
|
|
|
||||||
|
coax</div>
|
||||||
|
|
||||||
|
<ul style="margin: 6px 0 0 14px; padding: 0;">
|
||||||
|
<li><strong style="color: var(--text-primary);">Design:</strong> Two bifilar helical loops, offset 90°</li>
|
||||||
|
<li><strong style="color: var(--text-primary);">Material:</strong> Copper pipe (10mm), copper wire, or coax outer shield</li>
|
||||||
|
<li><strong style="color: var(--text-primary);">Total height:</strong> ~46 cm (for 137 MHz)</li>
|
||||||
|
<li><strong style="color: var(--text-primary);">Loop dimensions:</strong> Use a QFH calculator for exact bending measurements</li>
|
||||||
|
<li><strong style="color: var(--text-primary);">Polarization:</strong> True RHCP omnidirectional — ideal for overhead satellite passes</li>
|
||||||
|
<li><strong style="color: var(--text-primary);">Gain pattern:</strong> Hemispherical upward coverage, rejects ground interference</li>
|
||||||
|
</ul>
|
||||||
|
<p style="margin-top: 6px; color: var(--text-dim); font-style: italic;">
|
||||||
|
Gold standard for weather satellite reception. No tracking needed — covers the whole sky.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Placement & LNA -->
|
||||||
|
<div style="background: var(--bg-primary); border: 1px solid var(--border-color); border-radius: 4px; padding: 10px; margin-bottom: 10px;">
|
||||||
|
<strong style="color: var(--accent-cyan); font-size: 12px;">Placement & LNA</strong>
|
||||||
|
<ul style="margin: 6px 0 0 14px; padding: 0;">
|
||||||
|
<li><strong style="color: var(--text-primary);">Location:</strong> OUTDOORS with clear sky view is critical. Roof/balcony/open field.</li>
|
||||||
|
<li><strong style="color: var(--text-primary);">Height:</strong> Higher is better but not critical — clear horizon line matters more</li>
|
||||||
|
<li><strong style="color: var(--text-primary);">Antenna up:</strong> Point the antenna straight UP (zenith) for best overhead coverage</li>
|
||||||
|
<li><strong style="color: var(--text-primary);">Avoid:</strong> Metal roofs, power lines, buildings blocking the sky</li>
|
||||||
|
<li><strong style="color: var(--text-primary);">Coax length:</strong> Keep short (<10m). Signal loss at 137 MHz is ~3 dB per 10m of RG-58</li>
|
||||||
|
<li><strong style="color: var(--text-primary);">LNA:</strong> Mount at the antenna feed point, NOT at the SDR end.
|
||||||
|
Recommended: Nooelec SAWbird+ NOAA (137 MHz filtered LNA, ~$30)</li>
|
||||||
|
<li><strong style="color: var(--text-primary);">Bias-T:</strong> Enable the Bias-T checkbox above if your LNA is powered via the coax from the SDR</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style="margin-bottom: 8px;">
|
<!-- Quick reference -->
|
||||||
<strong style="color: var(--text-primary);">QFH Antenna (Best)</strong>
|
<div style="background: var(--bg-primary); border: 1px solid var(--border-color); border-radius: 4px; padding: 10px;">
|
||||||
<ul style="margin: 4px 0 0 16px; padding: 0;">
|
<strong style="color: var(--accent-cyan); font-size: 12px;">Quick Reference</strong>
|
||||||
<li>Quadrifilar helix - omnidirectional RHCP</li>
|
<table style="width: 100%; margin-top: 6px; font-size: 10px; border-collapse: collapse;">
|
||||||
<li>Best for overhead passes, rejects ground noise</li>
|
<tr style="border-bottom: 1px solid var(--border-color);">
|
||||||
<li>Build from copper pipe or coax</li>
|
<td style="padding: 3px 4px; color: var(--text-dim);">Wavelength (137 MHz)</td>
|
||||||
<li>Cost: ~$20-30 in materials</li>
|
<td style="padding: 3px 4px; color: var(--text-primary); text-align: right;">218.8 cm</td>
|
||||||
</ul>
|
</tr>
|
||||||
</div>
|
<tr style="border-bottom: 1px solid var(--border-color);">
|
||||||
|
<td style="padding: 3px 4px; color: var(--text-dim);">Quarter wave (element length)</td>
|
||||||
<div style="margin-bottom: 8px;">
|
<td style="padding: 3px 4px; color: var(--text-primary); text-align: right;">53.4 cm</td>
|
||||||
<strong style="color: var(--text-primary);">Tips</strong>
|
</tr>
|
||||||
<ul style="margin: 4px 0 0 16px; padding: 0;">
|
<tr style="border-bottom: 1px solid var(--border-color);">
|
||||||
<li>Outdoors with clear sky view is critical</li>
|
<td style="padding: 3px 4px; color: var(--text-dim);">Best pass elevation</td>
|
||||||
<li>LNA (e.g. Nooelec SAWbird) helps a lot</li>
|
<td style="padding: 3px 4px; color: var(--text-primary); text-align: right;">> 30°</td>
|
||||||
<li>Enable Bias-T if using a powered LNA</li>
|
</tr>
|
||||||
<li>Passes >30 elevation give best images</li>
|
<tr style="border-bottom: 1px solid var(--border-color);">
|
||||||
</ul>
|
<td style="padding: 3px 4px; color: var(--text-dim);">Typical pass duration</td>
|
||||||
|
<td style="padding: 3px 4px; color: var(--text-primary); text-align: right;">10-15 min</td>
|
||||||
|
</tr>
|
||||||
|
<tr style="border-bottom: 1px solid var(--border-color);">
|
||||||
|
<td style="padding: 3px 4px; color: var(--text-dim);">Polarization</td>
|
||||||
|
<td style="padding: 3px 4px; color: var(--text-primary); text-align: right;">RHCP</td>
|
||||||
|
</tr>
|
||||||
|
<tr style="border-bottom: 1px solid var(--border-color);">
|
||||||
|
<td style="padding: 3px 4px; color: var(--text-dim);">NOAA (APT) bandwidth</td>
|
||||||
|
<td style="padding: 3px 4px; color: var(--text-primary); text-align: right;">~40 kHz</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td style="padding: 3px 4px; color: var(--text-dim);">Meteor (LRPT) bandwidth</td>
|
||||||
|
<td style="padding: 3px 4px; color: var(--text-primary); text-align: right;">~140 kHz</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user