← ~/notes · 3 min read

한이음 공모전 — 몰카 탐지기 (ESP32 + 마그네틱 + WiFi 스캔)

공모전 주제로 몰카 탐지기를 만들었다. 마그네틱 + WiFi RF 두 채널로 가능성을 늘렸다.

목차
  1. 왜 두 채널인가
  2. 하드웨어 구성
  3. 펌웨어 — Arduino-ESP32
  4. 의심 SSID 패턴
  5. 백엔드 — FastAPI + PostgreSQL
  6. 팀 협업에서 부딪힌 것들
  7. 만들면서 알게 된 것들
  8. 한 줄 결론

대학 한이음 공모전 주제로 휴대용 몰카 탐지기를 팀으로 만들었다.

스마트폰 앱과 BLE 통신, ESP32 보드에 마그네틱 + WiFi 스캐너 두 종류 센서, FastAPI 서버 + PostgreSQL로 데이터 적재.


왜 두 채널인가

상용 몰카 탐지기는 보통 렌즈 반사(IR LED + 카메라)나 RF 스캔 둘 중 하나만 한다. 둘 다 한계가 있어서 우리는 두 채널 + 알파를 섞었다.

방식장점단점
렌즈 반사카메라 구분 없이 다 잡힘시야 안에 정확히 있어야, 사용자 숙련 필요
RF 스캔 (WiFi/Bluetooth)멀리서도 잡힘송신 안 하는 카메라 (저장형)는 못 잡음
마그네틱카메라 모듈의 모터/전자석 감지강자성체 일반에도 반응 (오탐 ↑)

세 채널을 종합하면 한 채널이 못 잡는 걸 다른 채널이 보완.


하드웨어 구성

ESP32-WROOM-32 보드
├─ HMC5883L 마그네틱 센서 (I2C)
├─ ESP32 내장 WiFi (RF 스캔용)
├─ BLE (스마트폰 통신)
└─ 진동 모터 + LED (탐지 알림)

ESP32는 WiFi + BLE가 한 칩에 다 들어있어서 그 자체가 RF 스캐너 + 컨트롤러. 가격은 5천원.

마그네틱 센서는 Adafruit HMC5883L. 3축 자기장 감지, μT 단위. I2C로 ESP32에 연결.


펌웨어 — Arduino-ESP32

#include <Wire.h>
#include <Adafruit_HMC5883_U.h>
#include <WiFi.h>
#include <BLEDevice.h>

Adafruit_HMC5883_Unified mag(12345);
const float BASELINE_uT = 50.0;
const float THRESHOLD_uT = 80.0;

void setup() {
  mag.begin();
  WiFi.mode(WIFI_STA);
  WiFi.disconnect();
  BLEDevice::init("HiddenCamDetector");
  // BLE characteristic 설정 (스마트폰과 통신)
}

void loop() {
  // 1) 마그네틱 측정
  sensors_event_t event;
  mag.getEvent(&event);
  float strength = sqrt(pow(event.magnetic.x, 2) +
                       pow(event.magnetic.y, 2) +
                       pow(event.magnetic.z, 2));
  bool magnetic_anomaly = (strength > THRESHOLD_uT);

  // 2) WiFi 스캔
  int n = WiFi.scanNetworks();
  std::vector<String> suspicious;
  for (int i = 0; i < n; i++) {
    String ssid = WiFi.SSID(i);
    int rssi = WiFi.RSSI(i);
    // 의심 SSID 패턴: "IPCAM", "HC*", "CamHi" 등
    if (matches_camera_pattern(ssid) && rssi > -60) {
      suspicious.push_back(ssid + " (" + String(rssi) + " dBm)");
    }
  }

  // 3) BLE로 결과 송신
  send_ble_alert(magnetic_anomaly, suspicious);

  delay(2000);
}

WiFi 스캔과 마그네틱을 1초씩 번갈아 한다.


의심 SSID 패턴

상용 몰카는 자주 다음 패턴의 AP를 띄움:

