Flash an AirGradient ONE from the Command Line

Michael Lynch

커맨드라인에서 AirGradient ONE 플래시하기

원문은 Michael Lynch님이 에 게재했습니다. 이 블로그 구독하기

집안 공기질을 측정하려고 AirGradient ONE 실내 공기질 모니터를 두 대 구매했다. AirGradient 기기는 오픈소스라서 AirGradient의 독자적인 클라우드 대시보드로 데이터를 보내는 대신 직접 커스텀 펌웨어를 올려 데이터를 로컬에서 수집할 수 있다.

사무실에 둔 AirGradient ONE 공기질 모니터로 CO2와 오염 물질을 측정하고 있다.

기존 펌웨어 플래싱 문서는 번거로운 GUI 프로그램인 Arduino IDE를 사용하도록 되어 있다:

기존 AirGradient ONE 플래싱 가이드는 번거로운 GUI 프로그램인 Arduino IDE에 의존한다.

커맨드라인으로 AirGradient 기기를 플래시하는 방법을 찾을 수 없어 직접 알아내는 데만 몇 시간이 걸렸다. 그래서 아래에 과정을 정리해 뒀다.

여담: AirGradient가 왜 그렇게 인기 있는지 모르겠다

포럼에서 AirGradient 이야기가 나올 때마다 다들 제품에 열광하는 분위기다. 내가 써 본 AirGradient ONE은 평범한 수준이었다. 소프트웨어는 버그가 매우 많고 문서도 부실하다. 하지만 완제품 공기질 모니터를 오픈소스로 판매하는 곳은 AirGradient밖에 찾지 못해서 결국 두 번째 제품을 또 샀다.

수년간 AirGradient는 AirGradient ONE에 소프트웨어를 올리는 방법을 따로 공개조차 하지 않았다. 나는 아래 블로그 글들을 보고 방법을 익혔다:

올해 들어서야 AirGradient가 공식 플래싱 가이드를 공개했지만, 여전히 잘 눈에 띄지 않는 곳에 있다.

환경

이 과정은 Debian 13.0에서 테스트했지만, Debian/Ubuntu 계열 시스템이라면 대부분 동일하게 동작할 것이다.

패키지 설치

먼저 필요한 기본 패키지를 설치한다:

sudo apt update && \
  sudo apt install -y \
    git \
    curl \
    python3 \
    python3-serial

arduino-cli 설치

다음으로 Arduino CLI 도구를 설치한다:

ARDUINO_CLI_VERSION='1.2.2'
ARDUINO_BIN_DIR="${HOME}/.local/arduino-cli"

mkdir -p "${ARDUINO_BIN_DIR}" && \
  curl -fsSL https://raw.githubusercontent.com/arduino/arduino-cli/master/install.sh \
  | BINDIR="${ARDUINO_BIN_DIR}" sh -s "${ARDUINO_CLI_VERSION}"
export PATH="${PATH}:${ARDUINO_BIN_DIR}"

arduino-cli의 버전 문자열을 출력해 설치가 제대로 됐는지 확인한다:

$ arduino-cli version
arduino-cli  Version: 1.2.2 Commit: c11b9dd5 Date: 2025-04-22T13:51:01Z

ESP32 라이브러리 다운로드

AirGradient ONE은 ESP32 Arduino 라이브러리에 의존한다. 이 글을 쓰는 시점 기준으로 AirGradient는 아직 Arduino 3.x 버전과 호환되지 않으므로, 최신 안정 버전인 2.x를 사용해야 한다.

ARDUINO_ESP32_VERSION='2.0.17'

arduino-cli config init \
  --additional-urls https://espressif.github.io/arduino-esp32/package_esp32_index.json && \
  arduino-cli core install "esp32:esp32@${ARDUINO_ESP32_VERSION}"

내 기기의 경로 찾기

다음으로 AirGradient ONE의 장치 경로가 필요하다. 장치 경로를 찾는 가장 간단한 방법은 다음과 같다:

  1. dmesg --follow 실행
  2. AirGradient ONE을 USB로 시스템에 연결
  3. dmesg 출력에서 장치 경로가 나타나는지 확인

내 시스템에서는 이렇게 표시된다:

$ sudo dmesg --follow
[517021.978880] usb 1-4: New USB device found, idVendor=303a, idProduct=1001, bcdDevice= 1.01
[517021.978884] usb 1-4: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[517021.978894] usb 1-4: Product: USB JTAG/serial debug unit
[517021.978896] usb 1-4: Manufacturer: Espressif
[517021.978898] usb 1-4: SerialNumber: D8:3B:DA:1A:EE:C4
[517022.017678] cdc_acm 1-4:1.0: ttyACM0: USB ACM device
                                 ^^^^^^^
                                 Path name

