Computer >> 컴퓨터 >  >> 시스템 >> Mac

Node.js와 라즈베리 파이, LCD 화면으로 직접 만드는 날씨 모니터링 기기

스마트 홈 기기 시장은 지난 몇 년간 폭발적으로 성장했습니다. 2015년 약 30만 대에 불과했던 스마트 홈 기기는 2020년 거의 12억 대에 달했으며, 2021년에는 15억 대까지 늘어날 것으로 전망됩니다.

2021년까지 가구당 평균 8.7개의 스마트 기기를 보유하게 될 것이라는 예측을 고려하면, 여러분의 집에도 이미 몇 개의 스마트 기기가 있을 가능성이 높습니다.

개발자라면 이 분야에서 약간의 이점이 있습니다. 바로 자신만의 스마트 홈 기기를 직접 만들 수 있기 때문입니다.

빠르게 발전한 것은 기기만이 아닙니다. 기기에 사용되는 개발 보드 역시 점점 더 상용화되고 누구나 쉽게 구할 수 있게 되었습니다.

이 글에서는 라즈베리 파이(Raspberry Pi)와 LCD 화면, 그리고 몇 줄의 코드만으로 실외 또는 특정 지역의 날씨를 모니터링하는 방법을 알아보겠습니다.

Node.js와 라즈베리 파이, LCD 화면으로 직접 만드는 날씨 모니터링 기기

DIY(Do It Yourself) 프로젝트인 만큼, 먼저 필요한 준비물부터 확인해야 합니다.

준비물

  • 라즈베리 파이 3(또는 상위 모델)
  • LCD 화면
  • 연결용 점퍼 와이어
  • 가변 저항(포텐셔미터, 선택 사항)
  • 브레드보드(선택 사항)

만드는 방법

필요한 것이 모두 갖춰졌다면 바로 시작해 볼까요? 단계별로 하나씩 살펴보겠습니다.

1단계 - 기본 설정

첫 번째 단계는 기본 환경 설정과 모든 부품의 정상 동작 확인입니다.

이 데모에서는 날씨 데이터 제공자로 ClimaCell Weather API를 사용합니다. 대기질 지표를 포함해 다양한 지표를 제공하기 때문입니다.

API를 사용하려면 해당 플랫폼에서 계정을 개설하고 API 키를 발급받아야 합니다. 이 키로 요청에 서명하게 됩니다.

Node.js와 라즈베리 파이, LCD 화면으로 직접 만드는 날씨 모니터링 기기
ClimaCell API 호출 한도

계정은 무료로 개설할 수 있으며, 시간당 100회의 API 호출 한도가 제공되어 이 프로젝트에는 충분합니다.

API 키를 받았다면 하드웨어 설정으로 넘어가 LCD 화면을 라즈베리 파이에 연결합니다. 배선 작업 시에는 반드시 라즈베리 파이의 전원을 꺼 두세요.

라즈베리 파이 3의 핀 배열은 아래 이미지에서 확인할 수 있습니다.

Node.js와 라즈베리 파이, LCD 화면으로 직접 만드는 날씨 모니터링 기기
라즈베리 파이 3 핀 배열

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

Node.js와 라즈베리 파이, LCD 화면으로 직접 만드는 날씨 모니터링 기기
라즈베리 파이와 LCD 간 연결

이렇게 하드웨어를 연결하면 LCD 화면이 최대 밝기와 최대 명암비로 설정됩니다. 밝기는 큰 문제가 되지 않지만, 명암비는 화면의 문자를 읽을 수 없게 만들 수 있습니다.

그래서 최소한 하나의 가변 저항(포텐셔미터)을 추가해 명암비를 조절할 수 있도록 해야 합니다.

Node.js와 라즈베리 파이, 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 화면 관련 전체 코드는 다음과 같습니다.

Node.js와 라즈베리 파이, LCD 화면으로 직접 만드는 날씨 모니터링 기기
RAW

먼저 새 lcd 객체를 생성하고 사용한 핀 번호를 인수로 전달합니다.

colsrows 키는 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자밖에 표시할 수 없다는 점을 유의하세요.

더 많은 종류의 데이터를 표시하고 싶은데 이 한계가 부담스럽다면 스크롤 효과를 활용할 수 있습니다.

Node.js와 라즈베리 파이, LCD 화면으로 직접 만드는 날씨 모니터링 기기

