Seri Protokoller
TEKNİK REHBER SERİ PROTOKOLLER UART 2026

UART protokolü
ve serial terminal.

Bootloader konsolundan GSM modeme, debug porttan RS-485 ağına — UART her yerde. stty, minicom, picocom ve pyserial ile tam kontrol.

00 UART temelleri

UART (Universal Asynchronous Receiver/Transmitter) — saat sinyali olmadan, önceden anlaşılmış baud rate ile çalışan asenkron seri haberleşme.

  TX ──────────────────────────────► RX
  RX ◄────────────────────────────── TX
  GND ─────────────────────────────── GND

  Frame yapısı:
  │ START │ D0 │ D1 │ D2 │ D3 │ D4 │ D5 │ D6 │ D7 │ [PARITY] │ STOP │
  │  (0)  │                 8 data bit                         │ (1)  │
    

Baud rate, data bits, parity, stop bits

UART parametrelerini her iki tarafın aynı şekilde yapılandırması gerekir. En yaygın ayar: 115200 8N1 (115200 baud, 8 data bit, No parity, 1 stop bit).

ParametreYaygın değerlerAçıklama
Baud rate9600, 19200, 38400, 57600, 115200, 230400, 460800, 921600Saniyedeki sembol sayısı (UART'ta 1 sembol = 1 bit)
Data bits7, 8Her frame'deki veri bit sayısı. 8 universaldir.
ParityNone (N), Even (E), Odd (O)Hata tespiti için. Çoğu modern kullanımda N.
Stop bits1, 2Frame sonu boşluk süresi. Genellikle 1.
Flow controlNone, RTS/CTS (hardware), XON/XOFF (software)Veri akış denetimi. Bootloader konsollarda genellikle None.

RS-232 vs TTL vs RS-485 gerilim seviyeleri

StandartLogic-1 (mark)Logic-0 (space)MesafeKullanım
TTL (3.3V)3.3V0V<1mSoC GPIO → USB-TTL dönüştürücü
TTL (5V)5V0V<1mArduino, eski MCU'lar
RS-232-3V ile -15V+3V ile +15V<15mDB9 konnektör, eski PC com port
RS-485+1.5V differansiyel (A-B)-1.5V differansiyel (A-B)1200mModbus, sanayi otomasyonu
UYARI

Raspberry Pi / BeagleBone gibi kartların UART pinleri 3.3V TTL seviyesinde çalışır. Doğrudan RS-232 cihaza bağlamak SoC'yi kalıcı olarak hasar verebilir. MAX3232 veya benzeri seviye dönüştürücü kullan.

01 Linux serial subsystem

Linux tty (TeleTYpe) subsystem, UART donanımını /dev/ttyXXX aygıt dosyaları üzerinden kullanıcıya sunar.

/dev/ttyS0–S3PC'deki yerleşik RS-232 seri portlar (16550 UART çipi). 8250/16550 driver.
/dev/ttyUSB0USB-TTL dönüştürücü (CP2102, CH340, FTDI FT232). usb_serial driver.
/dev/ttyAMA0ARM PrimeCell UART (Raspberry Pi donanım UART). pl011 driver.
/dev/ttyACM0USB CDC ACM (Arduino gibi kendi USB-serial içeren cihazlar).
/dev/serial0Raspberry Pi'da symlink: aktif UART'a işaret eder (ttyAMA0 veya ttyS0).
bash — port kontrolü
# Mevcut seri portları listele:
ls /dev/tty*

# USB cihaz tanımlama:
dmesg | grep ttyUSB
# [ 14.2] usb 1-1.2: cp210x converter now attached to ttyUSB0

# USB seri cihaz bilgisi:
udevadm info --query=all --name=/dev/ttyUSB0

# Seri porta erişim izni:
ls -la /dev/ttyUSB0
# crw-rw---- 1 root dialout 188, 0 Jan  1 00:03 /dev/ttyUSB0

# Kullanıcıyı dialout grubuna ekle:
sudo usermod -aG dialout $USER

udev rules ile kalıcı cihaz adı

USB-TTL dönüştürücüler her takıldığında farklı numara alabilir (ttyUSB0, ttyUSB1 ...). udev kuralı ile sabit isim verilebilir.

/etc/udev/rules.d/99-serial.rules
# FTDI FT232 tabanlı cihazı sabit isme bağla:
SUBSYSTEM=="tty", ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6001", \
  ATTRS{serial}=="A50285BI", SYMLINK+="ttyGSM"

# CP2102 tabanlı cihaz:
SUBSYSTEM=="tty", ATTRS{idVendor}=="10c4", ATTRS{idProduct}=="ea60", \
  SYMLINK+="ttyESP"
bash
# Cihazın idVendor/idProduct/serial bilgisini öğren:
udevadm info -a -n /dev/ttyUSB0 | grep -E 'idVendor|idProduct|serial'

# Kuralları yeniden yükle:
sudo udevadm control --reload-rules
sudo udevadm trigger

02 stty — baud rate ve ham mod

stty (set tty) — seri port parametrelerini komut satırından yapılandırır. Hem interaktif hem script kullanım için idealdir.

bash
# Mevcut tty ayarlarını görüntüle:
stty -a
stty -F /dev/ttyUSB0 -a

# Baud rate ayarla (115200 8N1):
stty -F /dev/ttyUSB0 115200

# Tam parametre seti:
stty -F /dev/ttyUSB0 115200 cs8 -parenb -cstopb -crtscts
#              ↑baud  ↑8bit ↑noparity ↑1stopbit ↑no hw flow ctrl

# Ham (raw) mod — line editing, echo, signal karakterleri devre dışı:
stty -F /dev/ttyUSB0 raw

# Script'te okuma için: stty ile ham moda al, cat ile oku:
stty -F /dev/ttyUSB0 9600 raw -echo
cat /dev/ttyUSB0 &      # arka planda oku
echo -e "AT\r" > /dev/ttyUSB0  # yaz
cs88 data bit (cs7 = 7 bit)
-parenbParity devre dışı (parenb = enable parity)
-cstopb1 stop bit (cstopb = 2 stop bit)
-crtsctsHardware flow control devre dışı (crtscts = enable RTS/CTS)
rawHam mod: tüm satır işleme kapat. Veri olduğu gibi iletilir.
-echoGirilen karakterleri geri yansıtma (echo kapat)
min 1 time 5Ham modda: en az 1 karakter veya 0.5 sn sonra read() dönsün
bash — stty ile basit terminal
# stty ile basit iki yönlü terminal (ctrl-c ile çık):
stty -F /dev/ttyUSB0 115200 raw -echo
cat /dev/ttyUSB0 &
PID=$!
while read -r line; do
    printf "%s\r\n" "$line" > /dev/ttyUSB0
done
kill $PID

03 minicom — kurulum ve yapılandırma

minicom — gelişmiş terminal emülatörü. Oturum capture, makro, XMODEM/YMODEM dosya transferi destekler.

bash — kurulum
sudo apt install minicom

İlk yapılandırma

bash
# Yapılandırma menüsünü aç (root gerekebilir):
sudo minicom -s

# Menü: Serial port setup → (A) Serial Device: /dev/ttyUSB0
#                        → (E) Bps/Par/Bits: 115200 8N1
#                        → (F) Hardware Flow Control: No
# Menü: Save setup as dfl  (varsayılan olarak kaydet)
# Menü: Exit from Minicom

# Kaydedilmiş yapılandırmayla bağlan:
minicom

# Belirli cihaza doğrudan bağlan:
minicom -D /dev/ttyUSB0 -b 115200

# Echo açık (gönderdiğini gör):
minicom -D /dev/ttyUSB0 -b 115200 -e

# Renkli çıktı:
minicom -c on -D /dev/ttyUSB0

minicom kısayolları

Kısayolİşlev
Ctrl-A ZYardım menüsünü aç
Ctrl-A Xminicom'dan çık
Ctrl-A CEkranı temizle
Ctrl-A LCapture (oturumu dosyaya kaydet)
Ctrl-A WSatır kaydırma aç/kapat
Ctrl-A SDosya gönder (XMODEM/YMODEM/ZMODEM)
Ctrl-A RDosya al
Ctrl-A OYapılandırma menüsü
Ctrl-A ELocal echo aç/kapat
bash — script modunda kullanım
# Script'ten minicom'a komut gönder (expect tarzı):
# minicom'u capture modunda başlat ve çıktıyı dosyaya al:
minicom -D /dev/ttyUSB0 -b 115200 -C /tmp/capture.txt -S script.txt

# script.txt içeriği (minicom script formatı):
# send "AT\r"
# sleep 1
# send "AT+CIMI\r"
# sleep 1
# ! killall minicom

04 picocom — sade alternatif

picocom — minimal terminal emülatörü. Yapılandırma dosyası gerektirmez, argümanlarla anında bağlanır. Embedded geliştirme için idealdir.

bash
sudo apt install picocom

# Temel kullanım:
picocom -b 115200 /dev/ttyUSB0

# 8N1, hardware flow control yok:
picocom -b 115200 --parity n --databits 8 --flow n /dev/ttyUSB0

# CR/LF dönüşümü (her CR için LF ekle — bazı bootloader'lar için):
picocom -b 115200 --omap crcrlf /dev/ttyUSB0

# İki yönlü CR/LF dönüşüm:
picocom -b 115200 --omap crcrlf --imap lfcrlf /dev/ttyUSB0

# Logfile al:
picocom -b 115200 -l --logfile /tmp/uart.log /dev/ttyUSB0

picocom kısayolları

Kısayolİşlev
Ctrl-A Ctrl-Xpicocom'dan çık
Ctrl-A Ctrl-QPort'u kapatmadan çık
Ctrl-A Ctrl-UBaud rate artır
Ctrl-A Ctrl-DBaud rate azalt
Ctrl-A Ctrl-SDosya gönder (ASCII, XMODEM, YMODEM seç)
Ctrl-A Ctrl-RDosya al
Ctrl-A Ctrl-CHex display aç/kapat
Ctrl-A Ctrl-LEkranı temizle

05 screen ve cu

screen ve cu — seri porta bağlanmak için ek yazılım yüklenmeden kullanılabilen araçlar.

bash — screen
# screen ile seri porta bağlan:
screen /dev/ttyUSB0 115200

# Özel baud ve parametreler:
screen /dev/ttyUSB0 115200,cs8,-parenb,-cstopb

# screen'den çıkış:
# Ctrl-A K (kill) → y
# veya: Ctrl-A \  → y

# screen oturumunu yeniden bağlamak (detach/attach):
# Ctrl-A D  → detach
screen -r   # tekrar bağlan

# Log kaydet:
# Ctrl-A H → screenlog.0 dosyasına log başlar
bash — cu (UUCP)
# cu ile bağlan (uucp paketi içinde gelir):
cu -l /dev/ttyUSB0 -s 115200

# ~. ile bağlantıyı kes (tilde + nokta)
NOT

screen'in seri port kullanımı bir yan özelliktir; temel amacı terminal multiplexer'dır. Uzun süre açık kalacak seri konsol oturumları için (detach ve sonra tekrar bağlanma ihtiyacı olan durumlar) screen kullanışlıdır. Sadece seri bağlantı için picocom daha sade bir seçenektir.

06 Python ile serial: pyserial

pyserial — Python'dan seri porta erişimin standart kütüphanesi. Linux, macOS ve Windows üzerinde tutarlı çalışır.

bash — kurulum
pip3 install pyserial
# veya:
sudo apt install python3-serial
serial_basic.py
import serial
import time

# Port aç:
ser = serial.Serial(
    port='/dev/ttyUSB0',
    baudrate=115200,
    bytesize=serial.EIGHTBITS,
    parity=serial.PARITY_NONE,
    stopbits=serial.STOPBITS_ONE,
    timeout=1.0,           # read() için timeout (saniye)
    write_timeout=1.0,
    xonxoff=False,         # software flow control
    rtscts=False,          # hardware flow control
)

print(f"Port: {ser.name} açık: {ser.is_open}")

# Tek satır yaz (CR+LF ile biter):
ser.write(b'AT\r\n')

# Yanıtı satır satır oku:
line = ser.readline()      # '\n' bulana kadar veya timeout
print(f"Yanıt: {line.decode('ascii', errors='replace').strip()}")

# N bayt oku:
raw = ser.read(10)
print(f"10 bayt: {raw.hex(' ')}")

# Tampon temizle:
ser.reset_input_buffer()    # rx tampon temizle
ser.reset_output_buffer()   # tx tampon temizle

ser.close()
serial_readline.py — güvenli okuma döngüsü
import serial
import threading

def reader(ser, stop_event):
    while not stop_event.is_set():
        try:
            line = ser.readline()
            if line:
                print(f"<< {line.decode('utf-8', errors='replace').rstrip()}")
        except serial.SerialException as e:
            print(f"Serial hata: {e}")
            break

with serial.Serial('/dev/ttyUSB0', 115200, timeout=0.1) as ser:
    stop = threading.Event()
    t = threading.Thread(target=reader, args=(ser, stop), daemon=True)
    t.start()

    try:
        while True:
            cmd = input(">> ")
            ser.write((cmd + '\r\n').encode())
    except KeyboardInterrupt:
        stop.set()
read(n)En fazla n bayt oku. Timeout dolana kadar bekler. Gelen veri n'den azsa kısmi veri döner.
read_until(expected)expected byte sequence görene kadar oku. Varsayılan b'\n'.
readline()'\n' görene veya timeout dolana kadar oku. read_until(b'\n') ile eşdeğer.
write(data)bytes yaz. Python string değil bytes gönder: b"AT\r\n" veya "AT\r\n".encode()
in_waitingOkunmayı bekleyen bayt sayısı. Polling için kullanışlı.
flush()TX tamponunun boşalmasını bekle.

07 Pratik: AT komut seti

AT komutları (Hayes komutları) GSM/LTE modemler, ESP8266/ESP32 WiFi modülleri, Bluetooth modemler ve birçok embedded cihazla haberleşmede kullanılır.

Temel AT komutları

KomutAçıklamaBeklenen yanıt
ATModem canlı mı kontrolOK
ATIModem kimliği / firmwareModel string + OK
AT+CGSNIMEI numarası15 haneli IMEI + OK
AT+CIMIIMSI numarası (SIM)15 haneli IMSI + OK
AT+CSQSinyal kalitesi+CSQ: rssi,ber
AT+CREG?Ağ kayıt durumu+CREG: 0,1 (kayıtlı)
AT+COPS?Operatör adı+COPS: 0,0,"Turkcell"
ATE0Echo kapatOK
ATE1Echo açOK
ATZFabrika ayarlarına dönOK
at_modem.py
import serial
import time

def at_command(ser, cmd, timeout=2.0, expected="OK"):
    """AT komutu gönder ve yanıtı topla."""
    ser.reset_input_buffer()
    ser.write((cmd + "\r\n").encode("ascii"))

    response = []
    deadline = time.time() + timeout
    while time.time() < deadline:
        line = ser.readline().decode("ascii", errors="replace").strip()
        if line:
            response.append(line)
        if line in (expected, "ERROR", "+CME ERROR"):
            break
    return response

with serial.Serial("/dev/ttyUSB0", 115200, timeout=0.2) as ser:
    # Echo kapat:
    at_command(ser, "ATE0")

    # Modem testi:
    resp = at_command(ser, "AT")
    print(f"AT: {resp}")

    # IMEI:
    resp = at_command(ser, "AT+CGSN")
    print(f"IMEI: {resp}")

    # Sinyal kalitesi:
    resp = at_command(ser, "AT+CSQ")
    for line in resp:
        if line.startswith("+CSQ:"):
            parts = line.split(":")[1].strip().split(",")
            rssi = int(parts[0])
            dbm  = -113 + rssi * 2 if rssi < 99 else "bilinmiyor"
            print(f"Sinyal: {rssi} ({dbm} dBm)")

ESP8266 AT komutları

bash — picocom ile ESP8266
picocom -b 115200 --omap crcrlf /dev/ttyUSB0

# ESP8266 AT komutları:
# AT           → OK
# AT+GMR       → firmware versiyonu
# AT+CWMODE=1  → Station mode (WiFi client)
# AT+CWLAP     → Çevredeki WiFi ağlarını listele
# AT+CWJAP="SSID","password"  → WiFi'ye bağlan
# AT+CIFSR     → IP adresi al

08 RS-485 — half-duplex multi-drop

RS-485 — differansiyel, yarı çift yönlü (half-duplex) multi-drop bus. Tek çift kablo ile 32 cihaza, 1200 metreye kadar 10 Mbps veri aktarımı.

  Master          RS-485 Bus          Slave 1  Slave 2  Slave N
  ┌──────┐                           ┌──────┐ ┌──────┐ ┌──────┐
  │  TX  ├──A(+)──────────────────────┤      ├─┤      ├─┤      │
  │  RX  ├──B(-)──────────────────────┤      ├─┤      ├─┤      │
  │  DE  │  120Ω (terminal)   120Ω   └──────┘ └──────┘ └──────┘
  └──────┘  (her iki uçta)
    

RS-485'te sadece bir cihaz aynı anda konuşabilir. UART→RS-485 dönüştürücüler için bir DE (Driver Enable) pini bulunur; bu pin yüksekken TX, düşükken RX modu aktiftir.

Linux'ta RS-485 ayarı: TIOCSRS485

rs485_enable.c
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <linux/serial.h>

int rs485_enable(const char *dev)
{
    int fd = open(dev, O_RDWR | O_NOCTTY);
    if (fd < 0) { perror("open"); return -1; }

    struct serial_rs485 rs485conf = {0};
    rs485conf.flags |= SER_RS485_ENABLED;        /* RS-485 modunu aktifleştir */
    rs485conf.flags |= SER_RS485_RTS_ON_SEND;    /* TX sırasında RTS/DE yüksek */
    rs485conf.flags &= ~SER_RS485_RTS_AFTER_SEND; /* TX sonrası DE düşük */
    rs485conf.delay_rts_before_send = 0;         /* TX öncesi gecikme (ms) */
    rs485conf.delay_rts_after_send  = 0;         /* TX sonrası gecikme (ms) */

    if (ioctl(fd, TIOCSRS485, &rs485conf) < 0) {
        perror("TIOCSRS485");
        close(fd);
        return -1;
    }

    return fd;  /* fd'yi normal UART gibi kullan */
}

int main(void)
{
    int fd = rs485_enable("/dev/ttyS1");
    if (fd < 0) return 1;

    /* RS-485 üzerinde Modbus RTU çerçevesi gönder (örnek): */
    unsigned char frame[] = { 0x01, 0x03, 0x00, 0x00, 0x00, 0x0A, 0xC5, 0xCD };
    write(fd, frame, sizeof(frame));

    unsigned char buf[64];
    int n = read(fd, buf, sizeof(buf));
    if (n > 0) {
        for (int i = 0; i < n; i++)
            printf("%02X ", buf[i]);
        printf("\n");
    }

    close(fd);
    return 0;
}

Termination direnci

RS-485 bus'ının her iki ucuna 120Ω direnç bağlanmalıdır. Terminasyon eksikliği yansıma (reflection) sorunlarına yol açarak veri bozulmasına neden olur. Sadece iki uçta (en başta ve en sonda) direnç olmalıdır; ortaya bağlanan cihazlara terminasyon direnci eklenmez.

SorunNedenÇözüm
Çerçeve hataları (framing error)Baud rate uyumsuzluğuHer iki taraftaki baud'u eşleştir
Veri kayıplarıDE timing yetersizdelay_rts_before_send artır
Echo (kendi gönderdiğini okuma)Half-duplex; RX aktifSER_RS485_RX_DURING_TX bayrağını kaldır
Uzun kablo hatalarıTermination eksik, cap. yük fazla120Ω terminal ekle, kablo kalitesini artır