산업 제조
산업용 사물 인터넷 | 산업자재 | 장비 유지 보수 및 수리 | 산업 프로그래밍 |
home  MfgRobots >> 산업 제조 >  >> Manufacturing Technology >> 제조공정

아두이노 메가 2560과 DHT22, SIM800L로 만드는 SMS 원격 온도 조회 시스템

부품 및 소모품

부품 수량 비고
아두이노 메가 2560 (Arduino Mega 2560) 1 하드웨어 시리얼 포트 다수 보유 (Serial1~3)
DHT22 온습도 센서 1 AM2302 호환
SIM800L GSM/GPRS 모듈 1 별도 3.7-4.2V 전원 필요
10k옴 저항 1 DHT22 데이터 라인 풀업용
브레드보드 1
점퍼 와이어 1세트

프로젝트 소개

안녕하세요. 이 프로젝트는 더 큰 프로젝트의 일부입니다. 이 부분에서 많은 문제를 겪고 결국 해결책을 찾아 커뮤니티와 공유하고자 합니다. 비슷한 문제로 고생하는 분들께 도움이 되길 바랍니다.

프로젝트 설명

아두이노로 SMS를 보내면 집 안의 온도를 문자메시지로 회신받는 시스템입니다.

소프트웨어 및 라이브러리 수정

SIM800L 모듈용으로 Seeeduino_GPRS 라이브러리 사용. 아두이노 메가에서 작동하려면 라이브러리 내 핀 정의를 수정해야 합니다:

// sim800.h 원본
#define SIM800_TX_PIN 8
#define SIM800_RX_PIN 7

// 메가용으로 변경 (SoftwareSerial 대신 하드웨어 시리얼 Serial3 사용 권장이나,
// 라이브러리 수정이 어려워 SoftwareSerial 핀을 메가의 디지털 핀으로 변경)
#define SIM800_TX_PIN 10
#define SIM800_RX_PIN 11

라이브러리를 SoftwareSerial에서 메가의 하드웨어 시리얼 포트(Serial3 등)로 변경하는 것은 너무 복잡해 쉬운 길을 택했습니다.

겪었던 문제

기본적으로 DHT.h와 Seeeduino_GPRS 라이브러리 예제를 복사해 붙여넣기 했습니다. 문제는 gprs.h 예제가 고정된 문자열 메시지만 보내는 방법만 보여주고, 변수(온도 값)를 문자열로 변환해 보내는 방법이 없었다는 점입니다. GPRS_SIM900, SIM800L-master 라이브러리도 마찬가지였습니다.

웹에서 몇 주간 검색하고 포럼 글도 찾아봤지만 답을 못 구했습니다. 답변을 못 받은 분들께 이 글이 도움이 되길 바랍니다.

해결책

float 값을 String으로 변환 → String을 char 배열로 변환 → 전송 하면 됩니다. 간단하죠!

핵심 코드 스니펫

MyString = String(temp, 0);           // float를 String으로 (소수점 0자리)
MyString = (MyString + " Degrees C"); // 단위 추가

// String → char 배열 변환
int str_len = MyString.length() + 1;  // 널 종료 문자 공간 포함
char char_array[str_len];             // 버퍼 준비
MyString.toCharArray(char_array, str_len); // 복사

gprs.sendSMS("04XXXXXXXX", char_array); // 전화번호와 메시지 전송

배선

SIM800L 모듈 전원용으로 울트라파이어 18650 배터리 사용. 추후 전압 레귤레이터 추가 예정. 이 튜토리얼 참조.

참고 자료

사용 라이브러리

코드

DHT_SIMPosting.ino (전체 스케치)

// 다양한 DHT 습도/온도 센서 테스트 예제
// Written by ladyada, public domain
#include "DHT.h"
#define DHTPIN 2     // 데이터 핀
#define DHTTYPE DHT22 // DHT 22 (AM2302)

DHT dht(DHTPIN, DHTTYPE);

#include 
#include 
#define TIMEOUT 5000

GPRS gprs;
bool ITemp = false;
float temp;
String MyString;
#define LED_PIN 13
bool ledStatus;

char currentLine[500] = "";
int currentLineIndex = 0;
bool nextLineIsMessage = false;

