Python ile 2 Kanal 5V Röle Kontrol Arayüzü
Bu uygulamada önce 2 kanal 5V röle modülü açıklanacak, daha sonra Arduino'ya bağlı 2 kanal 5V röle kartında bulunan 2 adet rölenin Python arayüz ile kontrol edilebilmesi için Python ve Arduino kodları verilecektir.
Python ile Arduino mikrodenetleyici kartının bağlı olduğu seri portu kontrol edebilmek için PySerial modülünün kurulması gerekir. Bu kütüphane kullanılarak Python ile seri port kontrolü yapılabilir. Python programlama dilinde oyun ve kullanıcı arayüzleri oluşturmak için PyGame modülü yaygın olarak kullanılır. Bu modüllerin kurulması için aşağıdaki işlem adımları takip edilir:
1. Kullanılan Python editörünün komut satırı (terminal) açılır. Alternatif olarak Windows komut istemi veya Windows PowerShell açılır.
2. pip install pyserial
3. pip install pygame
komutları verilir.
Editör olarak Python IDLE Shell ve Visual Studio Code kullanılmıştır. Visual Studio Code editörü kullanılacaksa Python eklentisinin kurulması gerekir. Kod açıklamaları açıklama (yorum) satırı olarak verilmiştir.
Bu uygulamada Arduino'ya bağlı 2 kanal 5V röle kartında bulunan 2 adet röle, Python arayüz ile kontrol edilmiştir. Pygame modülü kullanılarak 800x600 ölçüsünde bir pencere oluşturularak her kanal için on/off butonlarıyla kontrol sağlanmıştır. Program çıktısı aşağıda verilmiştir. Aynı arayüz LED kontrolü için uyarlanabilir.

Görsel 1: Kullanıcı port seçim arayüzü

Görsel 2: Python röle kontrol arayüzü program kodu çıktısı
Programda kullanılan arkaresim.png, pencere ikonu için kullanılan relay.png, butonlar için buton_on.png, buton_off.png ve programdan çıkış için kullanılan kapat.png dosyaları aşağıdaki bağlantıya tıklanarak indirilebilir. Bu dosyalar Python kodunun bulunduğu klasör içerisinde bulunmalıdır.
Röle ve Röle Kartı Hakkında
Röle, bir elektromıknatıs tarafından elektriksel olarak çalıştırılan elektromekanik bir anahtardır. Röleyle yüksek voltajlı elektronik cihazlar kontrol edilebilir. Elektromıknatıs, bir mikrodenetleyiciden gelen 5V gibi düşük bir gerilimle tetiklenir ve yüksek gerilimli bir devreyi açmak veya kapatmak için bir kontağı çeker.

Görsel 3: Röle sembolü
Aşağıda 250V AC ve 30 VDC'de 10A değerinde 2 adet röleye sahip 5V 2 kanal röle kartının pin diyagramı görülmektedir. Yüksek gerilim çıkış konnektöründe 3 pin bulunur. Ortadaki pin ortak pindir (COM). Diğer iki pinden biri normalde açık (NO) bağlantı, diğeri normalde kapalı (NC) bağlantı içindir. Modülün diğer tarafında iki pin grubu bulunmaktadır. Birincisinde 4 pin; modülü beslemek için bir toprak (GND) ve bir VCC pini ile 2 giriş pini (IN1 ve IN2) bulunur. İkinci pin grubunda 3 pin; JD-VCC, VCC, GND bulunur. JD-VCC pini rölenin elektromıknatısını besler. JD-VCC ve VCC pinleri arasında güç seçmek için bir jumper vardır. Jumper'ın takılı olduğu yapılandırmayla rölenin elektromıknatısı doğrudan Arduino kartından beslenir. Ancak rölede bir sorun olursa mikrodenetleyici zarar görebilir.

Görsel 4: 5V 2 kanal röle kartı pin diyagramı

