Otomasyon

Arduino ile Endüstriyel Otomasyon: PLC Olmadan Üretim Hattı Kontrolü

Fatih Algül
12.03.2026 13 görüntülenme

Neden PLC Yerine Arduino?

Endüstriyel otomasyon denildiğinde akla ilk gelen bileşen şüphesiz PLC (Programmable Logic Controller) sistemleridir. Ancak özellikle küçük ve orta ölçekli üretim hatlarında, prototipleme aşamalarında veya bütçe kısıtlamalarının söz konusu olduğu projelerde Arduino tabanlı çözümler ciddi bir alternatif olarak öne çıkmaktadır. Bir Siemens S7-1200 PLC'nin maliyeti yüzlerce dolardan başlarken, bir Arduino Mega 2560 kartı bunun çok küçük bir bölümüne edinilebilir.

Elbette Arduino, ağır sanayi uygulamalarında bir PLC'nin yerini tam anlamıyla alamaz. Ancak aşağıdaki senaryolarda güçlü bir çözüm sunar:

  • Küçük ölçekli üretim hatları — 5-10 istasyondan oluşan montaj hatları
  • Prototipleme ve Ar-Ge — yeni bir üretim sürecinin hızlıca test edilmesi
  • Retrofit projeler — eski makinelerin düşük maliyetle otomasyona kavuşturulması
  • Eğitim amaçlı kurulumlar — teknik okul ve üniversite laboratuvarları
  • Tarımsal otomasyon — sera kontrol sistemleri, sulama otomasyonu

Sistem Mimarisi: Üretim Hattı Kontrol Katmanları

Bir üretim hattı kontrol sistemi tasarlarken katmanlı bir mimari kullanmak hem bakım kolaylığı hem de ölçeklenebilirlik açısından kritik önem taşır. Arduino tabanlı bir sistemde bu katmanlar şu şekilde yapılandırılabilir:

1. Algılama Katmanı (Sensörler)

Üretim hattında çeşitli sensörler kullanarak ortam ve ürün durumunu sürekli izleriz. Endüstriyel ortamda yaygın olarak kullanılan sensör tipleri:

  • Endüktif yaklaşım sensörleri — metal parçaların tespiti için (NPN/PNP çıkışlı)
  • Kapasitif sensörler — metal olmayan malzemelerin algılanması
  • Fotoelektrik sensörler — ürün geçiş sayımı ve pozisyon tespiti
  • Sıcaklık sensörleri (PT100, termokupl) — fırın ve ısıtma prosesleri
  • Basınç transmitterleri — pnömatik hat basınç kontrolü
  • Akış sensörleri — sıvı dozajlama sistemleri

2. Kontrol Katmanı (Arduino + Röle Modülleri)

Arduino, sensörlerden gelen verileri işleyerek aktüatörlere komut gönderir. Endüstriyel ortamda güvenilirlik için Arduino Mega 2560 tercih edilmelidir; çünkü 54 dijital I/O, 16 analog giriş ve 4 adet donanımsal UART portu sunar.

3. Güç ve Aktüatör Katmanı

Motorlar, valfler, konveyör bantlar ve pnömatik silindirler bu katmanda yer alır. Arduino ile bu bileşenler arasındaki bağlantı, endüstriyel röle modülleri veya yarı iletken röleler (SSR) aracılığıyla sağlanır.

4. İzleme Katmanı (HMI / SCADA)

Operatörlerin sistemi izleyip müdahale edebilmesi için basit bir HMI (Human Machine Interface) paneli oluşturulabilir. Bunun için bir Nextion dokunmatik ekran veya seri port üzerinden haberleşen bir bilgisayar yazılımı kullanılabilir.

Donanım Bağlantı Şeması ve Güvenlik Önlemleri

Endüstriyel ortamda Arduino kullanırken elektriksel izolasyon ve gürültü filtreleme hayati önem taşır. Aşağıdaki önlemler mutlaka alınmalıdır:

  • Optokuplörler — sensör ve röle sinyallerini Arduino'dan galvanik olarak izole edin
  • Ayrı güç kaynakları — Arduino için 5V/2A izoleli bir SMPS, röle kartı ve aktüatörler için ayrı 24V endüstriyel güç kaynağı kullanın
  • TVS diyotlar ve varistörler — gerilim piklerine karşı koruma sağlayın
  • Kablolama — sinyal kablolarını güç kablolarından ayrı kanal içinde çekin; ekranlı kablo tercih edin
  • Acil durdurma (E-Stop) — yazılımdan bağımsız, donanımsal bir acil durdurma devresi mutlaka bulunmalıdır
  • Watchdog Timer — Arduino donması durumunda sistemi güvenli duruma geçirmek için harici bir watchdog devresi ekleyin