void Reply() {
  Serial.println("GPRS - Send SMS Test ...");
  gprs.preInit();
  delay(1000);
  while (0 != gprs.init()) {
    delay(1000);
    Serial.print("init error\r\n");
  }
  Serial.println("Init success, start to send SMS message...");
  
  if (ITemp == true) {
    float t = dht.readTemperature();
    temp = t;
    ITemp = false;
  }
  
  MyString = String(temp, 0);        // float → String
  MyString = (MyString + " Degrees C"); // 단위 추가
  
  // String → char 배열
  int str_len = MyString.length() + 1;
  char char_array[str_len];
  MyString.toCharArray(char_array, str_len);
  
  gprs.sendSMS("04XXXXXXXX", char_array); // 전화번호 입력 필요
}

void setup() {
  Serial.begin(9600);
  Serial.println("DHTxx test!");
  dht.begin();
  
  gprs.preInit();
  delay(1000);
  while (0 != gprs.init()) {
    delay(1000);
    Serial.print("init error\r\n");
  }
  
  // SMS 모드 ASCII 설정
  if (0 != gprs.sendCmdAndWaitForResp("AT+CMGF=1\r\n", "OK", TIMEOUT)) {
    Serial.println("ERROR:CMGF");
    return;
  }
  
  // 새 SMS 수신 알림 활성화
  if (0 != gprs.sendCmdAndWaitForResp("AT+CNMI=1,2,0,0,0\r\n", "OK", TIMEOUT)) {
    Serial.println("ERROR:CNMI");
    return;
  }
  Serial.println("Init success");
}

void loop() {
  delay(2000); // 측정 간격
  
  float h = dht.readHumidity();
  float t = dht.readTemperature();
  
  Serial.print("Humidity: "); Serial.print(h); Serial.println(" %\t");
  Serial.print("Temperature: "); Serial.print(t); Serial.println(" *C ");
  
  SIM();
}

void SIM() {
  digitalWrite(LED_PIN, ledStatus);
  Serial.println("Looking for SMS");
  
  if (gprs.serialSIM800.available()) {
    char lastCharRead = gprs.serialSIM800.read();
    
    if (lastCharRead == '\r' || lastCharRead == '\n') {
      String lastLine = String(currentLine);
      
      // +CMT: 새 SMS 수신 표시
      if (lastLine.startsWith("+CMT:")) {
        Serial.println(lastLine);
        nextLineIsMessage = true;
      } else if (lastLine.length() > 0) {
        if (nextLineIsMessage) {
          Serial.println(lastLine);
          
          // 메시지 내용 확인 및 동작
          if (lastLine.indexOf("InTemp") >= 0) {
            Serial.println("InTemp");
            ITemp = true;
            Reply();
          }
          // else if (lastLine.indexOf("LED OFF") >= 0) { ... }
          
          nextLineIsMessage = false;
        }
      }
      
      // 버퍼 클리어
      for (int i = 0; i < sizeof(currentLine); ++i) currentLine[i] = 0;
      currentLineIndex = 0;
    } else {
      currentLine[currentLineIndex++] = lastCharRead;
    }
  }
}

회로도

아두이노 메가 2560과 DHT22, SIM800L로 만드는 SMS 원격 온도 조회 시스템
아두이노 메가 2560, DHT22, SIM800L 연결도

핵심 포인트

개선 아이디어

제조공정

  1. 온도 제어 팬: 미디어 가구 냉각용 DIY 릴레이 시스템
  2. 5달러 I2C 센서로 라즈베리 파이 온도 로거 만들기
  3. 라즈베리 파이 2에서 DS18B20으로 온도 읽기
  4. 라즈베리 파이와 DS18B20을 이용한 전문적인 온도 모니터링
  5. 라즈베리 파이에서 Maxim 1-Wire 센서와 DS2482 I2C 브리지로 온도 측정하기
  6. 라즈베리 파이로 서버실 정확한 온도 모니터링하기
  7. 초보자 IoT 튜토리얼: 라즈베리 파이에서 온도 데이터 스트리밍하기
  8. 라즈베리 파이로 네트워크 지원 실험실 기상 관측소 구축하기
  9. MCP9808, InfluxDB, Grafana로 라즈베리 파이 홈 온도 모니터 구축하기
  10. 윈도우 IoT 코어 라즈베리파이 2 로버: 초보자부터 고급까지 완전 가이드