[아두이노] 슈퍼커패시터 UPS + Raspberry Pi + Arduino 자동 복구 시스템 아이디어



시스템 개요

이 시스템의 목적은 다음 두 가지입니다.

  1. 정전 시 Raspberry Pi를 안전하게 종료하여 데이터 손상을 방지

  2. 전원 복구 후 Raspberry Pi가 자동으로 다시 부팅되지 않는 경우 Arduino가 강제로 깨워서 자동 복구

즉, 단순 UPS가 아니라 안전 종료(Safe Shutdown) + 자동 복구(Self-Healing) 기능을 구현하는 구조입니다.


각 장치 역할

Raspberry Pi (데이터 보호 담당)

  • UPS 전원 상태 감시

  • 정전 발생 감지

  • 디스크 캐시 저장(sync)

  • 안전 종료 수행

  • 종료 직전 Arduino에게 종료 사실 전달


Arduino (전원 관리자 담당)

  • 전원 복구 시 가장 먼저 동작

  • Raspberry Pi의 생존 여부 확인

  • Raspberry Pi가 응답하지 않으면 RUN 핀 리셋

  • 무인 자동 복구 수행


하드웨어 연결

Raspberry Pi

GPIO용도
GPIO18UPS 전원 감지 입력
GPIO20Heartbeat 출력

Arduino

용도
D2Raspberry Pi Heartbeat 입력
D3Raspberry Pi RUN 리셋 제어

동작 시나리오

정상 상태

외부 전원이 정상 공급 중

외부 전원 ON
      ↓
UPS 정상
      ↓
Raspberry Pi 실행
      ↓
GPIO20 = HIGH
      ↓
Arduino 대기

정전 발생

UPS 감지 핀이 LOW로 떨어짐

정전 발생
      ↓
GPIO18 FALLING 감지
      ↓
sync 실행
      ↓
3초 대기
      ↓
sync 재실행
      ↓
Heartbeat LOW
      ↓
Shutdown 수행

전원 복구

전원 복구
      ↓
Arduino 부팅
      ↓
5초 대기
      ↓
Heartbeat 확인

Raspberry Pi 정상 부팅

Heartbeat = HIGH
      ↓
정상 상태
      ↓
아무 작업 안 함

Raspberry Pi 식물인간 상태

Heartbeat = LOW
      ↓
RUN 핀 리셋
      ↓
Raspberry Pi 강제 재부팅

Raspberry Pi 파이썬 코드

#!/usr/bin/env python3

import RPi.GPIO as GPIO
import time
import os

POWER_SENSE_PIN = 18
HEARTBEAT_PIN = 20

GPIO.setmode(GPIO.BCM)

GPIO.setup(
    POWER_SENSE_PIN,
    GPIO.IN,
    pull_up_down=GPIO.PUD_DOWN
)

GPIO.setup(
    HEARTBEAT_PIN,
    GPIO.OUT
)

# 살아있음을 알림
GPIO.output(
    HEARTBEAT_PIN,
    GPIO.HIGH
)

# 전원 차단 감지
GPIO.add_event_detect(
    POWER_SENSE_PIN,
    GPIO.FALLING,
    bouncetime=500
)

print("UPS Monitor Started")

try:

    while True:

        if GPIO.event_detected(
            POWER_SENSE_PIN
        ):

            print("Power Failure Detected")

            # 데이터 저장
            os.system("sync")

            print("Saving Data 1/2")

            time.sleep(3)

            os.system("sync")

            print("Saving Data 2/2")

            print("Shutdown in 5 seconds")

            for sec in range(5, 0, -1):

                print(sec)

                time.sleep(1)

            # 종료 직전 Heartbeat 제거
            GPIO.output(
                HEARTBEAT_PIN,
                GPIO.LOW
            )

            time.sleep(0.5)

            os.system(
                "sudo shutdown -h now"
            )

            break

        time.sleep(0.5)

except KeyboardInterrupt:

    GPIO.cleanup()

Arduino 코드

const int RPI_HEARTBEAT_PIN = 2;
const int RPI_RESET_PIN = 3;

