저희 부모님께서는 기계 가동 소음이 심한 공장에서 근무하고 계십니다. 그러다 보니 스마트폰 벨 소리나 진동을 전혀 인지하지 못해 급한 전화를 놓치는 경우가 종종 발생했습니다. 가끔 급하게 연락을 드려야 할 때도 거의 퇴근 시간쯤 연락을 해주실 때가 많았는데요. 좋은 방법이 없을까 고민하다가 이런 니즈에 맞춰 나온 상품이 없나 찾아보았지만 품질이 좋아 보이진 않는 중국산 벨 소리 증폭기 정도만 있었고 LED 같은 상품이 없을까 찾아보았지만 원격으로 ON/OFF 정도만 가능한 조명밖에 없어 전화 이벤트를 알리기엔 적합하지 않았습니다. 그러다 문득 예전에 장난감 삼아 사둔 라즈베리 파이 피코 W 가 떠올랐고 작지만 내장 LED까지 탑재하고 있어 어느 정도 시각적으로 알림이 가능하지 않을까 생각하다가 아무래도 블루투스를 연동하려면 앱을 개발해야 되니 시간이 좀 걸리겠구나 생각을 했었는데… 관련해서 정보를 찾아보니 안드로이드 자동화 앱인 Tasker를 활용하면 앱 개발 없이도 블루투스 연동이 가능했습니다. 그래서 AI한테 물어보며 직접 제작한 전화가 오면 LED가 강력하게 깜빡이는 알림 장치를 제작한 과정을 공유합니다.

