[회고] 스마트홈 IoT 프로젝트

hyoin·2025년 12월 7일
post-thumbnail

구현한 공동현관의 일부 기능 - 인가된 태그 인식:
구현한 공동현관의 일부 기능 - 인가된 태그 인식

스마트홈 IoT 프로젝트 회고: 일주일의 소중한 경험들

1. 들어가며

드디어 스마트홈 IoT 프로젝트가 끝났다! 기간은 고작 일주일이었지만, 정말 많은 것을 배우고 느낀 프로젝트였다.

이 프로젝트에서 나는 공동현관 기능을 맡았는데, 스테퍼 모터(28BYJ-48)로 슬라이딩 도어를 제어하고, RFID(MFRC522)로 태그를 인식하고, 초음파 센서로 장애물을 감지하는 부분을 담당했다. 그리고 Flask로 서버를 구축해서 PyQt6로 만든 대시보드와 HTTP 통신을 하는 부분도 구현했다.

아두이노(C++), Python(Flask, PyQt6), 그리고 RDS를 사용했고, 이 과정에서 예상하지 못한 문제들도 많았지만, 그만큼 배운 것도 정말 많았다. 그 이야기들을 나눠보려고 한다.


2. 설계

프로토콜 설계

여러 개의 아두이노 보드가 Flask 서버로 시리얼 메시지를 계속 보내야 했다. 그런데 어떤 아두이노가 보낸 메시지인지, 그리고 그 메시지가 무엇을 의미하는지 구분할 방법이 필요했다. 특히 아두이노 보드 간의 통신도 필요했기에 중앙 제어 서버를 두는 걸 선택했다.

이 때문에 팀에서 함께 통신 프로토콜을 설계했는데, 메시지 형식의 기본 구조는 이렇게 했다:

[DEVICE_ID],[DATA_TYPE],[VALUE]

예를 들어 MAIN,RFID_VALID,12A34B56 이런 식이다. 각 아두이노의 ID, 어떤 센서의 데이터인지, 그리고 실제 값을 구분하는 것이다.

사실 실무에서는 바이트 개수를 기준으로 파싱한다고 하는데, 시간이 부족해서 빠르게 진행하기 위해 콤마를 구분자로 사용했다. 이건 나중에 개선하고 싶은 부분이다.

아키텍처 설계: 초반

처음 계획은 이렇게 단순했다:

  • 관제탑 역할을 하는 Python 프로세스 1개: 모든 아두이노로부터 시리얼 데이터를 받아서 처리
  • 대시보드 Python 프로세스 1개: 사용자 인터페이스 담당

"두 프로세스가 같은 포트(시리얼 포트)를 공유할 수 있지 않을까?" 라는 뇌피셜로 시작했다(사실 타이트한 일정이라 제발 됐으면 좋겠다 라는 생각이었다)
하지만 당연하게도... 한 프로세스가 포트를 점유하면 다른 프로세스는 접근할 수 없었다. 😅


3. 기능 구현

공동현관 모듈 제어

공동현관이 제대로 작동하려면 세 가지 센서가 조화롭게 움직여야 했다.

RFID 태그 인식:

  • 인가된 태그를 인식하면 → 도어 오픈
  • 비인가된 태그를 인식하면 → 아무것도 안 함
  • 태그 UID를 대시보드에 표시

스테퍼 모터로 도어 제어:

  • RFID가 유효한 태그를 감지하면 28BYJ-48 모터가 작동해서 슬라이딩 도어를 열어준다.

초음파 센서로 안전성 확보:

  • 문이 열려있을 때 초음파 센서가 장애물을 감지하면 → 문이 닫혀서는 안 된다!
  • 이건 사람이나 물체가 끼일 수 있으니까 중요한 부분이었다.

다만 아쉬웠던 점이 하나 있다. 지금은 태그의 UID를 그대로 대시보드에 표시하는데, 실제 서비스라면 사용자 이름이나 라벨이 나와야 할 텐데 시간 관계상 못했다. 다음엔 데이터베이스에서 태그 ID를 조회해서 실제 사용자 정보를 표시해야겠다.

대시보드와 Flask 서버: HTTP 통신

처음엔 관제탑 역할의 Python 프로세스가 시리얼 통신만 담당했다. 하지만 포트 점유 문제가 터지면서 급하게 리팩토링이 필요했다.

해결책: Flask 서버로 전환

  • 관제탑 Python 프로세스 → Flask 서버로 리팩토링
  • 아두이노에서 보내는 시리얼 데이터를 수신하고 처리
  • 대시보드는 HTTP 요청으로 Flask 서버와 통신

대시보드에서는 이제 이렇게 통신한다:

GET/POST http://localhost:5000/door/control

Flask 서버가 요청을 받으면 아두이노로 명령을 내려준다.

대시보드 상태 표시:

  • "공동현관 열림" / "공동현관 닫힘" 같은 상태를 실시간으로 표시
  • 수동으로 열기 버튼도 있어서 대시보드에서 직접 제어 가능

모듈 간 제어: 공동현관과 엘리베이터

흥미로운 부분이었다. 공동현관이 열림 상태가 되면, 자동으로 엘리베이터도 호출되도록 했다. 이건 Flask 서버를 통해서 다른 아두이노 보드에 명령을 전달하는 식으로 구현했다.


4. 예상 밖의 문제들 (그리고 배운 점)