Görsel 5: 5V 2 kanal röle kartı kontaklar
- GND: Toprak hattı.
- IN1: Birinci röleyi kontrol eder. Arduino'nun dijital pinine bağlanır.
- IN2: İkinci röleyi kontrol eder. Arduino'nun dijital pinine bağlanır.
- VCC: 5V.
- COM: Ortak pin.
- NC (Normalde Kapalı): Normalde kapalı yapılandırma, rölenin varsayılan olarak kapalı olması istenildiğinde kullanılır. Bu durum Arduino'dan röle modülüne devreyi açmak ve akımı durdurmak için bir sinyal gönderilmediği sürece akımın akmaya devam ettiği anlamına gelir.
- NO (Normalde Açık): Normalde açık yapılandırma tam tersi şekilde çalışır. Röle her zaman açıktır. Bu nedenle Arduino'dan devreyi kapatmak için bir sinyal gönderilmediği sürece bu kontağa bağlı yük çalışmaz. Eğer yük (örneğin bir lamba) arada bir çalıştırılmak isteniyorsa, NO kontağı kullanmak daha iyidir.
Görsel 6'da röle kartı devre şeması verilmiştir. Mikrodenetleyiciden gelen ve optokuplör aracılığıyla röleyi etkinleştirmek için VCC pinine bağlanan 5V gerilimin, rölenin elektromıknatısını (bobinini) besleyen JD-VCC pinine de bağlı olduğu görülmektedir. Bu durumda röle ile mikrodenetleyici arasında izolasyon bulunmamaktadır.

Görsel 6: Röle kartı devre şeması (jumper takılı)
Mikrodenetleyiciyi röleden izole etmek için jumper çıkarılmalı ve röle bobini (elektromıknatıs) için ayrı bir güç kaynağı JD-VCC ve toprak (GND) pinine bağlanmalıdır. Bu yapılandırmayla mikrodenetleyicinin röleyle fiziksel bir bağlantısı olmaz. Sadece optokuplör üzerinden LED diyot ışığı röleyi etkinleştirmek için kullanılır (Görsel 7).

Görsel 7: Röle kartı devre şeması (jumper takılı değil)
Devre şeması dikkatle incelenirse modülün giriş pinlerinin ters yönde çalıştığı görülür. Giriş pini LOW (lojik 0) olduğunda röle aktif hale gelir. Çünkü bu şekilde akım VCC'den düşük veya toprak olan giriş pinine akabilir. LED diyot ışık vererek röleyi aktif hale getirir. Giriş pini HIGH (lojik 1) olduğunda ise akım akışı olmaz. Bu nedenle LED diyot ışık vermez ve röle aktif hale gelmez.

Görsel 8: Röle kartı devre şeması (jumper takılı değil)
Dikkat!!!
Modülün VCC ve JD-VCC pinlerini birbirine bağlayan bir jumper olduğuna dikkat edilmelidir. Genellikle bu jumper mavi renktedir. Jumper, devrenin Arduino devresine fiziksel olarak bağlı olup olmadığının seçilmesine imkan tanır. Jumper takılı iken, VCC ve JD-VCC pinleri birbirine bağlanır. Bu durum, röle elektromıknatısının (bobininin) doğrudan Arduino'nun güç pininden beslendiği anlamına gelir. Bu nedenle röle modülü ve Arduino devreleri fiziksel olarak birbirinden izole değildir. Jumper takılı değilken, röle elektromıknatısını JD-VCC pini üzerinden beslemek için bağımsız bir güç kaynağı sağlanmalıdır. Bu yapılandırma, röleyi Arduino'dan modülün yerleşik optokuplörü ile fiziksel olarak izole eder. Bu daha güvenlikli bir yapılandırmadır. Röle kartıyla çalışırken yanlış veya uygunsuz kullanım durumları ciddi yaralanmalara veya ölüme yol açabilir. Şebeke gerilimine bağlı projeler yapılırken yüksek gerilim konusunda dikkatli olunmalıdır. Tüm iş sağlığı ve güvenliği tedbirleri alınmalıdır.
Uygulamaya Ait Şema, Bağlantı Şekli ve Görseller