<빛 반사를 위해 알루미늄 반사판을 배경으로 만들어둠>
준비물 및 핵심 원리
- 하드웨어: 라즈베리파이 피코 W(내장 LED 사용)
- 소프트웨어: Thonny 에디터, MicroPython, Tasker (Android 앱, 유료 7,500원)
- 작동 원리:
- 스마트폰에 전화가 오면 Tasker가 이벤트를 감지합니다.
- Tasker가 블루투스(BLE)를 통해 피코 W에 특정 신호를 전송합니다.(RING)
- 신호를 받은 피코 W가 즉시 LED를 점멸시켜 시각적 알림을 제공합니다.
- 마찬가지로 통화 중 상태가 되면 특정 신호를 전송하여 종료시킵니다.(STOP)
- 신호를 받은 피코 W가 LED를 끄고 다음 이벤트를 대기합니다.
여기서 포인트는 전화를 받지 못한 상태 부재중의 경우 3번에 계속 머무르며 전화를 걸 때까지 LED를 계속 점멸시킵니다.
단계별 제작 가이드
1단계: 라즈베리파이 피코 W 코딩 (MicroPython)
피코 W는 블루투스와 와이파이를 수신할 수 있는 무선칩을 내장하고 있으므로 MicroPython의
bluetooth 라이브러리를 사용했습니다.- 우선 thonny 에디터를 열어 라즈베리파이피코w와 연결 시킵니다.
- 아래 코드를 작성합니다.(GPT를 통해 코드를 작성시킴)
-
import bluetooth import machine import utime from micropython import const _IRQ_CENTRAL_CONNECT = const(1) _IRQ_CENTRAL_DISCONNECT = const(2) _IRQ_GATTS_WRITE = const(3) # ===== Nordic UART Service (NUS) UUIDs ===== NUS_UUID = bluetooth.UUID("6E400001-B5A3-F393-E0A9-E50E24DCCA9E") RX_UUID = bluetooth.UUID("6E400002-B5A3-F393-E0A9-E50E24DCCA9E") # Phone -> Pico (WRITE) TX_UUID = bluetooth.UUID("6E400003-B5A3-F393-E0A9-E50E24DCCA9E") # Pico -> Phone (NOTIFY) _FLAG_WRITE = bluetooth.FLAG_WRITE _FLAG_NOTIFY = bluetooth.FLAG_NOTIFY led = machine.Pin("LED", machine.Pin.OUT) # ===== 논블로킹 패턴 + 타임아웃 ===== PATTERN_RING = [(1, 120), (0, 120)] pattern = PATTERN_RING pattern_idx = 0 next_change_ms = utime.ticks_ms() blinking = False RING_TIMEOUT_MS = 0 # 부재중 알림 점멸 지속 시간(ms) 0인 경우 무한 ring_started_ms = None def stop_blink(): global blinking, ring_started_ms blinking = False ring_started_ms = None led.off() def start_blink(): global blinking, ring_started_ms, pattern_idx, next_change_ms blinking = True ring_started_ms = utime.ticks_ms() pattern_idx = 0 next_change_ms = utime.ticks_ms() def pattern_tick(): global pattern_idx, next_change_ms now = utime.ticks_ms() if blinking and RING_TIMEOUT_MS and ring_started_ms is not None: if utime.ticks_diff(now, ring_started_ms) >= RING_TIMEOUT_MS: print("RING timeout -> auto STOP") stop_blink() return if not blinking: return if utime.ticks_diff(now, next_change_ms) >= 0: on, dur = pattern[pattern_idx] led.value(on) pattern_idx = (pattern_idx + 1) % len(pattern) next_change_ms = utime.ticks_add(now, dur) class PicoNUS: def __init__(self): self.ble = bluetooth.BLE() self.ble.active(True) self.ble.irq(self._irq) # NUS: RX(write), TX(notify) ((self.rx_handle, self.tx_handle),) = self.ble.gatts_register_services(( (NUS_UUID, ( (RX_UUID, _FLAG_WRITE), (TX_UUID, _FLAG_NOTIFY), )), )) self._advertise() def _irq(self, event, data): if event == _IRQ_CENTRAL_CONNECT: print("BLE Connected") elif event == _IRQ_CENTRAL_DISCONNECT: print("BLE Disconnected") stop_blink() self._advertise() elif event == _IRQ_GATTS_WRITE: raw = self.ble.gatts_read(self.rx_handle) try: cmd = raw.decode().strip().upper() except: cmd = "" print("BLE Received:", cmd) if cmd in ("RING", "CALL", "START"): start_blink() elif cmd in ("STOP", "END", "IDLE", "OFF"): stop_blink() def _advertise(self): name = b"Pico-Call-LED" adv = b"\x02\x01\x06" + bytes((len(name) + 1, 0x09)) + name self.ble.gap_advertise(100_000, adv) print("Advertising as Pico-Call-LED (NUS)") PicoNUS() stop_blink() while True: pattern_tick() utime.sleep_ms(5) - main.py 이름으로 저장 후 종료
2단계: Tasker 앱 연동 설정
안드로이드의 Tasker 앱은 스마트폰의 다양한 이벤트를 트리거 시켜 강력한 자동화 기능을 제공합니다.
- Playstore 에서 Tasker를 다운 받습니다.(유료 7,500원)
- BLE Tasker plugin 이라는 Tasker의 플러그인 앱도 다운받습니다.
- 아래와 같이 Tasker 앱을 실행 시켜 설정해줍니다.
- 프로필 탭에서 +버튼을 누르기
- 만들기
- 이벤트
- 전화
- 전화벨 울림
- 새로운 작업 – RING
- + 버튼
- 플러그인
- BLE Tasker Plugin
- Disconnect Action(최초에 연결이 되어있는 경우 끊고 시작을 위함)
- 오류 후 작업 계속 체크
- + 버튼
- 플러그인
- BLE Tasker Plugin
- Connect Action
- 구성에서 연필 모양 편집 버튼
- MAC 주소 입력
- 아래 세 항목에 UUID 입력(코드의 6E400001-B5A3-F393-E0A9-E50E24DCCA9E 값)
- GATT Service UUID
- Characteristic for receive message event
- Characteristic for sending messages
- + 버튼
- 플러그인
- BLE Tasker Plugin
- Send Message Action
- 구성에서 연필 모양 편집 버튼
- Text 타입 선택
- Message to send 에 RING 작성
- + 버튼
- 다시 프로필로 돌아와서 + 추가 버튼
- 이벤트
- 전화
- 통화 중
- 새로운 작업 – STOP
- + 버튼
- 플러그인
- BLE Tasker Plugin
- Send Message Action
- 구성에서 연필 모양 편집 버튼
- Text 타입 선택
- Message to send 에 STOP 작성
- + 버튼
- 플러그인
- BLE Tasker Plugin
- Disconnect Action(최초에 연결이 되어있는 경우 끊고 시작을 위함)
- 오류 후 작업 계속 체크
- + 버튼
- 완료 후 피코W 와 연결되는지 테스트
실사용 후기
공장 한편 부모님 시야가 잘 닿는 곳에 LED 장치를 설치해 드렸습니다. 이제는 LED 불빛을 보고 전화를 잘 받으시고 혹시나 못받는 상황이 되어도 LED는 계속 들어오고 있으니 확인하시고 너무 늦지 않게 다시 전화를 해주시곤 하십니다.
직접 제작해 보니 기성품보다 저렴할 뿐만 아니라, 부모님의 환경에 딱 맞게 커스텀할 수 있다는 점이 큰 보람이었습니다. 다만, 내장 LED 의 경우 너무 작아 아쉬운 부분이 있는데 더 큰 LED가 필요하신분은 외부 LED를 추가로 달아서 보완은 가능할 것 같습니다.
거창한 시스템은 아니지만, 부모님의 불편함을 해소해 드릴 수 있어 보람 있는 프로젝트였습니다. 비슷한 고민을 하시는 분들이라면 라즈베리파이 피코 W를 활용해 보시길 적극 추천합니다. 궁금하신 점은 댓글로 남겨주세요!