Kritik uyarı: Acil durdurma mekanizması hiçbir zaman yalnızca yazılıma bağlı olmamalıdır. Donanımsal bir kontaktör devresi ile tüm güç çıkışları fiziksel olarak kesilmelidir.

Örnek Proje: 3 İstasyonlu Üretim Hattı Kontrolü

Aşağıdaki senaryoyu ele alalım: Bir konveyör bant üzerinde üç istasyon bulunmaktadır. İlk istasyonda parça algılama, ikinci istasyonda pnömatik presleme, üçüncü istasyonda kalite kontrol (ağırlık ölçümü) yapılmaktadır. Hatalı parçalar ayrı bir hatta yönlendirilir.

// ============================================
// 3 İstasyonlu Üretim Hattı Kontrol Sistemi
// Arduino Mega 2560
// ============================================

// --- Pin Tanımlamaları ---
// Sensörler
const int SENSOR_IST1       = 2;   // İstasyon 1 - Parça algılama (fotoelektrik)
const int SENSOR_IST2       = 3;   // İstasyon 2 - Parça pozisyon sensörü
const int SENSOR_IST3       = 4;   // İstasyon 3 - Parça pozisyon sensörü
const int SENSOR_PRES_UST   = 5;   // Pres üst limit switch
const int SENSOR_PRES_ALT   = 6;   // Pres alt limit switch
const int SENSOR_E_STOP     = 7;   // Acil durdurma butonu (NC)

// Aktüatörler
const int RELAY_KONVEYOR    = 22;  // Konveyör motor rölesi
const int RELAY_PRES_ILERI  = 23;  // Pnömatik pres ileri solenoid valf
const int RELAY_PRES_GERI   = 24;  // Pnömatik pres geri solenoid valf
const int RELAY_AYIRICI     = 25;  // Hatalı parça ayırıcı piston
const int LED_YESIL         = 26;  // Çalışıyor göstergesi
const int LED_KIRMIZI       = 27;  // Hata göstergesi

// Analog
const int LOAD_CELL_PIN     = A0;  // Yük hücresi (ağırlık ölçüm)

// --- Sabitler ---
const float AGIRLIK_MIN     = 95.0;   // Minimum kabul ağırlığı (gram)
const float AGIRLIK_MAX     = 105.0;  // Maksimum kabul ağırlığı (gram)
const unsigned long PRES_SURESI   = 2000;  // Presleme süresi (ms)
const unsigned long KONVEYOR_ADIM = 1500;  // İstasyonlar arası taşıma süresi (ms)

// --- Durum Makinesi ---
enum SistemDurumu {
  BOSTA,
  PARCA_ALGILANDI,
  KONVEYOR_TASIYOR,
  PRESLEME_BASLA,
  PRESLEME_DEVAM,
  PRESLEME_GERI,
  KALITE_KONTROL,
  PARCA_AYIRMA,
  HATA_DURUMU
};

SistemDurumu mevcutDurum = BOSTA;
unsigned long durumZamani = 0;
unsigned int toplamParca = 0;
unsigned int hataliParca = 0;

// --- Fonksiyon: Yük Hücresi Okuma ---
float agirlikOku() {
  long toplam = 0;
  for (int i = 0; i < 10; i++) {
    toplam += analogRead(LOAD_CELL_PIN);
    delay(1);
  }
  float ortalama = toplam / 10.0;
  // Kalibrasyon: 0-1023 aralığını 0-200 gram'a dönüştür
  return (ortalama / 1023.0) * 200.0;
}

// --- Fonksiyon: Acil Durum Kontrolü ---
bool acilDurumKontrol() {
  if (digitalRead(SENSOR_E_STOP) == HIGH) {
    // NC buton açıldı = acil durum
    mevcutDurum = HATA_DURUMU;
    digitalWrite(RELAY_KONVEYOR, LOW);
    digitalWrite(RELAY_PRES_ILERI, LOW);
    digitalWrite(RELAY_PRES_GERI, HIGH);
    digitalWrite(LED_KIRMIZI, HIGH);
    digitalWrite(LED_YESIL, LOW);
    Serial.println("!!! ACIL DURDURMA AKTIF !!!");
    return true;
  }
  return false;
}

