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

IoT 기반 듀얼 축 태양광 추적기: 아두이노로 구현하는 스마트 에너지 관리

프로젝트 개요

이 프로젝트는 IoT 기술을 접목한 듀얼 축(2축) 태양광 추적 시스템을 아두이노 메가 2560과 이더넷 실드를 이용해 구현합니다. LDR(조도 센서)로 태양 위치를 감지해 자동으로 패널을 회전시키거나, Cayenne 대시보드에서 수동으로 제어할 수 있습니다. 발전 전압·전류·전력, 온도·습도 데이터를 실시간 모니터링하고 임계값 초과 시 알림(이메일/SMS)도 전송합니다.

주요 기능

필요한 하드웨어 부품

부품수량비고
아두이노 메가 2560 (Arduino Mega 2560)1메인 컨트롤러
이더넷 실드 (Wiznet W5100)1아두이노 위에 장착, RJ45로 공유기 연결
SG90 마이크로 서보 모터2상하(UD), 좌우(LR) 축 구동
LDR 조도 센서 (GL5528, 5MΩ)4패널 4모서리 장착, 아날로그 핀 A0~A3
DHT22 온습도 센서1디지털 핀 2번, -40~80°C / 0~100% RH
미니 태양광 패널 (115×85mm, 1.6W, 6V)1추적 대상 패널
330Ω 저항4LDR 전압 분할 회로용
10Ω 저항2PV 전류 측정용 전압 분할(부하 겸용)
220Ω 저항1모드 표시 LED용
5mm 적색 LED1자동/수동 모드 표시 (핀 3)

소프트웨어 및 플랫폼

하드웨어 설계 상세

서보 모터 구동부

LDR 센서 회로 (전압 분할)

각 LDR과 330Ω 직렬 저항으로 전압 분할 회로 구성 → 아두이노 아날로그 핀 A0~A3 입력. ADC 10비트(0~1023)로 디지털 변환. 빛이 강할수록 LDR 저항 감소 → 분할 전압 상승.

PV 전압/전류 측정 회로

두 개의 10Ω 직렬 저항으로 전압 분할 겸 부하 회로 구성 → 중간 노드 전압을 아날로그 핀 A4 입력.
Vout = (A4 읽기값 × 5.0) / 1023
전류 = Vout / 10 (옴의 법칙)
전압 = Vout × 2 (분할 비율 1:1)
전력 = 전압 × 전류

온습도 센서 (DHT22)

데이터 핀 → 디지털 핀 2번, VCC/GND 연결. 라이브러리로 온도(°C), 습도(%) 읽기.

이더넷 실드 네트워크 연결

Wiznet W5100 칩 기반, TCP/IP 스택 내장. 공유기 RJ45 포트와 직결. 고정 IP 또는 DHCP로 네트워크 참여 → Cayenne MQTT 브로커 접속.

모드 표시 LED

디지털 핀 3번 연결. LOW = 수동 모드, HIGH = 자동 모드. Cayenne 대시보드 버튼 위젯으로 제어.

소프트웨어 설계

1. 아두이노 IDE 펌웨어 구조

2. Cayenne MQTT 연동 원리

Cayenne은 MQTT 발행/구독 모델 사용. 아두이노는 CAYENNE_OUT(VIRTUAL_CHANNEL) 함수로 센서 데이터 발행, CAYENNE_IN(VIRTUAL_CHANNEL) 함수로 액추에이터 명령 수신. 가상 채널(0~31)은 위젯과 매핑.

3. 자동 추적 알고리즘 (그림 4 참조)

// 수평 축(상하) 추적
avgtop    = (LDR_TopRight + LDR_TopLeft) / 2;
avgbot    = (LDR_BotRight + LDR_BotLeft) / 2;
diffhori  = avgtop - avgbot;

if (|diffhori| <= 임계값(10)) 서보 정지;
else if (diffhori > 임계값)  서보 시계방향(CW) 2° 회전;
else                         서보 반시계방향(CCW) 2° 회전;

// 수직 축(좌우) 추적
avgleft   = (LDR_TopLeft + LDR_BotLeft) / 2;
avgright  = (LDR_TopRight + LDR_BotRight) / 2;
diffverti = avgleft - avgright;

