Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/AngelAmoSanchez/TFG-RaspberryPi-BLE/llms.txt

Use this file to discover all available pages before exploring further.

The default zone thresholds (NEAR_THRESHOLD=-60, MEDIUM_THRESHOLD=-75) are conservative starting points. Signal strength varies significantly depending on the Raspberry Pi’s Bluetooth adapter, nearby walls and furniture, and the type of devices being detected. The calibrate_ble.py script performs a live scan in your target environment and recommends thresholds derived from the actual signal distribution.

What the tool does

calibrate_ble.py runs a 20-second passive BLE scan using BleakScanner with the same callback mechanism as the main agent. During the scan it prints each detected advertisement in real time so you can observe how RSSI changes as you move a device closer or further away. After the scan completes it prints:
  1. Per-device statistics — average, maximum, and minimum RSSI, detection count, and dwell time.
  2. Percentile-based threshold recommendations — the top 30 % of signal strengths becomes near_threshold, the top 70 % becomes medium_threshold.
  3. A signal distribution histogram across five distance bands.

Running the calibration tool

The tool must run with the same BLE capabilities as the main agent. Activate the virtual environment and run it directly:
cd /home/pi/TFG-RaspberryPi-BLE/raspberry-pi
source venv/bin/activate
python3 calibrate_ble.py
Run the tool from inside the virtual environment. The venv/bin/python3 binary has the cap_net_raw,cap_net_admin capabilities set by install.sh. Calling the system Python will fail with a Bluetooth permission error.
The script does not accept command-line arguments. The scan duration is fixed at 20 seconds.

Real-time output during the scan

As devices are detected the tool prints one line per advertisement:
======================================================================
  CALIBRACIÓN BLE - Sistema de Conteo de Personas
======================================================================
Escaneando dispositivos BLE durante 20 segundos...
INSTRUCCIONES:
  1. Acerca/aleja tu dispositivo (Mi Band, móvil, etc.)
  2. Observa cómo cambia el RSSI según la distancia
  3. Anota los valores que ves a diferentes distancias

[A1:B2:C3...] iPhone 13                  | RSSI:  -48 dBm | MUY CERCA (<1m)
[D4:E5:F6...] Apple Watch                | RSSI:  -55 dBm | CERCA (1-2m)
[A1:B2:C3...] iPhone 13                  | RSSI:  -61 dBm | MEDIO (2-4m)
[D4:E5:F6...] Apple Watch                | RSSI:  -73 dBm | LEJOS (4-8m)
The distance classification used during the scan is finer-grained than the three-zone model used by the main agent:
RSSI rangeLabel
≥ −50 dBmMUY CERCA (< 1 m)
−60 to −51 dBmCERCA (1–2 m)
−70 to −61 dBmMEDIO (2–4 m)
−80 to −71 dBmLEJOS (4–8 m)
< −80 dBmMUY LEJOS (> 8 m)

Summary output after the scan

After the 20-second window the tool prints a full summary:
======================================================================
  RESUMEN DE CALIBRACIÓN BLE
======================================================================

  Duración: 20.1s
  Detecciones totales: 147
  Dispositivos únicos: 6

══════════════ DISPOSITIVOS DETECTADOS (ordenados por señal) ══════════════

──────────────────────────────────────────────────────────────────────────
== iPhone 13 (A1:B2:C3:D4:E5:F1) ==
   RSSI Promedio:   -54.3 dBm
   RSSI Máximo:      -48 dBm  (más cerca detectado)
   RSSI Mínimo:      -63 dBm  (más lejos detectado)
   Detecciones:       42
   Permanencia:     19.8s
──────────────────────────────────────────────────────────────────────────
== Xiaomi Band (A1:B2:C3:D4:E5:F4) ==
   RSSI Promedio:   -76.1 dBm
   RSSI Máximo:      -71 dBm
   RSSI Mínimo:      -83 dBm
   Detecciones:       31
   Permanencia:     18.2s
Each device is sorted by its maximum observed RSSI (strongest signal first). At the bottom of the output the tool calculates thresholds from all collected RSSI values using two percentiles:
======================================================================
  UMBRALES RECOMENDADOS PARA config.py
======================================================================

Basado en 147 mediciones:

@dataclass
class ZoneConfig:
    """Configuración de umbrales de zonas"""
    near_threshold: int = -55    # Top 30% señales (cercanas)
    medium_threshold: int = -72  # Top 70% señales (medias)
    # far = resto (peor que -72)
The 30th-percentile value (top 30 % of strongest readings) becomes near_threshold. The 70th-percentile value becomes medium_threshold. Signals weaker than medium_threshold are classified as FAR.
# From calibrate_ble.py
all_rssi.sort(reverse=True)

p30 = all_rssi[int(len(all_rssi) * 0.3)]  # Top 30% = near
p70 = all_rssi[int(len(all_rssi) * 0.7)]  # Top 70% = medium

Signal distribution histogram

The final section shows how many readings fell in each distance band, with a bar chart:
══════════════ DISTRIBUCIÓN DE SEÑALES ══════════════

  MUY CERCA (<1m)      12 ( 8.2%) ████
  CERCA (1-2m)         31 (21.1%) ██████████
  MEDIO (2-4m)         58 (39.5%) ███████████████████
  LEJOS (4-8m)         35 (23.8%) ███████████
  MUY LEJOS (>8m)      11 ( 7.5%) ███
Use this histogram to judge whether the recommended thresholds make sense for your space. If the majority of readings fall in MUY LEJOS you may have too few devices nearby during calibration — repeat the scan with more representative traffic. Open .env and update the two threshold variables with the values printed by the tool:
NEAR_THRESHOLD=-55
MEDIUM_THRESHOLD=-72
Then restart the agent for the change to take effect:
sudo systemctl restart ble-scanner

Calibration tips

RSSI distributions shift when many devices are present simultaneously. Run calibration during a period that reflects your typical operating conditions — not in an empty room if the space is usually busy.
Different hardware (phones, smartwatches, fitness trackers) broadcasts at different power levels. Include at least one device of each type you expect to count.
A single 20-second run may not capture enough variation. Run the tool two or three times at different times of day and average the recommended thresholds.
A wall between the Raspberry Pi and a device can drop RSSI by 10–20 dBm. Calibrate with the Pi in its final mounted position and with the room in its normal state.
If the summary shows zero unique devices, check that:
  • The Bluetooth service is running: sudo systemctl status bluetooth
  • At least one BLE-capable device (smartwatch, fitness tracker, wireless earphones) is nearby and actively broadcasting
  • Smartphone Bluetooth is enabled — note that many phones do not emit BLE advertisements unless an app is actively using Bluetooth
After applying new thresholds, watch the live agent output for one full scan cycle to confirm the zone distribution looks reasonable for the devices present.
sudo journalctl -u ble-scanner -f

Build docs developers (and LLMs) love