// --- Fonksiyon: Seri Port Durum Raporu ---
void durumRaporla() {
  Serial.print("Durum: ");
  Serial.print(mevcutDurum);
  Serial.print(" | Toplam: ");
  Serial.print(toplamParca);
  Serial.print(" | Hatali: ");
  Serial.println(hataliParca);
}

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

  // Sensör pinleri
  pinMode(SENSOR_IST1, INPUT_PULLUP);
  pinMode(SENSOR_IST2, INPUT_PULLUP);
  pinMode(SENSOR_IST3, INPUT_PULLUP);
  pinMode(SENSOR_PRES_UST, INPUT_PULLUP);
  pinMode(SENSOR_PRES_ALT, INPUT_PULLUP);
  pinMode(SENSOR_E_STOP, INPUT_PULLUP);

  // Aktüatör pinleri
  pinMode(RELAY_KONVEYOR, OUTPUT);
  pinMode(RELAY_PRES_ILERI, OUTPUT);
  pinMode(RELAY_PRES_GERI, OUTPUT);
  pinMode(RELAY_AYIRICI, OUTPUT);
  pinMode(LED_YESIL, OUTPUT);
  pinMode(LED_KIRMIZI, OUTPUT);

  // Başlangıç durumu: tüm çıkışlar kapalı
  digitalWrite(RELAY_KONVEYOR, LOW);
  digitalWrite(RELAY_PRES_ILERI, LOW);
  digitalWrite(RELAY_PRES_GERI, LOW);
  digitalWrite(RELAY_AYIRICI, LOW);
  digitalWrite(LED_YESIL, HIGH);
  digitalWrite(LED_KIRMIZI, LOW);

  Serial.println("Sistem hazir. Parca bekleniyor...");
}

void loop() {
  // Her döngüde acil durum kontrolü
  if (acilDurumKontrol()) return;

  switch (mevcutDurum) {

    case BOSTA:
      if (digitalRead(SENSOR_IST1) == LOW) {
        Serial.println("Parca algilandi - Istasyon 1");
        mevcutDurum = PARCA_ALGILANDI;
        durumZamani = millis();
      }
      break;

    case PARCA_ALGILANDI:
      // Konveyörü çalıştır, parçayı istasyon 2'ye taşı
      digitalWrite(RELAY_KONVEYOR, HIGH);
      mevcutDurum = KONVEYOR_TASIYOR;
      durumZamani = millis();
      break;

    case KONVEYOR_TASIYOR:
      if (digitalRead(SENSOR_IST2) == LOW) {
        digitalWrite(RELAY_KONVEYOR, LOW);
        mevcutDurum = PRESLEME_BASLA;
        durumZamani = millis();
      }
      // Zaman aşımı kontrolü
      if (millis() - durumZamani > 10000) {
        Serial.println("HATA: Konveyor zaman asimi!");
        mevcutDurum = HATA_DURUMU;
      }
      break;

    case PRESLEME_BASLA:
      Serial.println("Presleme basliyor - Istasyon 2");
      digitalWrite(RELAY_PRES_ILERI, HIGH);
      mevcutDurum = PRESLEME_DEVAM;
      durumZamani = millis();
      break;

    case PRESLEME_DEVAM:
      if (millis() - durumZamani >= PRES_SURESI) {
        digitalWrite(RELAY_PRES_ILERI, LOW);
        digitalWrite(RELAY_PRES_GERI, HIGH);
        mevcutDurum = PRESLEME_GERI;
        durumZamani = millis();
      }
      break;

    case PRESLEME_GERI:
      if (digitalRead(SENSOR_PRES_UST) == LOW) {
        digitalWrite(RELAY_PRES_GERI, LOW);
        // Parçayı istasyon 3'e taşı
        digitalWrite(RELAY_KONVEYOR, HIGH);
        mevcutDurum = KALITE_KONTROL;
        durumZamani = millis();
      }
      break;

    case KALITE_KONTROL:
      if (digitalRead(SENSOR_IST3) == LOW) {
        digitalWrite(RELAY_KONVEYOR, LOW);
        delay(500); // Stabilizasyon bekle

        float agirlik = agirlikOku();
        Serial.print("Olculen agirlik: ");
        Serial.print(agirlik, 1);
        Serial.println(" g");

        toplamParca++;

        if (agirlik < AGIRLIK_MIN || agirlik > AGIRLIK_MAX) {
          Serial.println("HATA: Agirlik tolerans disi! Parca ayriliyor.");
          hataliParca++;
          mevcutDurum = PARCA_AYIRMA;
        } else {
          Serial.println("OK: Parca kabul edildi.");
          // Konveyörü çalıştırıp parçayı çıkışa gönder
          digitalWrite(RELAY_KONVEYOR, HIGH);
          delay(KONVEYOR_ADIM);
          digitalWrite(RELAY_KONVEYOR, LOW);
          mevcutDurum = BOSTA;
        }
        durumRaporla();
        durumZamani = millis();
      }
      break;

    case PARCA_AYIRMA:
      digitalWrite(RELAY_AYIRICI, HIGH);
      delay(800);
      digitalWrite(RELAY_AYIRICI, LOW);
      delay(200);
      mevcutDurum = BOSTA;
      Serial.println("Hatali parca ayrildi. Yeni parca bekleniyor...");
      break;

    case HATA_DURUMU:
      // Acil durum butonu serbest bırakılınca sistemi sıfırla
      if (digitalRead(SENSOR_E_STOP) == LOW) {
        delay(1000); // Debounce
        if (digitalRead(SENSOR_E_STOP) == LOW) {
          mevcutDurum = BOSTA;
          digitalWrite(LED_KIRMIZI, LOW);
          digitalWrite(LED_YESIL, HIGH);
          Serial.println("Sistem sifirlandi. Parca bekleniyor...");
        }
      }
      break;
  }

  delay(10); // Ana döngü kararlılığı için kısa bekleme
}