이 출력을 보면 내 시스템에서 AirGradient ONE 경로는 /dev/ttyACM0이다:

AIRGRADIENT_PATH='/dev/ttyACM0'

장치 경로에 쓰기 권한 부여

다음으로 AirGradient 장치 경로에 쓸 수 있도록 설정한다:

sudo chmod a+rw "${AIRGRADIENT_PATH}"

이제 AirGradient 경로의 권한은 이렇게 표시되어야 한다:

$ ls -l "${AIRGRADIENT_PATH}"
crw-rw-rw- 1 root dialout 166, 0 Aug 10 10:34 /dev/ttyACM0
 ^^^^^^^^

그리고 경로에 쓸 수 있도록 내 계정을 dialout 그룹에 추가한다:

sudo adduser "$(whoami)" dialout

AirGradient 소스 가져오기

다음으로 AirGradient 공장 플래싱 페이지에서 최신 프로덕션 릴리스를 확인한다.

# Current production release, as of this writing.
AIRGRADIENT_RELEASE='3.3.8'

경고: AirGradient 웹사이트에 나온 최신 버전은 AirGradient GitHub 저장소의 최신 릴리스 태그와 일치하지 않는다. 3.3.9를 테스트했을 때 두 기기 모두 CO2와 온도 측정에 실패해서, 3.3.9가 알려진 버그가 있는 릴리스인지 잘 모르겠다.

버전 번호를 확인했으니 AirGradient GitHub 저장소에서 소스 코드를 가져온다:

git clone --recurse-submodules \
  --branch "${AIRGRADIENT_RELEASE}" \
  --depth 1 \
  https://github.com/airgradienthq/arduino.git \
  ~/airgradient-one

AirGradient ONE 기기에 펌웨어 플래시하기

이제 기기에 소프트웨어를 플래시할 차례다:

cd ~/airgradient-one && \
  arduino-cli compile \
    --verbose \
    --fqbn esp32:esp32:esp32c3:CDCOnBoot=cdc,PartitionScheme=min_spiffs,DebugLevel=info \
    --library . \
    --port "${AIRGRADIENT_PATH}" \
    --verify \
    --upload \
    examples/OneOpenAir/OneOpenAir.ino

참고: AirGradient ONE 기기의 영구 데이터(즉, 설정 데이터를 포함한 하드 리셋)를 지우려면 --fqbn 플래그 끝에 ,EraseFlash=all을 추가하면 된다.

플래싱에 성공하면 기기가 재부팅되고 과정 마지막에 다음과 같은 출력이 나타난다:

Wrote 1753792 bytes (967231 compressed) at 0x00010000 in 14.7 seconds (effective 952.3 kbit/s)...
Hash of data verified.

Leaving...
Hard resetting via RTS pin...

선택 사항: 시리얼 로그 출력 보기

AirGradient가 컴퓨터에 연결된 상태에서 arduino-cli monitor 명령으로 시리얼 포트를 통해 로그 출력을 볼 수 있다:

$ arduino-cli monitor --port "${AIRGRADIENT_PATH}"
Using default monitor configuration for board: esp32:esp32:heltec_wifi_kit_32_V3
Monitor port settings:
  baudrate=9600
  bits=8
  dtr=on
  parity=none
  rts=on
  stop_bits=1

Connecting to /dev/ttyACM0. Press CTRL-C to exit.
[1] Standard Particle PM 2.5 = 7.00 ug/m3
[1] Particle Count 0.3 = 1298.5
[1] Particle Count 0.5 = 383.5
[1] Particle Count 1.0 = 39.7
[1] Particle Count 2.5 = 2.0
[1] Particle Count 5.0 = 2.0
[1] Particle Count 10 = 0.0

대안: Nix flake

Nix를 즐겨 쓴다면 Nix 방식으로 하고 싶을 것이다. 위 과정을 모두 자동화하는 Nix flake를 만들어 뒀다:

저장소를 플래시하고 싶을 때는 다음 명령만 실행하면 된다:

nix run .#flash

시리얼 출력을 보고 싶을 때는 다음 명령을 실행한다:

nix run .#monitor

내 Nix flake가 다른 시스템에서 얼마나 잘 동작할지는 장담할 수 없으니, 본인 시스템에 맞게 약간 손봐야 할 수도 있다.

결론

이 가이드가 AirGradient ONE 기기를 플래시하고 원하는 대로 펌웨어를 커스텀하는 데 도움이 되길 바란다.

이 글은 muse-spark-1.2-contributor 모델을 사용해 번역했습니다.

댓글