Skip to content

alphaGithub/scanner

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

scanner

A poor-man's radar. A servo sweeps an ultrasonic sensor across 0–180°, an Arduino Nano measures distance at each angle and streams it to a Raspberry Pi over Bluetooth, and the Pi renders the returns as a live radar sweep on a small OLED.

        ░░░░░  90°  ░░░░░
      ░░       │       ░░          • = detected object
    ░         ╲│╱         ░        ─ = lit sweep (blue)
   0°━━━━━━━━━ ● ━━━━━━━━━180°      ● = sensor origin

Architecture

                         ┌───────────────────────────────────────────┐
   PHYSICAL              │  ARDUINO NANO          firmware: nano/      │
   ┌──────────┐  trig    │  ┌────────────┐    ┌──────────────────┐    │
   │ HC-SR04  │◀─────────┤  │ scanner.ino│    │ bluetooth.cpp/.h │    │
   │ ultrasonic├─────────▶│  │ read +     ├───▶│ btSendDistance() │    │
   └──────────┘  echo    │  │ median x5  │    └────────┬─────────┘    │
        ▲                │  └────────────┘             │              │
        │ rides on       └─────────────────────────────┼──────────────┘
        │ servo horn                                    │ JSON {"d": <cm>}
   ┌────┴─────┐                                         │ over Bluetooth (RFCOMM)
   │  SERVO   │                                         ▼
   │  GPIO18  │◀─move(angle)─┐         ┌───────────────────────────────┐
   └──────────┘              │         │  RASPBERRY PI    (Python)      │
                             │         │                                │
                     ┌───────┴──────┐  │  ┌──────────────────────────┐  │
                     │  ServoManger │◀─┼──┤     BluetoothManager      │  │
                     │  (servo.py)  │  │  │     (bluetooth.py)        │  │
                     └───────┬──────┘  │  │  reader thread →          │  │
                             │         │  │  latest_distance          │  │
                       move  │         │  └────────────┬─────────────┘  │
                             ▼         │               │ latest_distance│
                     ┌──────────────────────────────┐  │                │
                     │          ScanManger           │◀─┘                │
                     │          (scan.py)            │                   │
                     │  sweep thread • distances[181]│                   │
                     └───────────────┬───────────────┘                   │
                                     │ get_distances()                   │
                                     ▼                                    │
                     ┌──────────────────────────────┐                    │
                     │   DisplayManager / OLEDDisplay│   ┌────────────┐   │
                     │   (display.py)                ├──▶│ SH1106 OLED│   │
                     │   radar render                │   │  I²C 0x3C  │   │
                     └──────────────────────────────┘   └────────────┘   │
                          all wired by main.py                           │
                     └────────────────────────────────────────────────── │

Components

Component File Responsibility
Firmware nano/ Pulse HC-SR04, median-filter 5 samples, send {"d":<cm>} over HC-05.
BluetoothManager bluetooth.py RFCOMM client; background thread keeps the newest latest_distance.
ServoManger servo.py Angular servo on GPIO18; move(angle) for 0–180°.
ScanManger scan.py Background sweep; records distance per angle into distances[0..180].
OLEDDisplay display.py Renders the radar (rings + sweep) to the SH1106 panel.
DisplayManager display.py Thin adapter the display loop calls with the distance snapshot.
main.py main.py Wires the parts together and runs the OLED refresh loop.

Data flow

  HC-SR04        Nano            HC-05 ── BT ── Pi          ScanManger        OLED
    │             │                │           │               │              │
    │  echo       │                │           │               │              │
    ├────────────▶│ median(5)      │           │               │              │
    │             ├───────────────▶│  {"d":N}  │               │              │
    │             │                ├──────────▶│ latest_distance│              │
    │             │                │           │               │              │
    │             │            move(angle) ◀───┤ sweep thread   │              │
    │             │                │           ├──────────────▶│ distances[a]=N│
    │             │                │           │               │              │
    │             │                │           │  get_distances()              │
    │             │                │           │               ├─────────────▶│ draw
  1. Measure — the Nano pulses the HC-SR04, takes 5 samples, median-filters them, and emits a JSON line {"d": <cm>} (or -1 when out of range).
  2. ReceiveBluetoothManager reads that line over RFCOMM in a background thread and exposes the newest value as latest_distance.
  3. CorrelateScanManger's sweep thread moves the servo one angle at a time and stores the current latest_distance into distances[angle] (index = degree, -1 = out of range / not yet scanned).
  4. Render — the display loop in main.py polls get_distances() at REFRESH_RATE and hands the snapshot to OLEDDisplay, which draws the radar.

Display

The SH1106 is a 128×64 monochrome panel — "blue" simply means a lit pixel. OLEDDisplay draws a half-circle radar with the sensor at the bottom-centre:

   ┌──────────────────────────────────────┐
   │              · · · · · ·              │   · · · range rings (RINGS arcs,
   │          ·               ·            │         evenly spaced to MAX_DIST)
   │        ·    \  |  /  /      ·         │
   │      ·       \ | / /          ·       │   \ | / lit radial lines = sweep,
   │     ·         \|//              ·     │         drawn from origin out to
   │   ──────────────●──────────────────   │         each detected object
   │   180°          origin           0°   │
   └──────────────────────────────────────┘
  • Range ringsRINGS reference arcs at evenly spaced distances, the outermost at MAX_DIST cm.
  • Object returns — each in-range angle draws a lit radial line from the origin out to the object's distance; out-of-range angles stay black.
  • Orientation — 0° at the right edge, 90° straight up, 180° at the left (mirrors the servo's physical sweep).

Running

See SETUP.md for wiring, dependencies, and OS configuration. Then:

python3 main.py

The servo calibrates (0 → 90 → 180°), the sweep starts, and the radar appears on the OLED. Press Ctrl-C to stop.

Tuning

Knob Where Effect
sweepRate scan.py Angle steps per second (servo settle).
MAX_DIST display.py Distance (cm) mapped to the outer ring.
RINGS display.py Number of reference range rings.
REFRESH_RATE main.py OLED redraw rate (polls per second).

About

A HC-SR04 Scanner

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors