Gömülü Linux ve TCP/IP Üzerinden Endüstriyel 7-Segment Ekran Kontrol Sistemi

Yayınlanma Tarihi: 15 August 2026

Sistemin Çalışmasını İzleyin:

Bu endüstriyel otomasyon uygulamasında, RDF-GW2 Embedded Linux Ağ Geçidi üzerinde çalışan C çekirdeği, Lua betik motoru ve TCP/IP soket haberleşmesi kullanarak 4 haneli endüstriyel 7-segment ekran panelinin gerçek zamanlı ve uzaktan kontrolünü gerçekleştiriyoruz. Sistem, kesintisiz hot-reloading (canlı kod güncelleme) ve yüksek hızlı shared memory (paylaşımlı bellek) altyapısı sunar.

Sistem Mimarisi ve Yazılım Katmanları

Saha paneli kontrol sistemi, yüksek performans, modülerlik ve canlı kod geliştirme kolaylığı sağlayacak şekilde katmanlı bir yazılım mimarisiyle tasarlanmıştır:

  • RDF-GW2 (Embedded Linux Gateway): Sistem merkezinde yer alan Linux tabanlı ağ geçidi cihazı, tüm donanım sürücülerini ve yüksek seviyeli uygulama servislerini çalıştırır.
  • C Sürücü Çekirdeği (Segment Driver): Donanım seviyesindeki shift-register entegrelerini ve dijital pin matrisini doğrudan yönlendirerek 7-segment karakterlerin (ve ondalık noktaların) yüksek hızda taranmasını sağlar.
  • Paylaşımlı Bellek (/dev/shm IPC): C sürücü motoru ile Lua uygulama katmanı arasındaki veri transferini sıfır gecikmeyle yürütmek için Linux RAM tabanlı `/dev/shm` dosya sistemini kullanır.
  • Kesintisiz Lua Motoru & Hot-Reloading: `script.lua` dosyası C motoru tarafından `mtime` takibi ile izlenir. Kod üzerinde yapılan değişiklikler servis kesintisi yaşanmadan anında canlı sisteme aktarılır.
  • TCP Soket Sunucusu & Python İstemci: Port 5000 üzerinden dinleme yapan non-blocking TCP sunucusu sayesinde uzaktaki PC, PLC veya SCADA sistemleri (Python istemcisi) ağ üzerinden ekrana anlık karakter dizileri gönderebilir.

Öne Çıkan Özellikler ve Çalışma Mantığı

Canlı Kod Güncelleme (Hot-Reloading)

VS Code üzerinden SFTP ile cihaza aktarılan yeni Lua kodları, C host programı tarafından anında algılanıp yeniden yüklenir; TCP soket bağlantısı kopmadan veya sistem yeniden başlatılmadan çalışma devam eder.

Ağ Üzerinden TCP Soket Kontrolü

Python veya herhangi bir TCP istemcisi üzerinden gönderilen `"12.34"`, `"A.B.C.D."` gibi metin verileri otomatik ayrıştırılarak 4 haneli ekran panelinde anında görüntülenir.

Ondalık Nokta (Decimal Point) Desteği

Ayrıştırma mantığı sayesinde gelen dizideki nokta `.` karakterleri bağımsız bir hane kaplamaz, ilişkili olduğu sayısal hanenin ondalık LED segmentini (`Bit 7 / 0x80`) otomatik aktif eder.

Yüksek Hızlı Paylaşımlı Bellek (IPC)

Linux `/dev/shm` (Shared Memory) yapısı sayesinde disk I/O yükü oluşmaz; Lua betiği ve C sürücüsü RAM üzerinden mikrosaniyeler içinde haberleşir.

Uygulama Kod Örnekleri

Aşağıda IPC bellek yazma arayüzü, non-blocking TCP sunucu yapısı ve istemci haberleşmesini sağlayan örnek kod blokları yer almaktadır:

1. Doğrudan IPC Bellek Yazımı (Temel Lua Örneği)

Bu başlangıç betiği, karakter verilerini C sürücü çekirdeği tarafından izlenen RAM tabanlı /dev/shm/ düğümlerine doğrudan yazar:

-- script.lua
print("--- 7-Segment Control ---")

local function io_write(display_node, payload)
    local path = "/dev/shm/" .. display_node .. "_out"
    local file = io.open(path, "w")
    if file then
        file:write(tostring(payload))
        file:close()
    else
        print("Error: Could not write to target shared memory " .. path)
    end
end

local display1 = "display1"
local display2 = "display2"
local display3 = "display3"
local display4 = "display4"

io_write(display1, "1")
io_write(display2, " ")
io_write(display3, " ")
io_write(display4, " ")
--os.execute("sleep 1")

2. Non-Blocking TCP Ekran Sunucusu (Gelişmiş Lua Servisi)

Port 5000 üzerinde çalışan bu servis, her döngüde istemci bağlantılarını kontrol eder, ondalık nokta konumlarını otomatik işler ve paylaşımlı belleği günceller:

-- /root/script.lua
local socket = require("socket")

print("--- Starting Non-Blocking TCP Display Server (Port 5000) ---")

-- Bind TCP server once on load
local server = assert(socket.bind("*", 5000))
server:settimeout(0) -- Non-blocking check

local function io_write(display_node, payload)
    local path = "/dev/shm/" .. display_node .. "_out"
    local file = io.open(path, "w")
    if file then
        file:write(tostring(payload))
        file:close()
    else
        print("Error: Could not write to " .. path)
    end
end

local function update_displays(text)
    local displays = {"display1", "display2", "display3", "display4"}
    local char_idx = 1
    local text_len = #text

    for d = 1, 4 do
        if char_idx <= text_len then
            local char = text:sub(char_idx, char_idx)
            local payload = char

            if char_idx + 1 <= text_len and text:sub(char_idx + 1, char_idx + 1) == "." then
                payload = payload .. "."
                char_idx = char_idx + 2
            else
                char_idx = char_idx + 1
            end

            io_write(displays[d], payload)
        else
            io_write(displays[d], " ")
        end
    end
end

-- This function will be called by C on every loop tick
function step()
    local client = server:accept()
    if client then
        client:settimeout(0.5)
        local line, err = client:receive()
        if not err and line then
            print("Received command: " .. line)
            update_displays(line)
            client:send("OK\n")
        end
        client:close()
    end
end

3. Uzaktan TCP Python İstemcisi

RDF-GW2 Gateway cihazına TCP üzerinden bağlanıp komut gönderen hafif Python betiği (örneğin: python send_display.py "12.34"):

import socket
import sys

GATEWAY_IP = "192.168.1.50"
GATEWAY_PORT = 5000

def send_to_display(text: str):
    """
    Sends a string payload over TCP to the 7-segment Gateway.
    Examples:
      - "1234"   -> Displays 1, 2, 3, 4
      - "1.234"  -> Displays 1. on segment 1, 2, 3, 4 on rest
      - "A B C"  -> Displays A, space, B, space
    """
    try:
        # Create TCP/IP socket
        with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as client:
            client.settimeout(2.0)
            client.connect((GATEWAY_IP, GATEWAY_PORT))
            
            # Send message terminated with a newline
            message = text + "\n"
            client.sendall(message.encode('utf-8'))
            
            # Wait for acknowledgement from Gateway
            response = client.recv(1024).decode('utf-8')
            print(f"Gateway Response: {response.strip()}")

    except Exception as e:
        print(f"Error communicating with Gateway ({GATEWAY_IP}): {e}")

if __name__ == "__main__":
    if len(sys.argv) > 1:
        # Pass command line argument if provided: python send_display.py "12.34"
        display_text = sys.argv[1]
    else:
        # Default test string
        display_text = "0050"

    print(f"Sending '{display_text}' to 7-Segment Gateway ({GATEWAY_IP})...")
    send_to_display(display_text)

Geleneksel sabit yazılımlı gösterge panellerinin aksine, esnek Linux mimarisi ve uzaktan TCP haberleşmesi sayesinde bu çözüm endüstriyel sahalarda dinamik durum göstergesi, sayaç ve telemetri paneli olarak kolayca entegre edilebilir.



Proje Özeti
Sektör: Endüstriyel Otomasyon & Saha Göstergeleri
Haberleşme: TCP/IP Socket (Port 5000) & Shared Memory (/dev/shm)
Yazılım Dilleri: Embedded C, LuaScript, Python 3
Özellik: Live Hot-Reloading, Non-Blocking Polling
Donanım: RDF-GW2 Linux Gateway, 4-Digit 7-Segment Panel