Kod Yapısının Açıklaması

Yukarıdaki kodda durum makinesi (state machine) tasarım kalıbı kullanılmıştır. Bu, endüstriyel otomasyon yazılımlarında en yaygın kullanılan programlama yöntemidir ve PLC'lerdeki Grafcet / SFC (Sequential Function Chart) mantığının Arduino karşılığıdır. Her durum, üretim hattındaki bir adımı temsil eder ve bir sonraki duruma geçiş belirli koşulların sağlanmasına bağlıdır.

Kodun önemli tasarım kararları:

  • Zaman aşımı kontrolleri: Konveyör taşıma gibi kritik aşamalarda zaman aşımı mekanizması bulunur. Bir sensör arızalanırsa veya parça sıkışırsa sistem sonsuz döngüde kalmaz, hata durumuna geçer.
  • Acil durdurma önceliği: loop() fonksiyonunun en başında acil durum kontrolü yapılır. Bu sayede sistem hangi durumda olursa olsun acil durdurma anında devreye girer.
  • Analog okuma filtreleme: Yük hücresi okuması 10 örneğin ortalaması alınarak yapılır. Endüstriyel ortamdaki elektriksel gürültü, tek bir okumayı kolayca bozabilir.
  • NC (Normally Closed) sensör mantığı: Acil durdurma butonu NC olarak bağlanmıştır. Bu endüstriyel bir standarttır; kablo kopması durumunda sistem güvenli duruma geçer.

Haberleşme: Modbus RTU ile Endüstriyel Entegrasyon

Arduino'yu mevcut endüstriyel altyapıya entegre etmek için Modbus RTU protokolü kullanılabilir. RS-485 dönüştürücü modül (MAX485) ile Arduino, endüstriyel HMI paneller, frekans invertörleri ve diğer Modbus cihazlarıyla haberleşebilir.

#include <ModbusRtu.h>

// Modbus slave, ID: 1, RS-485 DE/RE pin: 8
Modbus slave(1, Serial1, 8);

uint16_t modbusRegisters[10];
// Register[0] = sistem durumu
// Register[1] = toplam parça sayısı
// Register[2] = hatalı parça sayısı
// Register[3] = anlık ağırlık (x10)
// Register[4] = komut registeri (HMI'dan gelen)

void setup() {
  Serial1.begin(19200);
  slave.start();
}

void loop() {
  // Modbus registerleri güncelle
  modbusRegisters[0] = (uint16_t)mevcutDurum;
  modbusRegisters[1] = toplamParca;
  modbusRegisters[2] = hataliParca;
  modbusRegisters[3] = (uint16_t)(agirlikOku() * 10);

  // Modbus iletişimini işle
  slave.poll(modbusRegisters, 10);

  // HMI'dan gelen komutları kontrol et
  if (modbusRegisters[4] == 1) {
    // Sistem başlat komutu
    mevcutDurum = BOSTA;
    modbusRegisters[4] = 0;
  } else if (modbusRegisters[4] == 2) {
    // Sistem durdur komutu
    mevcutDurum = HATA_DURUMU;
    modbusRegisters[4] = 0;
  }
}