아두이노 보드가 터지다

프로젝트 초반, 나는 큰 실수를 했다. 아두이노 보드를 항상 노트북에 연결시켜 뒀다.

컴퓨터를 끄면 USB에 연결된 기기들도 전기가 끊긴다고 생각했다... 근데 그게 아니었다. 컴퓨터를 끄고 나서도 아두이노 보드는 계속 전원을 받고 있었다. 스테퍼 모터 드라이버, RFID 모듈까지 달아둔 상태로 말이다.

며칠 동안 계속 전원을 받던 보드의 온도가 올라가거나 하는 신호는 없었다. 그래서 과부하가 있다는 걸 전혀 몰랐다.

통합 테스트 전: 발표 전, 대시보드까지 합쳐서 통합 테스트를 하려고 보드를 켰는데... 먹통이 되어버렸다. 컴퓨터에서도 인식을 못 했다.

아두이노 내부 회로가 손상된 거다. 여러 개의 전자 부품들이 계속 전력을 소비하다 보니 보드 자체가 과부하를 견디지 못한 거다. (거의 일주일 동안 끊임없이 돌렸으니 그럴만도 하다...)

다행히: 팀 친구들이 여분의 아두이노 보드를 빌려줘서 발표는 무사히 진행할 수 있었다.

포트 점유 문제와 급발진 리팩토링

앞서 언급했던 포트 점유 문제로 돌아와서.

처음엔 "관제탑 Python 프로세스"와 "대시보드 Python 프로세스" 두 개를 동시에 실행하려고 했다. 근데 시리얼 포트는 한 번에 하나의 프로세스만 점유할 수 있다.

문제를 깨닫던 순간:

serial port is busy

이 에러 메시지를 본 순간 내 얼굴은 파랗게 질렸다. 🫠

해결 과정:
1. 급하게 관제탑 역할을 Flask 서버로 리팩토링
2. 대시보드는 Flask 서버와 HTTP 통신으로 변경
3. 아두이노는 Flask 서버에만 시리얼 연결

운이 좋았던 이유:
처음부터 프로토콜을 잘 정의해뒀기 때문에, 아두이노 쪽 코드는 수정할 필요가 거의 없었다. 대시보드에서 시리얼로 처리하던 것들을 그대로 서버에 보내면 됐다.

이 경험에서 설계가 얼마나 중요한지를 뼈저리게 깨달았다. 미리 잘 정의해둔 프로토콜 덕분에, 예상 밖의 문제가 터졌을 때도 빠르게 대응할 수 있었다.


5. 아쉬웠던 점과 앞으로 개선할 것

1. 태그 UID 대신 사용자 정보 표시하기

지금: 12A34B56 같은 UID가 그대로 표시됨
개선: 데이터베이스에서 태그 ID를 조회해서 김철수 같은 실제 사용자명 표시

RDS를 이미 연결했으니 구현이 어렵지 않을 텐데, 시간이 부족했다. 다음 버전에서 꼭 개선해야겠다.

2. 바이트 기반 파싱으로 업그레이드하기

지금: 콤마를 구분자로 파싱 (DEVICE_ID,DATA_TYPE,VALUE)
실무: 바이트 개수를 기준으로 고정된 형식으로 파싱

바이트 기반 파싱이 더 안정적이고 효율적이라고 들었다. 이것도 다음 프로젝트의 과제로 삼아야겠다.

3. 아두이노 보드 관리 (쉬는 시간 주기)

이건... 기술적 개선이라기보단 휴먼 에러 예방이다.

  • 프로젝트 기간 중에도 규칙적으로 보드를 쉬게 하기
  • 필요 없을 땐 항상 USB를 뽑기
  • 보드의 온도나 상태를 수시로 확인하기 (사실 뜨거워졌는데 내가 인식을 못했던 것일 수도 있으니...)

4. 아키텍처 설계의 중요성 다시 한 번

이 프로젝트에서 배운 가장 중요한 교훈은 이거다:

"좋은 설계가 있으면, 예상 밖의 문제가 터져도 빨리 해결할 수 있다."

프로토콜을 미리 잘 정의했기 때문에, 아키텍처를 완전히 바꿔야 할 상황이 와도 빠르게 대응할 수 있었다. 반대로 설계를 대충 했다면, 발표 전날의 그 난리는 정말 감당할 수 없었을 거다.


6. 마치며

일주일이라는 짧은 기간이었지만, 정말 밀도 있는 시간이었다.

이 프로젝트에서 배운 가장 큰 것:

  • 기술만큼 설계가 중요하다.
  • 예상 밖의 문제는 항상 생긴다.
  • 하지만 좋은 기초가 있으면 빠르게 극복할 수 있다.

다음 IoT 프로젝트를 할 땐:
1. 더 견고한 설계로 시작하기
2. 하드웨어 소중히 다루기 (특히 보드...)
3. 충분한 테스트 시간 확보하기
4. 배운 교훈들을 적용해서 더 완성도 있는 프로젝트 만들기

이 경험이 앞으로의 IoT 프로젝트에 큰 밑거름이 될 거라고 믿는다. 그리고 그때는 아두이노 보드도 편안하게 쉬게 해줄 거다.

프로젝트 소스코드는 여기!

profile
배워야 할 게 많은 개발자... 하지만 공부를 포기하지 않지!!

0개의 댓글