// 동일한 로직으로 LR 서보 제어

임계값 ±10은 센서 노이즈로 인한 미세 진동 방지 및 서보 전력 소모 최소화 목적.

4. Cayenne 대시보드 위젯 구성

  1. Cayenne 가입 → "Bring Your Own Things" 선택 → MQTT 인증 정보(Username, Password, Client ID) 발급
  2. 아두이노 코드에 인증 정보 입력 후 업로드 → 시리얼 모니터로 연결 로그 확인
  3. 디바이스 온라인 되면 "Add new → Device/Widget → Custom Widgets"로 위젯 추가
    • 센서류: Value 위젯 (채널 번호 코드와 일치 필수)
    • 모드 전환: Button 위젯 (채널 8)
    • 서보 제어: Slider 위젯 (채널 6, 7, 0~180° 매핑)
  4. 위젯 설정에서 그래프 보기 활성화 가능

5. 알림(Trigger) 설정

"Add new → Trigger" 선택 → 조건(예: 온도 > 50°C) + 액션(이메일 발송) 설정 → 저장. 다중 수신자 지정 가능.

프로토타입 제작 사진

상세 실험 결과는 논문 참조: Springer Link

전체 임베디드 코드

/***************************************************************
 * PROJECT: IoT based solar tracker system / embedded software
 * Author: Aboubakr El Hammoumi
 ***************************************************************/
#define CAYENNE_PRINT Serial
#include 
#include 
#include 

#define DHTTYPE DHT22
#define DHTPIN 2
DHT dht(DHTPIN, DHTTYPE);

// MQTT 인증 정보 (자신의 Cayenne 대시보드에서 발급받은 값으로 교체 필요)
char username[] = "498d2d00-afe2-11ea-883c-638d8ce4c23d";
char password[] = "ab4a8f92d94033c01f6e18ce1d8a84d8c304c9c4";
char clientID[] = "17798a40-b968-11ea-93bf-d33a96695544";

Servo servo_x;  // UD 서보 (핀 5)
int servoh = 0, servohLimitHigh = 170, servohLimitLow = 10;
Servo servo_z;  // LR 서보 (핀 6)
int servov = 0, servovLimitHigh = 170, servovLimitLow = 10;

int topl, topr, botl, botr;
int threshold_value = 10;
float Vout;

void setup() {
  Serial.begin(9600);
  Cayenne.begin(username, password, clientID);
  servo_x.attach(5);
  servo_z.attach(6);
  dht.begin();
  pinMode(3, OUTPUT);
  digitalWrite(3, LOW);  // 초기 수동 모드
}

void loop() {
  // 센서 읽기
  topr = analogRead(A2);  // 주의: 원본 코드 핀 매핑 확인 필요
  topl = analogRead(A3);
  botl = analogRead(A4);
  botr = analogRead(A5);
  Vout = (analogRead(A1) * 5.0) / 1023;  // PV 전압 분할 읽기

  Serial.println("Manual-mode");
  Cayenne.loop();  // MQTT 송수신 처리 (위젯 데이터 업로드/다운로드)

  // 자동 모드일 때만 추적 알고리즘 실행
  if (digitalRead(3) == HIGH) {
    Serial.println("Automatic-mode");
    servoh = servo_x.read();
    servov = servo_z.read();

    int avgtop = (topr + topl) / 2;
    int avgbot = (botr + botl) / 2;
    int avgright = (topr + botr) / 2;
    int avgleft = (topl + botl) / 2;
    int diffhori = avgtop - avgbot;
    int diffverti = avgleft - avgright;

    // 수평 축(UD) 추적
    if (abs(diffhori) <= threshold_value) {
      servo_x.write(servoh);
    } else {
      if (diffhori > threshold_value) {
        servo_x.write(servoh - 2);  // CW
        if (servoh > servohLimitHigh) servoh = servohLimitHigh;
      } else {
        servo_x.write(servoh + 2);  // CCW
        if (servoh < servohLimitLow) servoh = servohLimitLow;
      }
      delay(10);
    }

    // 수직 축(LR) 추적
    if (abs(diffverti) <= threshold_value) {
      servo_z.write(servov);
    } else {
      if (diffverti > threshold_value) {
        servo_z.write(servov - 2);  // CW
        if (servov > servovLimitHigh) servov = servovLimitHigh;
      } else {
        servo_z.write(servov + 2);  // CCW
        if (servov < servovLimitLow) servov = servovLimitLow;
      }
      delay(10);
    }
  }
}

