스마트 홈 기기 시장은 지난 몇 년간 폭발적으로 성장했습니다. 2015년 약 30만 대에 불과했던 스마트 홈 기기는 2020년 거의 12억 대에 달했으며, 2021년에는 15억 대까지 늘어날 것으로 전망됩니다.
2021년까지 가구당 평균 8.7개의 스마트 기기를 보유하게 될 것이라는 예측을 고려하면, 여러분의 집에도 이미 몇 개의 스마트 기기가 있을 가능성이 높습니다.
개발자라면 이 분야에서 약간의 이점이 있습니다. 바로 자신만의 스마트 홈 기기를 직접 만들 수 있기 때문입니다.
빠르게 발전한 것은 기기만이 아닙니다. 기기에 사용되는 개발 보드 역시 점점 더 상용화되고 누구나 쉽게 구할 수 있게 되었습니다.
이 글에서는 라즈베리 파이(Raspberry Pi)와 LCD 화면, 그리고 몇 줄의 코드만으로 실외 또는 특정 지역의 날씨를 모니터링하는 방법을 알아보겠습니다.

DIY(Do It Yourself) 프로젝트인 만큼, 먼저 필요한 준비물부터 확인해야 합니다.
준비물
- 라즈베리 파이 3(또는 상위 모델)
- LCD 화면
- 연결용 점퍼 와이어
- 가변 저항(포텐셔미터, 선택 사항)
- 브레드보드(선택 사항)
만드는 방법
필요한 것이 모두 갖춰졌다면 바로 시작해 볼까요? 단계별로 하나씩 살펴보겠습니다.
1단계 - 기본 설정
첫 번째 단계는 기본 환경 설정과 모든 부품의 정상 동작 확인입니다.
이 데모에서는 날씨 데이터 제공자로 ClimaCell Weather API를 사용합니다. 대기질 지표를 포함해 다양한 지표를 제공하기 때문입니다.
API를 사용하려면 해당 플랫폼에서 계정을 개설하고 API 키를 발급받아야 합니다. 이 키로 요청에 서명하게 됩니다.

계정은 무료로 개설할 수 있으며, 시간당 100회의 API 호출 한도가 제공되어 이 프로젝트에는 충분합니다.
API 키를 받았다면 하드웨어 설정으로 넘어가 LCD 화면을 라즈베리 파이에 연결합니다. 배선 작업 시에는 반드시 라즈베리 파이의 전원을 꺼 두세요.
라즈베리 파이 3의 핀 배열은 아래 이미지에서 확인할 수 있습니다.

LCD와 개발 보드 간의 배선 연결은 다음과 같습니다.

이렇게 하드웨어를 연결하면 LCD 화면이 최대 밝기와 최대 명암비로 설정됩니다. 밝기는 큰 문제가 되지 않지만, 명암비는 화면의 문자를 읽을 수 없게 만들 수 있습니다.
그래서 최소한 하나의 가변 저항(포텐셔미터)을 추가해 명암비를 조절할 수 있도록 해야 합니다.

이 시점에서 라즈베리 파이 전원을 켜면 LCD 화면이 켜지는 것을 확인할 수 있습니다. 가변 저항을 돌려 명암비를 조절해 보세요.
2단계 - 프로젝트 설정
프로그래밍 언어는 Node.js를 사용합니다. 라즈베리 파이에 Node.js가 아직 설치되어 있지 않다면 공식 설치 가이드를 따라 간단히 설치할 수 있습니다.
새 폴더에서 npm init -y 명령어로 새 npm 패키지를 생성한 뒤, npm install lcd node-fetch 명령어로 필요한 두 가지 의존성을 설치합니다.
lcd: LCD 화면과 통신하는 데 사용node-fetch: ClimaCell API로 HTTP 요청을 보내는 데 사용
날씨 데이터 제공자와 통신하려면 API 키가 필요하다고 했습니다. 비밀 API 키를 메인 코드에 직접 넣을 수도 있지만, config.json 파일을 만들어 키와 기타 설정값을 함께 관리하는 것이 더 깔끔합니다.
config.json
{ "cc_key": "<your_ClimaCell_API_key>"}마지막으로 프로젝트의 메인 파일을 만들고 앞서 준비한 내용들을 포함시킵니다.
// * Dependencies
const Lcd = require("lcd");
const fs = require("fs");
const fetch = require("node-fetch");
// * Globals
const { cc_key } = JSON.parse(fs.readFileSync("./config.json"));
3단계 - LCD
lcd 모듈을 사용하면 화면에 글자를 쓰는 일은 아주 간단합니다. 이 라이브러리는 기기와의 통신 과정 위에 추상화 계층을 제공하므로, 각 명령어를 일일이 세세히 다룰 필요가 없습니다.
LCD 화면 관련 전체 코드는 다음과 같습니다.

먼저 새 lcd 객체를 생성하고 사용한 핀 번호를 인수로 전달합니다.
cols와 rows 키는 LCD 디스플레이의 열과 행 수를 나타냅니다. 이 예제에서는 16x2를 사용했습니다. LCD가 8열 1행이라면 16과 2를 해당 값으로 바꾸면 됩니다.
디스플레이에 내용을 출력하려면 다음 두 메서드를 순차적으로 사용해야 합니다.
lcd.setCursor()- 쓰기 시작할 위치 지정lcd.print()- 실제 텍스트 출력
동시에 async/await 키워드를 활용할 수 있도록 이 두 함수를 프로미스로 감쌌습니다.
이제 이 함수를 사용해 디스플레이에 원하는 내용을 출력할 수 있습니다. writeToLcd(0,0,'Hello World')를 실행하면 첫 번째 행 첫 번째 열부터 Hello World 메시지가 출력됩니다.
4단계 - 날씨 데이터
다음 단계는 날씨 데이터를 가져와 디스플레이에 출력하는 것입니다.
ClimaCell은 다양한 날씨 정보뿐 아니라 대기질, 꽃가루, 산불 등의 정보도 제공합니다. 데이터가 매우 방대하지만, LCD 화면은 16열 2행, 즉 32자밖에 표시할 수 없다는 점을 유의하세요.
더 많은 종류의 데이터를 표시하고 싶은데 이 한계가 부담스럽다면 스크롤 효과를 활용할 수 있습니다.