이 데모에서는 간단하게 다음 데이터를 LCD 화면에 출력하겠습니다.

  • 현재 시각(시, 분, 초)
  • 온도
  • 강수 강도
Node.js와 라즈베리 파이, LCD 화면으로 직접 만드는 날씨 모니터링 기기
RAW

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)하여 tempprecipitation 값을 추출한 뒤, 첫 번째 행과 두 번째 행에 각각 출력하면 됩니다.

5단계 - 마무리

이제 남은 일은 스크립트 로직을 작성하고, 새 데이터가 도착하면 LCD 화면을 업데이트하는 것입니다.

Node.js와 라즈베리 파이, LCD 화면으로 직접 만드는 날씨 모니터링 기기
RAW

날씨 데이터는 5분마다 업데이트됩니다. 하지만 ClimaCell이 부과하는 시간당 100회 API 호출 제한 범위 안이라면, 더 나아가 매분 날씨 데이터를 갱신할 수도 있습니다.

현재 시각 표시에는 두 가지 옵션이 있습니다.

  • observation_time 속성을 사용해 데이터를 받은 시각을 표시하거나,
  • 실제 시계처럼 현재 시간을 표시할 수 있습니다.

여기서는 두 번째 방법을 선택했지만, 원하는 방식대로 구현하시면 됩니다.

시간을 오른쪽 상단에 출력하려면 텍스트가 화면에 딱 맞도록 시작 열을 먼저 계산해야 합니다. 이를 위해 '전체 열 수'에서 '표시할 텍스트 길이'를 빼는 간단한 공식을 사용할 수 있습니다.

시간은 8자이고 열이 총 16개이므로, 8번째 열부터 출력을 시작하면 됩니다.

LCD 설정은 비동기적으로 동작하므로, 라이브러리가 제공하는 lcd.on() 메서드를 사용해 LCD가 초기화되어 사용할 준비가 되었는지 확인해야 합니다.

임베디드 시스템의 또 다른 모범 사례는 사용한 리소스를 닫고 해제하는 것입니다. 그래서 프로그램이 중지될 때 SIGINT 이벤트를 사용해 LCD 화면을 안전하게 종료합니다. 이 외에도 다음과 같은 이벤트를 활용할 수 있습니다.

  • SIGUSR1SIGUSR2 - nodemon 재시작 같은 "kill pid" 상황 처리
  • uncaughtException - 처리되지 않은 예외 처리

6단계 - 영원히 실행하기

스크립트가 완성되었으니 이제 프로그램을 실행할 수 있습니다. 다만 마무리하기 전에 한 가지만 더 처리해야 합니다.

지금쯤 SSH나 HDMI 케이블과 모니터로 라즈베리 파이에 연결해 사용하고 있을 겁니다. 어떤 방식이든 터미널을 닫으면 프로그램이 함께 중지됩니다.

또한 기기 전원을 끄고 잠시 후 또는 즉시 다시 켜도 스크립트가 자동으로 시작되지 않아 매번 수동으로 실행해야 합니다.

이 문제는 pm2 같은 프로세스 관리자를 사용하면 간단히 해결됩니다.

순서는 다음과 같습니다.

  1. sudo npm install pm2 -g - pm2 설치
  2. sudo pm2 startup - pm2 관리자용 시작 스크립트 생성
  3. pm2 start index.js - 애플리케이션 시작
  4. pm2 save - 서버 재시작 후에도 프로세스 목록 유지

이제 보드를 재부팅하면 기기가 준비되는 즉시 스크립트가 자동으로 시작됩니다.

결론

여기서부터는 새 기기를 원하는 대로 커스터마이징할 수 있습니다. 이 날씨 데이터가 유용하다면(또는 ClimaCell의 대기 오염, 꽃가루, 산불 지수, 도로 위험 등 다른 데이터가 필요하다면) 라즈베리 파이와 LCD 디스플레이를 넣을 맞춤형 케이스를 만들어 보세요. 배터리를 추가한 뒤 집 안 어디든 놓아두면 손쉽게 나만의 날씨 스테이션이 완성됩니다.

라즈베리 파이는 개인용 컴퓨터와 같아서, Arduino 같은 마이크로컨트롤러에서 할 수 있는 것보다 훨씬 다양한 작업을 수행할 수 있습니다. 덕분에 집에 있는 다른 스마트 기기들과 결합하기도 훨씬 쉽습니다.