// --- Cayenne 콜백 함수들 ---

// 모드 전환 버튼 (채널 8)
CAYENNE_IN(8) {
  int value = getValue.asInt();
  CAYENNE_LOG("Channel %d, pin %d, value %d", 8, 3, value);
  digitalWrite(3, value);
}

// UD 서보 수동 제어 (채널 7)
CAYENNE_IN(7) {
  if (digitalRead(3) == HIGH) {
    // 자동 모드: 수동 명령 무시
  } else {
    servo_x.write(getValue.asDouble() * 180);  // 0~1 → 0~180° 매핑
  }
}

// LR 서보 수동 제어 (채널 6)
CAYENNE_IN(6) {
  if (digitalRead(3) == HIGH) {
    // 자동 모드: 수동 명령 무시
  } else {
    servo_z.write(getValue.asDouble() * 180);
  }
}

// 센서 데이터 업로드 (CAYENNE_OUT)
CAYENNE_OUT(0) {  // 전류
  float current = Vout / 10;
  Cayenne.virtualWrite(0, current);
}
CAYENNE_OUT(1) {  // 전압
  float voltage = Vout * 2;
  Cayenne.virtualWrite(1, voltage);
}
CAYENNE_OUT(2) { Cayenne.virtualWrite(2, topr); }   // LDR 우상
CAYENNE_OUT(3) { Cayenne.virtualWrite(3, topl); }   // LDR 좌상
CAYENNE_OUT(4) { Cayenne.virtualWrite(4, botl); }   // LDR 좌하
CAYENNE_OUT(5) { Cayenne.virtualWrite(5, botr); }   // LDR 우하
CAYENNE_OUT(10) {  // 전력
  float power = (Vout * 2 * Vout) / 10;
  Cayenne.virtualWrite(10, power);
}
CAYENNE_OUT(11) {  // 온도
  float t = dht.readTemperature();
  Cayenne.virtualWrite(11, t, TYPE_TEMPERATURE, UNIT_CELSIUS);
}
CAYENNE_OUT(12) {  // 습도
  float h = dht.readHumidity();
  Cayenne.virtualWrite(12, h);
}

회로도

프로젝트 페이지에서 회로도 이미지(schematics.png)를 확인할 수 있습니다.

구현 시 주의사항 및 팁

확장 아이디어

마치며

이 프로젝트는 임베디드 시스템, 센서 인터페이싱, IoT 클라우드 연동, 제어 알고리즘, 기계적 설계가 모두 어우러진 종합적인 예제입니다. 태양광 발전 효율을 극대화하면서 원격 모니터링·제어까지 가능한 실용적인 시스템을 아두이노 생태계만으로 구현해 볼 수 있습니다. 연구·교육용 시제품으로 시작해 소규모 오프그리드 전원 시스템으로 확장하기에도 훌륭한 기반이 됩니다.

제조공정

  1. IoT 실무자를 움직이는 힘: 업계 리더들의 통찰
  2. IoT를 위한 블록체인: 안전하고 분산된 데이터 교환 열다
  3. IoT 보안 환경 보호: 주요 위협과 전략적 솔루션 – 파트 2
  4. IoT 보안 미래 대비: 더 안전한 연결 세상을 위한 전문가 전략
  5. 사물인터넷 투자: 성장과 가치 잠금 해제
  6. 사물인터넷의 진정한 진화 추적하기
  7. IoT: 데이터 홍수 마스터로 비즈니스 혁신 이끌기
  8. 오늘날 IoT가 직면한 5가지 핵심 과제
  9. 산업용 IoT로 성장 견인하기: 비용 절감을 넘어
  10. 솔라 트래커 V2.0: 고급 DIY 태양광 패널 추적 시스템