IPCAM-A1B2C3
HC-1234
CamHi_xxx
P2P_xxx
ANRAN_xxx
SUNLUXY_xxx

이런 패턴을 정규식으로 매칭. 100% 정답은 아니지만 false positive를 줄이는 데 효과적.


백엔드 — FastAPI + PostgreSQL

탐지 이벤트를 서버로 올려 시간/위치별 핫스팟 지도를 그릴 수 있게.

from fastapi import FastAPI
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker

app = FastAPI()

@app.post("/detection")
async def report_detection(data: DetectionEvent):
    db = SessionLocal()
    try:
        record = Detection(
            user_id=data.user_id,
            magnetic_uT=data.magnetic,
            wifi_ssids=data.wifi_ssids,
            location=data.gps,  # 스마트폰에서 GPS 첨부
            ts=datetime.utcnow()
        )
        db.add(record)
        db.commit()
    finally:
        db.close()
    return {"status": "ok"}

@app.get("/hotspots")
async def get_hotspots():
    # 최근 24시간, 위경도 그리드별 탐지 빈도
    db = SessionLocal()
    return db.query(Detection).filter(...).all()

스마트폰 앱이 ESP32에서 BLE로 받은 이벤트 + 자기 GPS를 합쳐서 서버로 POST.


팀 협업에서 부딪힌 것들

git 충돌. Arduino IDE 사용자 한 명, PlatformIO 사용자 두 명, VS Code 사용자 세 명. 각자 IDE가 만드는 메타파일이 충돌. .gitignore 정비에 이틀 쓰임.

# Arduino
*.cache/
.vs/
build/

# PlatformIO
.pio/
.pioenvs/
.piolibdeps/

# VS Code (개인 설정만 무시)
.vscode/launch.json
.vscode/c_cpp_properties.json

.vscode/settings.json은 팀 공유, 나머지 IDE 메타는 .gitignore.

보드 매니저 버전 통일. ESP32 보드 매니저 2.0.x vs 3.0.x에서 WiFi.scanNetworks() 동작이 미묘하게 다름. 팀 공통 버전 픽스 필수. platformio.ini에 명시:

[env:esp32dev]
platform = espressif32@6.4.0
framework = arduino
board = esp32dev

“서버”가 뭔지 처음 가르쳐야 했음. 팀원 두 명이 서버 개념이 처음. “Backend는 클라우드의 컴퓨터에서 돌고, FastAPI는 거기서 HTTP 요청을 받는 코드”부터 시작. 입문자에겐 너무 추상적이라 그림으로 그렸음.


만들면서 알게 된 것들

ESP32는 5천원짜리 만능 IoT 보드다. WiFi + BLE + I2C + ADC + DAC + 32bit MCU. 전공생이 첫 IoT 프로젝트로 쓰기 가장 좋음.

BLE characteristics 설계가 핵심. ESP32 ↔ 스마트폰 BLE 통신은 GATT characteristic 설계가 첫 단추. 너무 잘게 쪼개면 latency, 너무 크게 묶으면 유연성 손해. JSON 직렬화 후 한 characteristic에 쓰는 게 정석.

오탐 vs 미탐 트레이드오프. 마그네틱 임계값 80μT로 잡으면 모터/소형가전에 모두 반응. 100μT로 올리면 진짜 카메라 모듈만 반응하는데 위치를 정확히 갖다대야 함. 기본은 낮게 + 여러 차례 측정으로 보강.

팀 작업의 80%는 코딩이 아니라 의사소통이다. 환경 통일, 컨벤션, 그림 설명. 이게 깨지면 코드 한 줄도 못 나간다.


한 줄 결론

ESP32 + 멀티채널 센서 + BLE + FastAPI 백엔드는 공모전 규모 프로젝트의 기본기다. 비싼 도구 없이 5천원 + Python 서버로 충분히 실용적인 시스템이 나온다.

다음 단계: AI 모델로 SSID + 마그네틱 패턴 분류 → 오탐 줄이기. 학습 데이터 모으는 중.