이 데모에서는 간단하게 다음 데이터를 LCD 화면에 출력하겠습니다.
- 현재 시각(시, 분, 초)
- 온도
- 강수 강도

ClimaCell에서 특정 위치의 데이터를 가져오려면 해당 위치의 지리적 좌표, 즉 위도와 경도를 전송해야 합니다.
도시의 좌표는 latlong.net 같은 무료 도구로 쉽게 찾을 수 있으며, 찾은 좌표를 API 키와 함께 config.json 파일에 저장하거나 코드에 직접 작성하면 됩니다.
이 시점에서 API 호출이 반환하는 데이터 형식은 다음과 같습니다.
{
lat: 45.658,
lon: 25.6012,
temp: { value: 17.56, units: 'C' },
precipitation: { value: 0.3478, units: 'mm/hr' },
observation_time: { value: '2020-06-22T16:30:22.941Z' }
}이 객체를 구조 분해(destructuring)하여 temp와 precipitation 값을 추출한 뒤, 첫 번째 행과 두 번째 행에 각각 출력하면 됩니다.
5단계 - 마무리
이제 남은 일은 스크립트 로직을 작성하고, 새 데이터가 도착하면 LCD 화면을 업데이트하는 것입니다.

날씨 데이터는 5분마다 업데이트됩니다. 하지만 ClimaCell이 부과하는 시간당 100회 API 호출 제한 범위 안이라면, 더 나아가 매분 날씨 데이터를 갱신할 수도 있습니다.
현재 시각 표시에는 두 가지 옵션이 있습니다.
observation_time속성을 사용해 데이터를 받은 시각을 표시하거나,- 실제 시계처럼 현재 시간을 표시할 수 있습니다.
여기서는 두 번째 방법을 선택했지만, 원하는 방식대로 구현하시면 됩니다.
시간을 오른쪽 상단에 출력하려면 텍스트가 화면에 딱 맞도록 시작 열을 먼저 계산해야 합니다. 이를 위해 '전체 열 수'에서 '표시할 텍스트 길이'를 빼는 간단한 공식을 사용할 수 있습니다.
시간은 8자이고 열이 총 16개이므로, 8번째 열부터 출력을 시작하면 됩니다.
LCD 설정은 비동기적으로 동작하므로, 라이브러리가 제공하는 lcd.on() 메서드를 사용해 LCD가 초기화되어 사용할 준비가 되었는지 확인해야 합니다.
임베디드 시스템의 또 다른 모범 사례는 사용한 리소스를 닫고 해제하는 것입니다. 그래서 프로그램이 중지될 때 SIGINT 이벤트를 사용해 LCD 화면을 안전하게 종료합니다. 이 외에도 다음과 같은 이벤트를 활용할 수 있습니다.
SIGUSR1및SIGUSR2- nodemon 재시작 같은 "kill pid" 상황 처리uncaughtException- 처리되지 않은 예외 처리
6단계 - 영원히 실행하기
스크립트가 완성되었으니 이제 프로그램을 실행할 수 있습니다. 다만 마무리하기 전에 한 가지만 더 처리해야 합니다.
지금쯤 SSH나 HDMI 케이블과 모니터로 라즈베리 파이에 연결해 사용하고 있을 겁니다. 어떤 방식이든 터미널을 닫으면 프로그램이 함께 중지됩니다.
또한 기기 전원을 끄고 잠시 후 또는 즉시 다시 켜도 스크립트가 자동으로 시작되지 않아 매번 수동으로 실행해야 합니다.
이 문제는 pm2 같은 프로세스 관리자를 사용하면 간단히 해결됩니다.
순서는 다음과 같습니다.
sudo npm install pm2 -g- pm2 설치sudo pm2 startup- pm2 관리자용 시작 스크립트 생성pm2 start index.js- 애플리케이션 시작pm2 save- 서버 재시작 후에도 프로세스 목록 유지
이제 보드를 재부팅하면 기기가 준비되는 즉시 스크립트가 자동으로 시작됩니다.
결론
여기서부터는 새 기기를 원하는 대로 커스터마이징할 수 있습니다. 이 날씨 데이터가 유용하다면(또는 ClimaCell의 대기 오염, 꽃가루, 산불 지수, 도로 위험 등 다른 데이터가 필요하다면) 라즈베리 파이와 LCD 디스플레이를 넣을 맞춤형 케이스를 만들어 보세요. 배터리를 추가한 뒤 집 안 어디든 놓아두면 손쉽게 나만의 날씨 스테이션이 완성됩니다.
라즈베리 파이는 개인용 컴퓨터와 같아서, Arduino 같은 마이크로컨트롤러에서 할 수 있는 것보다 훨씬 다양한 작업을 수행할 수 있습니다. 덕분에 집에 있는 다른 스마트 기기들과 결합하기도 훨씬 쉽습니다.