TinyGSM 라이브러리를 활용한 임베디드 장치 SMS 알림 및 상태 보고 시스템 구현

TinyGSM을 이용한 효율적인 SMS 통신 구축

TinyGSM은 자원이 제한된 임베디드 환경에서 GSM 모듈을 제어하기 위해 설계된 경량 라이브러리입니다. 복잡한 AT 커맨드를 직접 다루지 않고도 추상화된 API를 통해 메시지 전송, 데이터 통신, 장치 제어를 수행할 수 있습니다. 특히 네트워크 연결이 불안정한 환경에서도 SMS를 활용한 비상 알림이나 상태 보고 시스템을 구축하는 데 매우 효과적입니다.

시스템 구성 및 라이브러리 초기화

TinyGSM 라이브러리는 SIM800, SIM7000, A6/A7 등 다양한 모듈을 지원합니다. 가장 먼저 사용할 하드웨어 사양에 맞춰 모뎀 모델을 정의하고 통신을 위한 시리얼 포트를 설정해야 합니다.

#define TINY_GSM_MODEM_SIM800  // 사용하는 모듈 모델 정의
#include <TinyGsmClient.h>

// 하드웨어 시리얼 포트 설정 (모뎀 연결용)
#define gsmSerial Serial1

// 모뎀 객체 생성
TinyGsm gsmModem(gsmSerial);

void setup() {
  gsmSerial.begin(9600); // 모뎀 통신 속도 설정
  delay(3000);
  
  if (!gsmModem.restart()) {
    Serial.println("모뎀 초기화 실패");
    return;
  }
  Serial.println("모뎀 준비 완료");
}

기본 SMS 전송 기능 구현

메시지 전송은 sendSMS 함수를 사용하며, 국가 코드를 포함한 수신 번호와 내용을 전달합니다. 성공 여부를 불리언 값으로 반환하므로 로직 처리가 간편합니다.

void transmitStatusMessage(const String& phoneNum, const String& content) {
  Serial.print("메시지 전송 중: ");
  Serial.println(content);
  
  bool isSuccessful = gsmModem.sendSMS(phoneNum, content);
  
  if (isSuccessful) {
    Serial.println("전송 성공");
  } else {
    Serial.println("전송 실패");
  }
}

실전 사례: 센서 임계치 기반 알림 시스템

임베디드 장치가 특정 센서 값을 모니터링하다가 위험 수치에 도달했을 때 관리자에게 SMS를 보내는 시나리오를 구현해 보겠습니다.

const float LIMIT_VAL = 45.0; // 온도 상한선
const String ADMIN_PHONE = "+821012345678";

void monitorAndReport(float sensorData) {
  if (sensorData > LIMIT_VAL) {
    String alertTxt = "[경고] 장치 온도가 임계치를 초과했습니다! 현재: " + String(sensorData) + "C";
    
    // 알림 전송 시도
    if (gsmModem.sendSMS(ADMIN_PHONE, alertTxt)) {
      Serial.println("관리자에게 비상 문자 발송 완료");
    } else {
      Serial.println("비상 문자 발송 실패");
    }
  }
}

void loop() {
  float currentTemp = readAnalogSensor(); // 센서 읽기 함수 (가정)
  monitorAndReport(currentTemp);
  delay(60000); // 1분 간격 체크
}

신뢰성 향상을 위한 고급 최적화

실제 환경에서는 네트워크 장애나 모듈 응답 지연이 발생할 수 있습니다. 이를 보완하기 위한 몇 가지 최적화 기법이 필요합니다.

1. 재시도 로직 적용

전송 실패 시 즉시 포기하지 않고 일정 횟수만큼 재시도하여 성공 확률을 높입니다.

bool sendSmsReliably(const String& target, const String& msg, int retryCount = 3) {
  for (int i = 0; i < retryCount; i++) {
    if (gsmModem.sendSMS(target, msg)) return true;
    Serial.println("재전송 시도 중...");
    delay(2000);
  }
  return false;
}

2. 수신 메시지 확인 및 원격 제어

장치가 메시지를 보내는 것뿐만 아니라, 특정 명령어가 담긴 SMS를 수신하여 원격으로 재부팅하거나 설정을 변경할 수 있습니다.

void processIncomingSms() {
  String senderNum = "";
  String messageContent = "";
  
  if (gsmModem.getSMS(&senderNum, &messageContent)) {
    Serial.print("발신번호: ");
    Serial.println(senderNum);
    Serial.print("내용: ");
    Serial.println(messageContent);
    
    if (messageContent.equalsIgnoreCase("REBOOT")) {
      Serial.println("장치 재시작 명령 수신");
      // 재부팅 로직 수행
    }
    
    // 저장 공간 확보를 위해 읽은 메시지 삭제
    gsmModem.deleteSMS(1);
  }
}

주요 문제점 및 해결 방법

  • 전원 부족: GSM 모듈은 메시지 전송 시 순간적으로 높은 전류(최대 2A)를 소비합니다. 안정적인 별도 전원 공급 장치를 사용하는 것이 중요합니다.
  • 신호 세기 저하: 안테나 위치가 적절하지 않으면 전송이 빈번하게 실패합니다. gsmModem.getSignalQuality() 함수를 사용하여 RSSI 값을 체크하고 위치를 조정하십시오.
  • 한글 깨짐 현상: 기본 sendSMS는 ASCII 기반인 경우가 많습니다. 한글 전송이 필요한 경우 UTF-8 스트림 기능을 지원하는 모드인지 확인하고 sendSMS_UTF8 관련 함수를 사용해야 합니다.

SMS 기능의 활용 가치

TinyGSM을 통한 SMS 구현은 인터넷 연결이 불가능한 오지나 이동 중인 차량 내 장치에서 강력한 통신 수단이 됩니다. MQTT나 HTTP와 같은 TCP 기반 통신이 실패했을 때를 대비한 훌륭한 백업 채널로도 활용할 수 있으며, 구조가 단순하여 배터리 소모를 최소화해야 하는 환경에 최적화되어 있습니다.

태그: TinyGSM Arduino SMS SIM800 GSM

8월 6일 00:55에 게시됨