Summary: 강의실 환경 데이터(온습도, 미세먼지)를 수집하는 프로젝트의 첫 단계로, Raspberry Pi 4에 Ubuntu Server 24.04 LTS 기반 C++ 개발 환경을 구성한다. DHT22를 커널 IIO 드라이버로 읽기 위한 디바이스 트리 설정, PMS7003용 UART 활성화, 그리고 Git/SSH 연동까지의 과정을 정리했다.
대상 환경
이 프로젝트는 Raspberry Pi 4에 DHT22(GPIO4)와 PMS7003(UART)을 연결한 구성이다. OS는 Ubuntu Server 24.04 LTS(arm64), 수집 프로그램은 C++20으로 작성하고 CMake로 빌드하며 PostgreSQL 접속에는 libpqxx를 사용한다.
Raspberry Pi OS 대신 Ubuntu Server를 선택하면서 달라지는 점은 단순한 배포판 교체 이상이었다. 뒤에서 다루겠지만, raspi-config 같은 대화형 설정 도구가 없어 부트 펌웨어 설정 파일을 직접 편집해야 하고, 센서를 읽는 방식도 사용자 공간 라이브러리 대신 커널 드라이버 기반을 택하게 된다.
패키지 설치
빌드 도구
sudo apt update
sudo apt install -y build-essential cmake pkg-config
build-essential이 g++ 컴파일러와 표준 라이브러리 개발 파일을 제공하고, cmake가 빌드를 구성한다. pkg-config는 이후 CMake가 libpqxx의 헤더·링크 경로를 자동으로 찾는 데 쓰인다.
PostgreSQL C++ 클라이언트
sudo apt install -y libpqxx-dev libpq-dev
libpqxx는 C++용 PostgreSQL 공식 클라이언트 라이브러리로, Ubuntu 24.04 기준 7.8.x가 설치된다. libpqxx 자체는 C 드라이버인 libpq 위에서 동작하므로 두 패키지를 함께 설치한다. 버전을 기록해 두는 이유는 libpqxx가 7.9를 기점으로 질의 API를 바꾸고 있어, 어떤 API를 쓸 수 있는지가 배포판 버전에 따라 갈리기 때문이다.
GPIO 확인 도구 (선택)
sudo apt install -y gpiod
gpioinfo, gpiodetect 같은 CLI로 GPIO 핀 상태를 확인할 수 있다. 필수는 아니지만 배선 문제를 소프트웨어 설정 문제와 분리해서 진단할 때 유용하다.
DHT22 커널 드라이버(IIO) 설정
이 단계가 환경 구축에서 가장 중요한 결정이었다. DHT22의 단선 프로토콜은 비트 하나를 마이크로초 단위 펄스 폭으로 구분하는데, 일반 사용자 공간 프로세스는 커널 스케줄링에 밀려 이 타이밍을 안정적으로 잡아내지 못한다. 사용자 공간 라이브러리로 GPIO를 직접 폴링하는 접근도 있지만, 커널의 dht11 드라이버(IIO 서브시스템)에 타이밍 처리를 맡기고 사용자 코드는 sysfs 파일 읽기만 수행하는 쪽이 구조적으로 유리하다.
설정은 /boot/firmware/config.txt 맨 아래에 한 줄을 추가하는 것으로 끝난다.
dtoverlay=dht11,gpiopin=4
오버레이 이름이 dht11이지만 DHT11/DHT22 공용 드라이버이며, 측정값의 스케일로 센서 종류를 자동 구분한다. 재부팅 후 /sys/bus/iio/devices/iio:device0/ 아래에 두 파일이 생긴다.
- in_temp_input — 온도, 밀리도(m°C) 단위 (예: 24300 = 24.3°C)
- in_humidityrelative_input — 상대습도, 밀리퍼센트 단위
주의할 점은 읽기 실패(EIO)가 간헐적으로 발생하는 것이 이 센서의 정상 동작 범위라는 것이다. 커널 드라이버를 쓴다고 해서 센서 응답 실패 자체가 사라지는 것은 아니므로, 수집 코드에는 재시도 로직이 여전히 필요하다.
UART(PMS7003) 설정
PMS7003은 UART로 데이터를 보내므로 하드웨어 UART를 활성화해야 한다. /boot/firmware/config.txt 맨 마지막에 추가한다.
[all]
dtoverlay=disable-bt
enable_uart=1
disable-bt가 필요한 이유는 Pi 4의 UART 배정 구조 때문이다. Pi 4에서 제대로 된 하드웨어 UART(PL011, ttyAMA0)는 기본적으로 블루투스 모듈에 배정되어 있고, disable-bt 없이 enable_uart=1만 켜면 GPIO14/15에는 미니 UART(/dev/ttyS0)가 잡힌다. 미니 UART는 보(baud) 클럭이 코어 클럭에 종속되어 클럭이 변동하면 통신이 흔들릴 수 있으므로, 블루투스를 내리고 PL011을 센서 전용으로 가져오는 쪽이 안전하다. 이렇게 하면 /dev/ttyAMA0 포트가 GPIO14/15에 생성된다.
여기서 놓치기 쉬운 부분이 시리얼 콘솔이다. 시리얼 포트로 OS 콘솔 로그인이 열려 있으면 센서 데이터와 콘솔 트래픽이 충돌한다. /boot/firmware/cmdline.txt에서 console=serial0,115200 항목을 제거하고, sudo systemctl disable serial-getty@ttyAMA0.service로 getty를 내린다.
포트 접근 권한도 필요하다. 실행 계정을 dialout 그룹에 추가한다.
sudo usermod -aG dialout $USER
이후 재부팅으로 설정을 반영한다.
Raspberry Pi OS와의 차이
| 항목 | Raspberry Pi OS | Ubuntu Server |
| 설정 도구 | raspi-config 메뉴 | config.txt 직접 편집 |
| 설정 파일 위치 | /boot/firmware/config.txt | /boot/firmware/config.txt (동일) |
| DHT22 읽기 | 사용자 공간 라이브러리 중심 생태계 | 커널 dht11 IIO 드라이버 |
| 개발 패키지 | 배포판 제공 GPIO 라이브러리 중심 | build-essential, cmake, libpqxx-dev |
정리하면서 흥미로웠던 점은, 설정 파일의 위치와 문법은 두 배포판이 동일하고 차이는 "그 파일을 누가 편집하느냐"뿐이라는 것이다. raspi-config는 결국 config.txt를 대신 편집해 주는 프론트엔드이므로, Ubuntu에서 직접 편집하는 방식이 오히려 어떤 설정이 어디에 반영되는지를 명확하게 보여준다.
git 설치 및 ssh 설정
수집 노드에서 저장소를 직접 받아 빌드하기 위해 Git과 SSH 키를 설정한다.
sudo apt install git -y
git config --global user.name "사용자 이름"
git config --global user.email "사용자 이메일"
git config --list # 등록 확인
SSH 키는 ed25519로 생성하고(기본 설정으로 진행), 공개 키를 GitHub에 등록한다.
ssh-keygen -t ed25519 -C "등록한 사용자 이메일"
cat ~/.ssh/id_ed25519.pub # 출력 전체를 복사
복사한 공개 키는 GitHub Settings → SSH and GPG keys → New SSH key에 붙여넣는다.

GitHub repositories 연동
저장소 페이지의 < > Code 버튼에서 SSH 탭의 URL을 복사한 뒤, 복제할 경로에서 clone한다.
git clone [복사한 URL]
저장소 이름과 동일한 폴더가 생성되고 전체 파일이 내려온다. 여기까지가 수집 노드 한 대를 프로젝트에 투입하기 위한 준비의 전부다.
결론
이 단계의 산출물은 "C++ 코드를 빌드할 수 있고, 두 센서가 커널 수준에서 인식되는 Ubuntu Server 노드"다. 핵심 판단은 두 가지였다. DHT22의 마이크로초 타이밍 문제를 사용자 공간에서 싸우지 않고 커널 드라이버에 위임한 것, 그리고 UART를 센서 전용으로 확보하기 위해 블루투스와 시리얼 콘솔을 명시적으로 내린 것. 다음 편에서는 이 두 센서가 실제로 어떤 프로토콜로 데이터를 보내는지를 다룬다.
'강의실 환경 모니터링' 카테고리의 다른 글
| DHT22 단선 프로토콜과 PMS7003 UART 프레임 구조 (0) | 2026.07.03 |
|---|