Bu sayede bir Weintek, Nextion veya bilgisayar tabanlı SCADA yazılımı üzerinden sistemi izlemek ve kontrol etmek mümkün hale gelir.

Arduino ve PLC Karşılaştırma Tablosu

  • Maliyet: Arduino Mega ~15-25$, temel PLC ~200-500$
  • I/O Sayısı: Arduino Mega 54 dijital + 16 analog; PLC modele göre genişletilebilir
  • Programlama: Arduino C/C++; PLC Ladder, FBD, ST, SFC
  • Çalışma Sıcaklığı: Arduino 0-70°C (ticari); PLC -25°C ile +70°C (endüstriyel)
  • EMC Dayanımı: Arduino düşük (ek önlem gerekir); PLC yüksek (sertifikalı)
  • Sertifikasyon: Arduino yok; PLC CE, UL, IEC 61131 uyumlu
  • Güvenilirlik (MTBF): Arduino belirtilmez; PLC onbinlerce saat
  • Topluluk/Destek: Arduino çok geniş açık kaynak; PLC üretici bazlı profesyonel destek

Endüstriyel Ortamda Arduino Güvenilirliğini Artırma İpuçları

  1. DIN ray montajlı muhafaza kullanın: Piyasada Arduino Mega için DIN ray uyumlu endüstriyel kasalar mevcuttur. Bu kasalar hem mekanik koruma hem de elektriksel izolasyon sağlar.
  2. Harici watchdog timer ekleyin: Arduino'nun dahili watchdog'u sınırlıdır. TPL5010 gibi harici bir watchdog IC'si ile mikrodenetleyici donma durumunda donanımsal reset sağlanır.
  3. EEPROM'a veri yedekleyin: Sayaç değerleri ve kalibrasyon parametreleri gibi kritik verileri EEPROM'a yazarak güç kesintilerinde veri kaybını önleyin. Ancak EEPROM yazma ömrünü (100.000 döngü) aşmamak için yazma sıklığını sınırlayın.
  4. Redundant sensör kullanın: Kritik noktalarda çift sensör kullanarak tek noktadan arıza (single point of failure) riskini azaltın.
  5. Gerilim regülasyonu: Endüstriyel ortamlarda güç hattı dalgalanmaları yaygındır. Arduino'yu beslemeden önce kaliteli bir DC-DC regülatör kullanarak kararlı 5V sağlayın.
  6. Firmware OTA güncelleme: ESP32 tabanlı bir modül ekleyerek kablosuz firmware güncellemesi yapabilir, bakım süresini minimuma indirebilirsiniz.

Sonuç ve Değerlendirme

Arduino ile endüstriyel otomasyon, doğru mühendislik yaklaşımıyla son derece başarılı sonuçlar verebilen bir çözüm yoludur. Özellikle küçük işletmelerin dijital dönüşüm süreçlerinde, Ar-Ge laboratuvarlarında ve eğitim kurumlarında PLC'ye kıyasla çok daha düşük maliyetle hızlı prototipleme ve uygulama geliştirme imkânı sunar.

Ancak unutulmaması gereken en önemli nokta şudur: güvenlik asla yazılıma bırakılmamalıdır. Donanımsal acil durdurma devreleri, galvanik izolasyon ve uygun kablolama standartlarına uymak, Arduino tabanlı bir sistemin endüstriyel ortamda güvenle çalışmasının temel şartıdır. CE işaretlemesi veya makine güvenliği sertifikasyonu gerektiren uygulamalarda, Arduino tek başına yeterli olmayacaktır; bu tür projelerde güvenlik PLC'leri veya sertifikalı güvenlik röleleri ile birlikte kullanılmalıdır.

Doğru tasarım, uygun bileşen seçimi ve endüstriyel standartlara saygı ile Arduino, üretim hattı otomasyonunda güçlü, esnek ve ekonomik bir platform olarak hizmet verebilir.

Yazar Hakkında
Fatih Algül
TechSoft Solutions
Proje mi var?

Yazılım, IoT veya otomasyon konularında destek almak ister misiniz?

İletişime Geç