Görsel 9: Arduino Uno ile röle kartı devre şeması
Malzeme Listesi
|
Sıra No |
Adı |
Özelliği |
Miktarı |
|
1 |
Arduino Uno R3 |
- |
1 Adet |
|
2 |
Röle kartı |
2 kanal 5V |
1 Adet |
|
3 |
LED diyot |
5 mm kırmızı, yeşil |
2 adet |
|
4 |
Direnç |
220R / ¼ W |
2 adet |
|
5 |
Breadboard |
830 pin |
1 Adet |
|
6 |
Jumper kablo |
Erkek-dişi / erkek-erkek |
- |
Uygulamaya Ait Python Kodu
Aşağıda 2 ayrı kod örneği verilmiştir. Her iki kod çıktısı da aynıdır.
İkinci verilen kod, alt fonksiyonlarla optimize edilmiştir. Ayrıca port kapalı iken programın çökmemesi için try-except bloğu ile hata yönetimi (exception handling) ve tkinter modülü kullanılarak küçük mesaj kutusunda uyarı mesajı vermesi özelliği eklenmiştir. Dinamik yeniden bağlanma mantığı kullanılmıştır. Cihazın port bağlantısı kesildikten sonra tekrar bağlantı sağlandığında program çalışmaya devam eder. Program açılışta kullanıcıya mevcut portları bir pencerede seçtirir. Kod daha da geliştirilebilir. Kaynak dosya auto-py-to-exe ile derlenerek tek bir exe dosya haline getirilmiş ve test edilmiştir. Derlenmiş dosya aşağıdaki bağlantıdan indirilebilir.
"""
Uygulama Adı : Python ile röle/led kontrol arayüzü
Açıklama : Röle kontrol arayüzü
Tarih : 1 Mayıs 2026
Yazan : İlhan DEMİR
"""
import pygame, os, serial
#pygame, os ve serial modülleri eklendi.
pygame.init()
#pygame modülü başlatıldı.
#Arduino kartının bağlı olduğu seri port ayarları yapıldı.
#Haberleşme portu com6, haberleşme hızı 9600 baud
#port=serial.Serial("com6",9600)
port=serial.Serial()
port.port="com6"
port.baudrate=9600
port.open()
print("Port açıldı.")
#port bilgileri konsoldan yazdırıldı.
print(port)
print()
ekranBoyutu=(800,600)
#Ekran boyutu demet veri tipinde tanımlandı.
#Pencere 800x360 ölçülerinde oluşturuldu.
ekran=pygame.display.set_mode(ekranBoyutu)
#ekran=pygame.display.set_mode((800,600))
pygame.display.set_caption("Arduino Röle Kontrol Arayüzü")
#Pencere için başlık tanımlandı.
iconDosya= "relay.png"
#relay.png dosyasının aynı klasörde olup olmadığının kontrolü yapıldı.
if os.path.exists(iconDosya):
#Pencere ikonu yüklendi.
icon = pygame.image.load(iconDosya)
pygame.display.set_icon(icon)
print("Pencere ikonu başarıyla yüklendi.")
else:
print(f"Uyarı: '{iconDosya}' dosyası bulunamadı. Varsayılan icon kullanılıyor.")
#Pencere arka plan görseli ve butonlar tanımlandı.
arkaResim=pygame.image.load("arkaresim.png")
onButon1=pygame.image.load("buton_on.png")
onButon1Koordinat=onButon1.get_rect()
onButon1Koordinat.topleft=(270,120)
offButon1=pygame.image.load("buton_off.png")
offButon1Koordinat=offButon1.get_rect()
offButon1Koordinat.topleft=(420,120)
onButon2=pygame.image.load("buton_on.png")
onButon2Koordinat=onButon2.get_rect()
onButon2Koordinat.topleft=(270,205)
offButon2=pygame.image.load("buton_off.png")
offButon2Koordinat=offButon2.get_rect()
offButon2Koordinat.topleft=(420,205)
kapatButon=pygame.image.load("kapat.png")
kapatButonKoordinat=kapatButon.get_rect()
kapatButonKoordinat.topleft=(345,350)
#Arayüz için font arial ve font boyutu piksel olarak tanımlandı.
font1=pygame.font.SysFont("arial",64)
font2=pygame.font.SysFont("arial",22)
font3=pygame.font.SysFont("arial",30)
#yazi1 render yapıldı.
yazi1=font1.render("Röle Kontrol Arayüzü",True,(40,44,52))
#yazi1 için konum ayarlandı.
yazi1Koordinat=yazi1.get_rect()
yazi1Koordinat.topleft=(165,40)
#"www.beyzemiter.com" karakter dizisi render yapıldı.
yazi2=font2.render("www.beyzemiter.com",True,(40,44,52))
#"www.beyzemiter.com" karakter dizisi için konum ayarlandı.
yazi2Koordinat=yazi2.get_rect()
yazi2Koordinat.topleft=(325,515)
#"1.Kanal" karakter dizisi render yapıldı.
yazi3=font3.render("1.Kanal",True,(40,44,52))
#"1.Kanal" karakter dizisi için konum ayarlandı.
yazi3Koordinat=yazi3.get_rect()
yazi3Koordinat.topleft=(160,166)
#"2.Kanal" karakter dizisi render yapıldı.
yazi4=font3.render("2.Kanal",True,(40,44,52))
#"2.Kanal" karakter dizisi için konum ayarlandı.
yazi4Koordinat=yazi3.get_rect()
yazi4Koordinat.topleft=(160,251)
#"© 2026 İlhan DEMİR" karakter dizisi render yapıldı.
yazi5=font2.render("© 2026 İlhan DEMİR",True,(40,44,52))
#"© 2026 İlhan DEMİR" karakter dizisi için konum ayarlandı.
yazi5Koordinat=yazi5.get_rect()
yazi5Koordinat.topleft=(325,545)
#arkaResim pencereyi dolduracak şekilde ayarlandı.
ekran.blit(arkaResim,(0,0))
#Butonlar görüntülendi.
ekran.blit(onButon1,onButon1Koordinat)
ekran.blit(offButon1,offButon1Koordinat)
ekran.blit(onButon2,onButon2Koordinat)
ekran.blit(offButon2,offButon2Koordinat)
ekran.blit(kapatButon,kapatButonKoordinat)
#yazi1, yazi2, yazi3, yazi4, yazi5 değişkenleri görüntülendi.
ekran.blit(yazi1,yazi1Koordinat)
ekran.blit(yazi2,yazi2Koordinat)
ekran.blit(yazi3,yazi3Koordinat)
ekran.blit(yazi4,yazi4Koordinat)
ekran.blit(yazi5,yazi5Koordinat)
durum=True
while durum:
#İmleç koordinatları alındı.
fare=pygame.mouse.get_pos()
#imleç koordinatlarını yazdır (genişlik,yükseklik)
print(fare)
#Bu döngü olmazsa pencere açıldığı gibi saniyeler içinde kapanır.
#Döngü sayesinde X butonuna basana kadar pencere aktif kalır.
for olay in pygame.event.get():
#Pencerenin X butonuna tıklanmış mı?
if olay.type==pygame.QUIT:
durum=False
#Farenin sol tuşuna tıklanmış mı?
if olay.type==pygame.MOUSEBUTTONDOWN:
#İmleç konumuna göre veri gönder.
#fare[0] genişlik (x), fare[1] yükseklik (y)
if 270<=fare[0]<=398 and 119<=fare[1]<=189:
port.write(b'a')
continue #Koşulu atla
if 420<=fare[0]<=548 and 119<=fare[1]<=189:
port.write(b'b')
continue #Koşulu atla
if 270<=fare[0]<=398 and 205<=fare[1]<=275:
port.write(b'c')
continue #Koşulu atla
if 420<=fare[0]<=548 and 205<=fare[1]<=275:
port.write(b'd')
continue #Koşulu atla
if 345<=fare[0]<=473 and 350<=fare[1]<=477:
#Döngüden çık.
durum=False
#Yapılan değişiklikler ekrana yansıtıldı.
pygame.display.flip()
#pygame.display.update()
#pygame modülü kapatıldı.
pygame.quit()
"""
Uygulama Adı : Python ile röle/led kontrol arayüzü
Açıklama : Röle kontrol arayüzü
Tarih : 2 Mayıs 2026
Yazan : İlhan DEMİR
"""
import sys, pygame, os, serial, time
#pygame, os ve serial modülleri eklendi.
import serial.tools.list_ports
from tkinter import ttk
# Açılır menü (Combobox) için
import tkinter as tk
#Grafik arayüz modülü eklendi. tk ön adıyla kullanılacak.
from tkinter import messagebox
#Küçük mesaj kutusu için özel alt modül eklendi.
# Genel ayarlar ve değişkenler
pygame.init()
#pygame modülü başlatıldı.
portAdi=""
baudRate = 9600
port = None
#Arduino kartının bağlı olduğu seri port ayarları yapıldı.
#Haberleşme portu com6, haberleşme hızı 9600 baud
ekranBoyutu = (800, 600)
#Ekran boyutu demet veri tipinde tanımlandı.
ekran = pygame.display.set_mode(ekranBoyutu)
#Pencere 800x600 ölçülerinde oluşturuldu.
pygame.display.set_caption("Arduino 2 Kanal Röle Kontrol Arayüzü")
#Pencere için başlık tanımlandı.
renk = (40, 44, 52)
# Renk tanımlaması demet veri tipinde yapıldı.
role1Durum = "Kapalı"
role2Durum = "Kapalı"
#auto-py-to-exe kullanarak tek bir exe dosya haline getirilmeye
#hazır olması için bu fonksiyon eklendi.
def kaynakYolu(goreceliYol):
#PyInstaller geçici klasöründeki dosya yolunu belirler.
#Derleme için bu fonksiyon gerekli, görsellerin kaynak yolu
try:
base_path = sys._MEIPASS
except Exception:
base_path = os.path.abspath(".")
return os.path.join(base_path, goreceliYol)
def portSecici():
#Kullanıcıya mevcut portları bir pencerede seçtirir.
secilenPort = None
def on_select():
nonlocal secilenPort
secilenPort = port_cb.get().split(" ")[0]
#Sadece COMx kısmını al
root.destroy()
root = tk.Tk()
#Pencere başlığı ve boyutları belirlendi.
root.title("Bağlantı Ayarları")
pencereGenislik = 300
pencereYukseklik = 200
# Monitör genişliğini ve yüksekliğini al.
ekranGenislik = root.winfo_screenwidth()
ekranYukseklik = root.winfo_screenheight()
# Orta noktayı hesapla.
merkezX = int(ekranGenislik/2 - pencereGenislik / 2)
merkezY = int(ekranYukseklik/2 - pencereYukseklik / 2)
# Pencereyi konumlandır: "Genişlik x Yükseklik+X+Y" formatında
root.geometry(f'{pencereGenislik}x{pencereYukseklik}+{merkezX}+{merkezY}')
# Hem yatay hem dikey büyütmeyi kapat.
# Kullanıcı pencereyi tam ekran yapamasın.
root.resizable(False, False)
tk.Label(root,
text="Arduino portunu seçin:",
font=("Arial", 10, "bold")
).pack(pady=20)
# Mevcut portları listele
portlar = [f"{p.device} ({p.description})" for p in serial.tools.list_ports.comports()]
if not portlar:
messagebox.showerror("Port Hatası", "Açık COM port bulunamadı!")
sys.exit()
port_cb = ttk.Combobox(root, values=portlar, state="readonly", width=30)
port_cb.pack(pady=5)
port_cb.current(0)
# İlk portu varsayılan seç.
tk.Button(root,
text="Bağlan ve Başlat",
command=on_select,
width=20,
height=2,
font=("Arial", 10)
).pack(pady=20)
root.mainloop()
return secilenPort
portAdi = portSecici()
def portAc():
global port, portAdi
try:
#Port nesnesi yok veya port açık değilse
if port is None or not port.is_open:
port = serial.Serial()
port.port = portAdi
port.baudrate = baudRate
port.dtr = False
port.rts = False
#Arduino resetlenme engellenmeye çalışıldı.
#Arduino'nun RESET ve GND pinleri arasına 10uF'lık
#bir kondansatör takmak resetlenmeyi durdurur.
port.open()
print(f"Port başarıyla açıldı: {port}")
# Port bilgileri konsoldan yazdırıldı.
return True
except Exception as e:
print(f"Hata: Port açılamadı! {e}")
uyari_mesaji_goster("Bağlantı Hatası", "Port açık değil! Lütfen bağlantıyı kontrol edin.")
return False
return True
#Dinamik yeniden bağlanma mantığı kullanılmıştır.
def komutGonder(komut):
global port, portAdi
# 1.adım: Port kapalıysa veya hiç oluşturulmadıysa bağlan.
if port is None or not port.is_open:
# Port o an başka bir program tarafından kullanılıyor olabilir
# veya cihaz çıkarılmış olabilir.
# Programının çökmemesi için try-except bloğu gereklidir.
try:
port = serial.Serial()
port.port = portAdi
port.baudrate = baudRate
port.dtr = False
port.rts = False
#Arduino resetlenme engellenmeye çalışıldı.
#Arduino'nun RESET ve GND pinleri arasına 10uF'lık
#bir kondansatör takmak resetlenmeyi durdurur.
port.open()
time.sleep(0.1)
print(f"Cihaz sonradan algılandı ve port açıldı: {portAdi}")
except Exception:
# Eğer cihaz hala takılı değilse buraya düşer.
pass
# 2.adım: Şimdi portun durumunu kontrol et ve komut gönder.
if port and port.is_open:
# Port o an başka bir program tarafından kullanılıyor olabilir
# veya cihaz çıkarılmış olabilir.
# Programının çökmemesi için try-except bloğu gereklidir.
try:
port.write(komut.encode())
port.flush()
print(f"Komut gönderildi: {komut}")
return True
except Exception as e:
# Gönderim anında bir kopma olursa portu sıfırla ve hata ver.
print(f"Gönderim hatası: {e}")
port.close()
port = None
uyari_mesaji_goster("Bağlantı Hatası", "Cihazla iletişim kesildi. Lütfen kabloyu kontrol edin.")
return False
else:
# Cihaz hala takılmadıysa kullanıcıyı uyar
print("UYARI: Port hala kapalı. Cihaz takılı mı?")
uyari_mesaji_goster("Bağlantı Yok", "Cihaz algılanamadı. Lütfen kabloyu kontrol edin ve tekrar deneyin.")
return False
#Port açık değilse açılan pencerede uyarı mesajı gösterildi.
def uyari_mesaji_goster(baslik, mesaj):
root = tk.Tk()
root.withdraw()
# Ana tkinter penceresini gizle
messagebox.showwarning(baslik, mesaj)
#Diyalog kutusunu sarı ünlem ikonu ile birlikte göster.
root.destroy()
# Pencere kapatılır. Bellek kaynakları serbest bırakılır.
def gorselleriYukle():
"""Tüm görselleri yüklendi ve koordinatları ayarlandı."""
resimler = {}
try:
resimler['arka'] = pygame.image.load(kaynakYolu("arkaresim.png"))
resimler['on1'] = pygame.image.load(kaynakYolu("buton_on.png"))
resimler['off1'] = pygame.image.load(kaynakYolu("buton_off.png"))
resimler['on2'] = pygame.image.load(kaynakYolu("buton_on.png"))
resimler['off2'] = pygame.image.load(kaynakYolu("buton_off.png"))
resimler['kapat'] = pygame.image.load(kaynakYolu("kapat.png"))
# Koordinat atamaları yapıldı.
resimler['on1_rect'] = resimler['on1'].get_rect(topleft=(270, 150))
resimler['off1_rect'] = resimler['off1'].get_rect(topleft=(420, 150))
resimler['on2_rect'] = resimler['on2'].get_rect(topleft=(270, 235))
resimler['off2_rect'] = resimler['off2'].get_rect(topleft=(420, 235))
resimler['kapat_rect'] = resimler['kapat'].get_rect(topleft=(345, 350))
# relay.png dosyasının aynı klasörde olup olmadığının kontrolü yapıldı.
iconDosya = kaynakYolu("relay.png")
if os.path.exists(iconDosya):
pygame.display.set_icon(pygame.image.load(iconDosya))
#Pencere ikonu yüklendi.
return resimler
except Exception as e:
print(f"Görsel yükleme hatası: {e}")
print(f"Uyarı: '{iconDosya}' dosyası bulunamadı. Varsayılan icon kullanılıyor.")
return None
def statikMetinleriHazirla():
"""Fontlar ve metin render işlemleri hazırlandı."""
font1 = pygame.font.SysFont("arial", 64)
font2 = pygame.font.SysFont("arial", 22)
font3 = pygame.font.SysFont("arial", 30)
statikMetinler = [
(font1.render("Röle Kontrol Arayüzü", True, renk), (165, 40)),
(font2.render("www.beyzemiter.com", True, renk), (325, 515)),
(font3.render("1.Kanal", True, renk), (160, 166)),
(font3.render("2.Kanal", True, renk), (160, 251)),
(font2.render("© 2026 İlhan DEMİR", True, renk), (325, 545)),
]
return statikMetinler
def dinamikMetinleriHazirla(r1Durum,r2Durum):
"""Fontlar ve metin render işlemleri hazırlandı."""
fontRoleDurum = pygame.font.SysFont("arial", 24, bold=False)
# Durum yazıları renklendirildi.
# Röleler açıksa durum yazıları yeşil, kapalıysa siyah)
renkRole1 = (0, 255, 0) if r1Durum == "Açık" else (0, 0, 0)
renkRole2 = (0, 255, 0) if r2Durum == "Açık" else (0, 0, 0)
dinamikMetinler = [
# Röle durum bilgileri
(fontRoleDurum.render(f"Durum: {r1Durum}", True, renkRole1), (580, 166)),
(fontRoleDurum.render(f"Durum: {r2Durum}", True, renkRole2), (580, 251))
]
return dinamikMetinler
def ekraniCiz(resimler, statikMetinler, dinamikMetinler):
#Tüm görseller ekrana basıldı.
ekran.blit(resimler['arka'], (0, 0))
ekran.blit(resimler['on1'], resimler['on1_rect'])
ekran.blit(resimler['off1'], resimler['off1_rect'])
ekran.blit(resimler['on2'], resimler['on2_rect'])
ekran.blit(resimler['off2'], resimler['off2_rect'])
ekran.blit(resimler['kapat'], resimler['kapat_rect'])
#Tüm yazılar ekrana basıldı.
for yazi, koordinat in statikMetinler:
ekran.blit(yazi, koordinat)
for yazi, koordinat in dinamikMetinler:
ekran.blit(yazi, koordinat)
# Ana program
resimler = gorselleriYukle()
statikMetinler = statikMetinleriHazirla()
dinamikMetinler = dinamikMetinleriHazirla(role1Durum, role2Durum)
portAc()
saat = pygame.time.Clock()
durum = True
while durum:
saat.tick(60)
#Döngü hızı saniyede 60 kez.
#Programın işlemci çekirdeğini şişirmesi engellendi.
fare = pygame.mouse.get_pos()
#İmleç koordinatları alındı.
#fare[0] genişlik (x), fare[1] yükseklik (y)
#Bu döngü olmazsa pencere açıldığı gibi saniyeler içinde kapanır.
#Döngü sayesinde X butonuna basana kadar pencere aktif kalır.
for olay in pygame.event.get():
#Pencerenin X butonuna tıklanmış mı?
if olay.type == pygame.QUIT:
durum = False
#Farenin sol tuşuna tıklanmış mı?
if olay.type == pygame.MOUSEBUTTONDOWN:
fareKonum=olay.pos
#Tıklanan konuma göre komut gönder.
# Röle 1 açık
if resimler['on1_rect'].collidepoint(fareKonum):
if komutGonder('a'):
# Sadece gönderim başarılıysa durumu değiştir.
role1Durum = "Açık"
dinamikMetinler = dinamikMetinleriHazirla(role1Durum, role2Durum)
print("Röle 1 çalışıyor.")
# Röle 1 kapalı
elif resimler['off1_rect'].collidepoint(fareKonum):
if komutGonder('b'):
# Sadece gönderim başarılıysa durumu değiştir.
role1Durum = "Kapalı"
dinamikMetinler = dinamikMetinleriHazirla(role1Durum, role2Durum)
print("Röle 1 kapalı.")
# Röle 2 açık
elif resimler['on2_rect'].collidepoint(fareKonum):
if komutGonder('c'):
# Sadece gönderim başarılıysa durumu değiştir.
role2Durum = "Açık"
dinamikMetinler = dinamikMetinleriHazirla(role1Durum, role2Durum)
print("Röle 2 çalışıyor.")
# Röle 2 kapalı
elif resimler['off2_rect'].collidepoint(fareKonum):
if komutGonder('d'):
# Sadece gönderim başarılıysa durumu değiştir.
role2Durum = "Kapalı"
dinamikMetinler = dinamikMetinleriHazirla(role1Durum, role2Durum)
print("Röle 2 kapalı.")
# Kapat butonu
elif resimler['kapat_rect'].collidepoint(fareKonum):
durum = False
#Tüm görseller ve yazılar ekrana basıldı.
ekraniCiz(resimler, statikMetinler, dinamikMetinler)
#Yapılan değişiklikler ekrana yansıtıldı.
pygame.display.flip()
#pygame.display.update()
# Çıkış işlemleri; çıkışta port ve pygame modülü kapatıldı.
if port and port.is_open:
port.close()
print("Port kapandı.")
print("Programdan çıkış yapıldı.")
pygame.quit()
sys.exit()
Uygulamaya Ait Arduino Kodu
/*
Uygulama Adı : 2 kanal 5V röle modülü uygulaması
Açıklama : Röle modülü lojik 0 ile tetiklenir.
Tarih : 01 Mayıs 2026
Yazan : İlhan DEMİR
*/
#define in1 2
#define in2 3
char gelenKomut;
void setup() {
pinMode(in1, OUTPUT);
pinMode(in2, OUTPUT);
digitalWrite(in1, HIGH);
digitalWrite(in2, HIGH);
//Başlangıçta röleler çalışmıyor.
Serial.begin(9600);
//UART donanımsal seri haberleşme 9600 baud hızla başlatıldı.
}
void loop() {
if (Serial.available() > 0) {
gelenKomut = Serial.read();
//Gelen veri varsa oku ve değişkende sakla.
if (gelenKomut == 'a') {
//Gelen komut "a" ise;
digitalWrite(in1, LOW);
Serial.println("Röle 1 çalışıyor.");
} else if (gelenKomut == 'b') {
//Gelen komut "b" ise;
digitalWrite(in1, HIGH);
Serial.println("Röle 1 kapalı");
} else if (gelenKomut == 'c') {
//Gelen komut "c" ise;
digitalWrite(in2, LOW);
Serial.println("Röle 2 çalışıyor.");
} else if (gelenKomut == 'd') {
//Gelen komut "d" ise;
digitalWrite(in2, HIGH);
Serial.println("Röle 2 kapalı");
}
}
}
Bu internet sitesi içeriğinde yer alan tüm eserler (yazı, resim, görüntü, fotoğraf, video, müzik vb.) İlhan DEMİR'e ait olup, 5846 sayılı Fikir ve Sanat Eserleri Kanunu ve 5237 sayılı Türk Ceza Kanunu kapsamında korunmaktadır. Bu hakları ihlal eden kişiler, 5846 sayılı Fikir ve Sanat eserleri Kanunu ve 5237 sayılı Türk Ceza Kanununda yer alan hukuki ve cezai yaptırımlara tabi olurlar. İlhan DEMİR, yasal işlem başlatma hakkına sahiptir.

BİR CEVAP YAZ