Setup your Radar
Build a privacy-first traffic radar; 1x Pi, no cameras, no cloud, just local speed data PDFs
A weatherproof traffic logger that keeps data local, requires no cameras, and helps you make a data-informed case for safer streets.
Difficulty: Intermediate • Time: 2–4 hours • Cost: $650
On this page
Introduction #
Safer streets start with measured traffic speeds.
One afternoon, a Raspberry Pi, and a radar sensor. By the evening you will have a speed monitor logging every vehicle that passes, a live dashboard, and the beginnings of the dataset that goes to your next council meeting. No cameras, no licence plates, no cloud accounts: just local speed data on hardware you own.
Before you begin #
Tools needed:
- Computer with Raspberry Pi Imager installed
- 5/16" nut driver (steel bands)
- Screwdriver
- Handsaw or circular saw
- Drill and bits
- Pencil and tape measure
- Optional: mitre box for 45° cuts
- Optional: multimeter
No soldering required · No coding required · No prior radar experience needed
Privacy considerations #
What this system collects #
| ✅ Collected | Vehicle speed, direction, timestamp |
| ❌ Not collected | No licence plates, no vehicle photos, no driver identity |
| ❌ Not transmitted | All data stays on your device |
Compliance #
Measuring vehicle speeds on public streets from your own property is generally legal. Mounting on public utility poles requires explicit permission. Always check your local regulations.
What you will build #
- Doppler radar logger: captures vehicle speeds 24/7
- Local SQLite database: all data stays on the device
- Live web dashboard: real-time speeds, histograms, time-of-day patterns
- Professional PDF reports: traffic engineering metrics (p50, p85, p98)
- Weatherproof hardware: designed for permanent outdoor deployment
The velocity.report Pi image includes everything pre-configured: flash one SD card, connect one sensor, and it starts collecting.
Parts list #
| Part | Price | Notes |
|---|---|---|
| Radar sensor OPS7243-A-CW-R2 | $420 | IP67, 100 m range, RS232 |
| Sensor mounting bracket OPS100-BK | $50 | Metal bracket for OPS7243 enclosure |
| Sensor cable OPS700-CBL-M1-PT-1.8 | $17 | M12 to pigtail; connects sensor to serial HAT |
| Raspberry Pi 4 (2 GB) | $55 | Also compatible with Pi 5 |
| Waveshare PoE HAT (F) | $20 | Powers the Pi + sensor over Ethernet |
| Waveshare RS232 HAT | $16 | RS232 interface for the sensor |
| Adafruit DE-9 serial connector | $3 | Connects sensor cable to serial HAT |
| SanDisk High Endurance 32 GB | $23 | High-endurance; designed for continuous writes |
| Core total | $604 | |
| ABS pipe, 4-in × 2-ft | $25 | Sensor mast |
| Timber stud, 2×4 × 8-ft | $4 | Crossbar and upright |
| Hose clamps ×2 | $6 | Clamp crossbar to roof rack bars |
| Corner braces, 4-pack | $5 | Brace the T-frame |
| Deck screws, 67-pack | $6 | Frame assembly |
| Full total | $650 | Core + roof rack mount |
Power is delivered over Ethernet via the PoE HAT. You will need a PoE-capable switch or injector on the network side. For mobile deployment you will also need a PoE battery pack or 12 V car outlet adapter, and a short Ethernet cable.
Step-by-step build guide #
Build overview (total time: 2–4 hours)
- Wire the Sensor to the Raspberry Pi: 15–30 minutes
- Flash the Pi Image: 10–15 minutes
- Access the Web Dashboard: 5 minutes
- Mount the Radar Sensor: 1–2 hours
- Configure Your Site: 10 minutes
- Generate Reports: after data collection
Step 1: wire the sensor to the Raspberry Pi #
Estimated time: 15–30 minutes
The OPS7243-A-CW-R2 sensor connects to the Raspberry Pi via an RS232 serial HAT. The PoE HAT stacks on top to provide power over Ethernet.
-
Attach the PoE HAT to the Raspberry Pi’s 40-pin GPIO header
-
Stack the serial HAT (Waveshare RS232/485) on top of the PoE HAT. Ensure all pins are aligned and fully seated.
-
Wire the sensor to the HAT following the wiring diagram below:
Step 2: flash the Pi image #
Estimated time: 10–15 minutes
The velocity.report image is a complete Raspberry Pi OS with everything pre-installed and pre-configured; flash it to an SD card and the system is ready to run.
Option A: use the custom Raspberry Pi Imager catalogue (recommended) #
This opens Raspberry Pi Imager with the velocity.report image pre-loaded:
macOS
cd "/Applications/Raspberry Pi Imager.app/Contents/MacOS/" && \
./rpi-imager --repo https://velocity.report/rpi.json
Linux
rpi-imager --repo https://velocity.report/rpi.json
Windows
"C:\Program Files (x86)\Raspberry Pi Imager\rpi-imager.exe" --repo https://velocity.report/rpi.json
- Select your Pi model
- Select velocity.report from the OS list
- Choose your SD card (32 GB high-endurance recommended)
- Configure settings before writing:
- Click the gear icon (⚙) or Edit Settings
- Set hostname:
velocity(or your preference) - Enable SSH: select Allow public-key authentication only and paste your public key (recommended). If you do not have an SSH key, select password authentication and choose a strong password.
- Set username and password: choose a username and password (required even with key authentication, for
sudo) - Configure Wi-Fi (optional): the Pi connects via Ethernet by default through the PoE HAT. Add Wi-Fi credentials only if you need wireless access as a fallback or for initial setup without Ethernet.
- Write the image
Option B: manual download #
- Download the latest
.img.xzfile from GitHub Releases - Open Raspberry Pi Imager, select Choose OS → Use custom, and select the file
- Configure settings as above, then write
After flashing #
- Insert the SD card into your Raspberry Pi and connect the PoE Ethernet cable
- Wait 1–2 minutes for first boot, then connect:
ssh velocity@velocity.local
The service starts automatically on boot and configures the sensor (JSON mode, units, magnitude). Verify it is running:
velocity-status
To watch live logs:
velocity-log
The image installs shell aliases for common operations: velocity-status, velocity-log, velocity-bounce (restart), velocity-stop, and velocity-start. See the Reference section for the full list.
Step 3: access the web dashboard #
Estimated time: 5 minutes
Open a browser on any device on the same network: https://velocity.local
The Pi generates a self-signed TLS certificate on first boot. Your browser will show a certificate warning: this is expected for a self-signed certificate. Click Advanced → Proceed to velocity.local (Chrome/Edge) or Accept the Risk and Continue (Firefox/Safari). No certificate installation is needed.
Success criteria: the dashboard loads and shows live vehicle detections or “No data yet”
If the dashboard will not load:
- Check the service is running:
velocity-status - Find the Pi’s IP address:
hostname -I - Test from the Pi itself:
curl -k https://localhost/ - Check logs:
velocity-log
Step 4: mount the radar sensor #
Estimated time: 1–2 hours
The same hardware supports two deployment modes: a portable rig on your car roof rack, or a fixed mount at home. Pick whichever suits the situation, or build both and move the sensor to whichever street needs attention this month.
Deployment option A: car roof rack mount (mobile) #
A portable rig that clamps to a standard roof rack. Park on any street, collect data for a few hours or a few days, then drive to the next location. One sensor, many streets.
Parts are listed in the parts list above. You will also need a PoE battery pack or 12 V car outlet adapter, and a short Ethernet cable from sensor to Pi.
Building the roof rack mount
-
Cut the 2×4 into four pieces: one 32-inch crossbar, one 24-inch upright, and two 11-inch braces (top-edge measurement, 45° mitres at both ends).
-
Build the main T-joint first: centre the upright on the crossbar and fasten it with corner brackets and deck screws so it stands properly vertical.
-
Fit the two 45° braces, one each side, and fasten with the remaining brackets and deck screws. These braces are what keep the structure from developing opinions in the wind.
-
Mark two pipe fixing points where it overlaps the wooden upright: 6-inch and 12-inch up from the bottom of the pipe. Drill pilot holes through the pipe into the wood.
-
Attach the pipe to the upright: hold the pipe vertical against the upright and drive screws through the pilot holes into the wood until the mast is locked in place.
-
Measure roof-rack bar spacing centre-to-centre, then mark and drill matching clamp holes in the crossbar.
-
Attach the sensor to the pipe. Use hose clamps to secure the sensor body to the pipe. Tighten evenly.
-
Clamp the crossbar to the roof rack. Use the two 1-13/16 to 3 in galvanised clamps and tighten firmly so the mount stays stable in wind while parked.
-
Route the cable from the sensor through a rear window seal or sunroof into the car. Connect to the Pi and power source inside.
Do not drive with the mount attached!
Deployment option B: home installation (permanent) #
A permanent mount on your property, aimed at the street.
Positioning:
- Mount 4–8 feet off the ground (reduces false detections from small objects)
- Use two stainless steel hose clamps (top and bottom)
- Choose a location with a clear line of sight to traffic
Weatherproofing checklist:
- ✅ Enclosure gasket intact and clean
- ✅ Seal tested before final mounting
- ✅ All cable glands sealed
Success criteria: enclosure is weatherproof, sensor aims correctly, mounting is secure
Aiming the sensor #
Once the sensor is mounted, aim it before collecting data. These guidelines apply to both deployments. For the mobile mount, parking parallel to the kerb already puts you close to 0°.
- Angle: as close to 0° (parallel with traffic flow) as practical, typically 15–25°. Lower angles need less cosine correction, so the speed readings are more accurate.
- Road coverage: the beam must encompass the full lane of traffic you are measuring. Angling the sensor 15–25° widens the field-of-view triangle enough to capture vehicles across the lane while keeping cosine error small. Choose the smallest angle whose beam triangle fully covers the lane.
- Orientation: face approaching or receding traffic (not perpendicular)
Recording your mounting angle
You will enter this in the dashboard as the cosine error angle (Step 5).
- Take a photo looking straight down at the road surface, perpendicular to the kerb. Include the sensor and the road in the frame.
- Draw one line along the kerb and a second line from the sensor along its beam direction.
- Measure the angle between the two lines and subtract from 90°. A phone protractor app works.
Step 5: configure your site #
Estimated time: 10 minutes
Before generating reports, configure your site in the dashboard so speed measurements are corrected for your mounting angle.
- Open the dashboard at https://velocity.local
- Navigate to Site Settings
- Set the site location on the interactive map
- Set the cosine error angle to match your radar mounting angle from Step 4. Drag the red dot on the radar field-of-view triangle to adjust the angle visually, or type the value directly. The triangle should encompass the road lanes you want to measure.
- Add any notes about the installation (useful for later reference)
- Save the configuration
The system stores this as the active site configuration period. Reports use the angle automatically to correct measured speeds. If you change the mounting angle later, create a new configuration period so historical reports remain accurate.
Step 6: generate reports #
After collecting data for a few days, generate professional reports from the dashboard.
- Open the dashboard at https://velocity.local
- Select your site and set the date range for the report period
- Click Generate Report
- Download the PDF
The report uses the cosine error angle from your site configuration (Step 5) to correct measured speeds automatically.
What the report includes:
- p50 (median): half of vehicles go faster than this
- p85 (traffic engineering standard): speed at which 85% of traffic travels at or below
- p98 (top 2%): threshold where the fastest regular drivers operate
- Speed distribution histograms and time-of-day charts
The dashboard also supports comparison reports for measuring the effect of traffic calming interventions: select two date ranges and the report shows side-by-side metrics with percentage changes.
Take your data to city hall #
Print the report. Bring it to the meeting. The data does the persuading.
Whether you are at a city council session, a town board hearing, or submitting written comments to a transport committee, the approach is the same: state the measured speed, explain what it means, and make clear that you intend to keep measuring.
What to bring #
- Printed PDF report: a physical document can be held, marked up, and filed into the public record. Screen shares cannot.
- Site photos: the street, the school, the park, the crossing. Data tells the story; photos make it concrete.
- Before-and-after comparison: if the council has already approved changes, bring the comparison report. Did p85 drop? Did it stay down?
What to say #
Lead with the metric traffic engineers already use:
“The 85th-percentile speed on [street name] is [X] mph. The posted limit is [Y] mph.”
The p85 is the standard threshold in US federal speed surveys and UK Department for Transport assessments. Using it means your data speaks the same language as a professional traffic study.
Then adapt to the situation:
- If the intervention worked: “After the [speed hump / signage / enforcement], p85 dropped from [X] to [Y] mph.”
- If it worked and then wore off: “p85 dropped initially. [N] months later it has returned to [W] mph.”
- If nothing has changed: “We have [N] weeks of continuous data. The p85 is [X] mph, consistently [Z] mph above the posted limit. This is the normal condition of this street.”
In January 2026, a velocity.report user took 6,000 transits from Clarendon Avenue (a 25 mph school zone on San Francisco’s high-injury network) to the SFMTA board. After repaving, median speed was up 8% to 33 mph and p85 up 5% to 39 mph. The ask: publish a before-and-after scoreboard for every project, and keep iterating until the speeds actually drop.
What to suggest #
Present the problem first, then name what might help:
- Speed humps or raised crossings: reduce p85 by 5–15 mph in most studies
- Kerb extensions: narrow the crossing distance
- Chicanes or lane narrowing: remove the straight-line path
- 20 mph zones: lower posted limits near schools and parks
- Radar speed signs: real-time driver feedback
- Targeted enforcement: your time-of-day data shows peak hours
You do not need to prescribe the answer. Present the evidence, name the options, and ask what the council can commit to and when.
Keep measuring #
Attend regularly. Each presentation enters the public record. Share the report with neighbours, the local press, and your elected representative.
- Baseline before any intervention
- Initial effect in the first weeks after a change
- Long-term compliance in the months that follow
- Regression: whether speeds drift back once the novelty wears off
A week of data shows patterns. A month is compelling. Three months across seasons is the kind of evidence that holds up in a budget discussion. The community that keeps measuring is the one that gets heard.
Network access and security #
Local network (recommended) #
The dashboard runs on HTTPS (port 443) and is accessible to any device on your local network. The Pi generates a self-signed TLS certificate on first boot; HTTP requests on port 80 redirect to HTTPS automatically. Your router firewall blocks external access by default, and no data leaves the network.
Best practices:
- Use SSH key authentication (configured during flashing)
- Use a strong Wi-Fi password (WPA3 if supported) if Wi-Fi is enabled
- Keep the OS updated:
sudo apt update && sudo apt upgrade
Remote access with Tailscale (recommended for clean HTTPS) #
Tailscale provides secure remote access without exposing your Pi to the public internet. Free for personal use. It is also the cleanest way to access the dashboard: Tailscale assigns your device a *.ts.net hostname with a valid Let’s Encrypt certificate, which means no browser warnings and no certificate exceptions required.
# Install Tailscale on your Pi
curl -fsSL https://tailscale.com/install.sh | sh
# Start Tailscale and authenticate
sudo tailscale up
Follow the authentication URL, install Tailscale on your phone or laptop, then access the dashboard at https://<hostname>.<tailnet>.ts.net — this URL has a valid certificate and works without any exception.
See the Tailscale documentation for details.
Shared and untrusted networks #
If the Pi is connected to a shared network (school, workplace, library, or multi-tenant building), other devices on that network can reach the dashboard. The dashboard has no user authentication: anyone who can reach port 443 can view your data.
Recommended isolation:
- VLAN: place the Pi on a dedicated VLAN or network segment so only your devices can reach it. Most managed switches and many consumer routers support VLAN configuration.
- Firewall rules: if VLAN isolation is not available, configure the router or switch to restrict access to the Pi’s IP address to specific client devices.
- Dedicated network: for permanent installations, a small dedicated switch or router (connected to the PoE injector) keeps the Pi off the shared network entirely.
If you cannot isolate the device, use Tailscale (above) and disable the Pi’s local network listener.
Public internet #
Do not expose this service to the public internet. The TLS certificate is self-signed and the dashboard has no user authentication. Use Tailscale for remote access.
Updating the software #
The image makes zero unsolicited network requests. Updates happen when you decide.
# Check whether a newer version is available
sudo velocity-ctl upgrade --check
# Download and apply the latest release
sudo velocity-ctl upgrade
# If something goes wrong, roll back
sudo velocity-ctl rollback
Updates replace the server binary and run any database migrations. Your data and configuration are preserved. For air-gapped deployments:
sudo velocity-ctl upgrade --binary /path/to/velocity-report
Backup and restore #
Back up before re-flashing. Your sensor data took weeks to collect; the software can be re-flashed in ten minutes.
Back up your data #
The database lives at /var/lib/velocity-report/sensor_data.db.
sudo velocity-ctl backup
This creates a timestamped copy in /var/lib/velocity-report/backups/. If you are about to re-flash the SD card, copy the backup off the Pi first:
# From your laptop
scp velocity@velocity.local:/var/lib/velocity-report/sensor_data.db \
~/sensor_data_backup_$(date +%Y%m%d).db
Re-flash and restore #
- Re-flash the SD card using Step 2
- Boot the Pi and verify the service runs (
velocity-status) - Stop the service:
velocity-stop - Copy the backup into place:
# From your laptop
scp ~/sensor_data_backup_20260326.db \
velocity@velocity.local:/tmp/sensor_data.db
# On the Pi
sudo cp /tmp/sensor_data.db /var/lib/velocity-report/sensor_data.db
sudo chown velocity:velocity /var/lib/velocity-report/sensor_data.db
- Start the service: it detects the existing database and runs any pending migrations automatically.
velocity-start
Troubleshooting #
| Problem | Fix |
|---|---|
| No sensor data | ls /dev/serial0 or ls /dev/velocity-radar to check the device |
| Service will not start | velocity-log to check logs |
| Dashboard will not load | velocity-status to verify the service |
| Certificate warning | Click Advanced → Proceed (Chrome/Edge) or Accept the Risk and Continue (Firefox/Safari) |
| Garbled or CSV output | Connect via screen /dev/serial0 19200 and send OJ then A! |
| Permission denied | sudo usermod -a -G dialout $USER then log out and back in |
USB-serial adapters get a /dev/velocity-radar symlink automatically.
- Full sensor documentation: OmniPreSense Support
- More help: TROUBLESHOOTING.md or Discord
Maintenance #
- Check the enclosure monthly for condensation
- Clean the sensor window seasonally
- Run
sudo velocity-ctl upgrade --checkperiodically
Reference #
What the image includes #
| Component | Location | Purpose |
|---|---|---|
| velocity-report server | /usr/local/bin/velocity-report |
Radar data collection and web dashboard |
| velocity-ctl | /usr/local/bin/velocity-ctl |
Device management and updates |
| PDF generator | /opt/velocity-report/tools/pdf-generator/ |
Professional traffic reports |
| Systemd service | /etc/systemd/system/velocity-report.service |
Starts automatically on boot |
| Nginx reverse proxy | /etc/nginx/sites-enabled/velocity |
TLS termination, HTTPS on port 443 |
| TLS certificates | /var/lib/velocity-report/tls/ |
Self-signed CA and server certificate |
The image also pre-configures serial port settings, UART overlays, sensor initialisation (JSON mode, units, magnitude reporting), and the service user.
Commands #
| Command | Purpose |
|---|---|
velocity-status |
systemctl status velocity-report.service |
velocity-log |
journalctl -u velocity-report.service -u nginx.service -f |
velocity-bounce |
sudo systemctl restart velocity-report.service |
velocity-stop |
sudo systemctl stop velocity-report.service |
velocity-start |
sudo systemctl start velocity-report.service |
velocity-report version |
Print the installed server version |
sudo velocity-ctl upgrade --check |
Check whether a newer release is available |
sudo velocity-ctl upgrade |
Download and apply the latest release |
sudo velocity-ctl rollback |
Restore the previous version |
sudo velocity-ctl backup |
Create a timestamped snapshot of binary and database |
Links #
- GitHub repository: github.com/banshee-data/velocity.report
- OmniPreSense support: omnipresense.com/support
- Community Discord: discord.gg/XXh6jXVFkt
- TROUBLESHOOTING.md
- CONTRIBUTING.md