void setup()
{
    Serial.begin(115200);

    pinMode(
        RPI_HEARTBEAT_PIN,
        INPUT_PULLDOWN
    );

    // 평상시 High-Z 상태 유지
    pinMode(
        RPI_RESET_PIN,
        INPUT
    );

    Serial.println(
        "Arduino Power Manager Start"
    );

    // Raspberry Pi 부팅 시간 확보
    delay(5000);

    if (
        digitalRead(
            RPI_HEARTBEAT_PIN
        ) == LOW
    )
    {
        Serial.println(
            "Raspberry Pi Not Responding"
        );

        // RUN 핀 리셋
        pinMode(
            RPI_RESET_PIN,
            OUTPUT
        );

        digitalWrite(
            RPI_RESET_PIN,
            LOW
        );

        delay(500);

        // 선 떼기
        pinMode(
            RPI_RESET_PIN,
            INPUT
        );

        Serial.println(
            "Reset Complete"
        );
    }
    else
    {
        Serial.println(
            "Raspberry Pi Alive"
        );
    }
}

void loop()
{
    // 센서 수집
    // 환경 제어
    // 데이터 처리

    delay(1000);
}

Raspberry Pi 서비스 등록

서비스 파일 생성

파일:

/etc/systemd/system/ups-monitor.service

내용:

[Unit]
Description=UPS Power Monitor
After=multi-user.target

[Service]
Type=simple
ExecStart=/usr/bin/python3 /home/pi/ups_monitor.py
Restart=always
User=pi

[Install]
WantedBy=multi-user.target

서비스 등록

sudo systemctl daemon-reload

sudo systemctl enable ups-monitor.service

sudo systemctl start ups-monitor.service

상태 확인

sudo systemctl status ups-monitor.service

권장 하드웨어 구성

RUN 핀 직접 연결 금지

Arduino 출력 핀을 Raspberry Pi RUN 핀에 직접 연결하는 것보다 아래 방식이 안전합니다.

Arduino D3
      │
      ▼
NPN 트랜지스터
      │
      ▼
Raspberry Pi RUN

또는

Arduino D3
      │
      ▼
옵토커플러
      │
      ▼
Raspberry Pi RUN

Heartbeat 개선 버전 (권장)

현재 구조

HIGH = 살아있음
LOW  = 죽음

개선 구조

1초마다 GPIO20 토글

HIGH
LOW
HIGH
LOW
HIGH
LOW
...

Arduino는 5초 동안 변화가 있는지 확인

변화 있음
 → 정상

변화 없음
 → 이상 상태
 → RUN 리셋

이 방식은 GPIO가 우연히 HIGH에 고착되는 경우까지 검출할 수 있어 더 신뢰성이 높습니다.


최종 동작 흐름

정상 운전
    ↓
정전 발생
    ↓
UPS 감지
    ↓
Raspberry Pi
    ↓
sync
    ↓
3초 대기
    ↓
sync
    ↓
Heartbeat OFF
    ↓
Shutdown

=========================

전원 복구
    ↓
Arduino 기동
    ↓
5초 대기
    ↓
Heartbeat 확인

HIGH
 └─ 정상

LOW
 └─ RUN 리셋
        ↓
 Raspberry Pi 재부팅

이 구조는 스마트팜 제어기, 환경 모니터링 장치, PLC 게이트웨이, 데이터 로거처럼 무인으로 장기간 운영되는 시스템에서 사용할 수 있는 비교적 견고한 안전 종료 및 자동 복구 아키텍처입니다.

댓글

이 블로그의 인기 게시물

공압 속도 제어: 미터인 vs 미터아웃

[투자] ETF 투자 가이드 : 카테고리별 ETF 선택 전략

NPN, PNP 트랜지스터 차이점

제너 다이오드에 저항을 연결하는 이유

[아두이노] 가변저항(Potential Divider)과 전압분배(Voltage Divider)

[PLC] 센서 NPN, PNP 출력 타입별 결선방법 (OMRON E2E-X 시리즈 3선식 배선)

[주식] 한국거래소(KRX) 데이터 API 입문 가이드

전력(kW) 계산하기 (직류, 교류 단상, 교류 삼상)

PLC 출력 형태

3선 결선식 센서의 타입 PNP, NPN