Skip to content

Latest commit

 

History

History
414 lines (326 loc) · 20.4 KB

File metadata and controls

414 lines (326 loc) · 20.4 KB

python-esp-bridge

ESP32'yi USB veya Bluetooth üzerinden Raspberry Pi'ye ya da herhangi bir bilgisayara bağlayın; GPIO, PWM, ADC, DAC, kapasitif dokunma, I2C, SPI, ek UART'lar, RMT darbe dizileri (NeoPixel, IR, DHT, ultrasonik sensörler, step motorlar), 1-Wire, CAN bus, I2S ses, dosyalar (LittleFS/SD), NVS depolama, derin uyku, Wi-Fi (ESP32 radyosu üzerinden TCP/UDP soketleri dahil), Ethernet, kamera, BLE ve ESP-NOW dahil tüm ESP32 çevre birimlerini Python'dan canlı olarak kullanın. Firmware güncellemeleri de aynı bağlantı üzerinden yapılır. Bridge firmware'ini bir kez yükleyin; sonrasında host tarafında her şey Python'dır. Her proje için yeniden flash etmeye gerek yoktur.

Tasarım kuralı basit: firmware yalnızca en küçük donanım yapı taşlarını sunar; cihaz protokolleri (WS2812 zamanlaması, NEC IR, DHT çözümleme, 1-Wire arama, step motor rampaları) okunması, test edilmesi ve genişletilmesi kolay olduğu için Python tarafında uygulanır.

┌────────────────┐  USB serial (≤2 Mbaud) veya BLE  ┌─────────────────────┐
│ Pi / PC        │ ───────────────────────────────► │ ESP32 (bridge fw)   │
│ Python:        │   binary protocol, COBS+CRC16    │ FreeRTOS tasks:     │
│  espbridge     │ ◄─────────────────────────────── │  tx / rx / network  │
└────────────────┘        yanıtlar + async olaylar  └─────────────────────┘

Oled

Hızlı başlangıç

Raspberry Pi OS, Linux, Windows ve macOS üzerinde çalışır. Python ≥ 3.11 gerekir.

  1. Firmware'i bir kez flash edin. Arduino IDE şart değil; paketle gelen hazır firmware'i doğrudan host bilgisayardan yükleyebilirsiniz. Komut seri portları listeler, siz birini seçersiniz ve esptool ile Huge APP imajını yazar:

    uvx --from "python-esp-bridge[flash]" flash   # uv ile kurmadan çalıştırma

    Kendiniz derlemek isterseniz Arduino IDE Library Manager'dan python esp bridge kütüphanesini kurun, File → Examples → python esp bridge → Bridge örneğini açın, partition scheme olarak Huge APP seçin ve Upload'a basın. Sketch'in tamamı EspBridge.begin(); çağrısından ibarettir. Ayrıntılar: FIRMWARE.md.

  2. Python kütüphanesini Pi'ye ya da PC'ye kurun. pip ile:

    pip install python-esp-bridge            # USB + Bluetooth birlikte gelir
    pip install "python-esp-bridge[oled]"    # + OLED ekranlar için Pillow
    pip install "python-esp-bridge[mcp]"     # + MCP sunucusu (espbridge-mcp)
    pip install "python-esp-bridge[flash]"   # + `espbridge flash` için esptool

    ...veya uv ile:

    uv add python-esp-bridge                 # uv projesine ekler (USB + Bluetooth)
    uv add "python-esp-bridge[oled]"         # ekstra paketle (oled / mcp / all)
    uv pip install python-esp-bridge         # ya da aktif ortama kurar

    Bluetooth ek paket gerektirmeden çalışır. Eski [ble] ekstra seçeneği, geriye dönük uyumluluk için etkisiz olarak korunur.

  3. Başlayın:

    from espbridge import Bridge
    
    with Bridge() as esp:                      # önce Bluetooth, olmazsa USB serial
        print(esp.info)                        # çip, MAC, yetenekler
    
        esp.gpio.mode(2, "output")             # RPi GPIO gibi, ama ESP32 üstünde
        esp.gpio.write(2, 1)                    # pinin geri okunan seviyesini döndürür
        esp.gpio.write(2, 1, verify=True)      # yazma tutmadıysa hata verir
        print(esp.adc.read_mv(34), "mV")
        esp.dac.write(25, 128)                 # gerçek analog çıkış (klasik ESP32)
        esp.pwm.servo(13, angle=90)
    
        esp.i2c.init(sda=21, scl=22)
        print([hex(a) for a in esp.i2c.scan()])
    
        esp.wifi.connect("ssid", "password")   # ESP32'nin radyosu...
        status, body = esp.net.http_get("http://example.com/")  # ...modeminiz olur

    USB kablosu olmadan da kullanabilirsiniz. Kartlar espbridge_<mac> adıyla, ayrıca verdiğiniz özel adla, yayın yapar ve parola ister. Varsayılan parola espbridge; sketch içinde EspBridge.begin("yourpassword") ile değiştirilebilir:

    with Bridge(ble=True, password="espbridge") as esp:   # Bluetooth üzerinden
        esp.gpio.write(2, 1)

    Bridge() önce Bluetooth'u dener, sonra USB serial'a düşer. Yalnızca USB / COM kullanmak için ble=False, belirli bir Bluetooth kartına bağlanmak için ble="name", belirli bir seri port için port="COM7" verin.

    Komut satırında espbridge bağlantı bilgisini yazdırır; espbridge ports aday seri portları listeler; espbridge scan bağlı kartları yoklar, espbridge scan --ble ise Bluetooth üzerinden yayın yapan bridge'leri bulur.

Özellikler

modül öne çıkanlar
GPIO pull-up/down ve open-drain dahil pin modları, toplu yazma, doğrulama için geri okunan seviye (verify= uyuşmazlıkta hata verir), debounce'lu kenar kesmeleri → Python callback'leri
ADC ham okuma + kalibre mV, attenuation ayarı (ADC2/Wi-Fi çakışması korunur)
DAC 8-bit çıkış + donanımsal cosine generator (klasik ESP32 / S2)
PWM LEDC: herhangi bir pin, frekans/çözünürlük, duty_pct, tone, servo
Touch kapasitif touch pad okumaları
I2C 2 bus, tarama, yazma/okuma, register yardımcıları, repeated-start
SPI 2 host, full-duplex transferler, CS yönetimi
UART UART1/2 köprülenir: Python'dan yazma, RX tarafı olay olarak geri akar
Wi-Fi tarama, STA bağlantısı, AP modu, durum/RSSI, durum olayları
NET ESP32 radyosu üzerinden TCP client/server + UDP, socket benzeri API, credit-window akış kontrolü
BLE tarama, advertise, GATT server (notify/write callback'leri), GATT client
ESP-NOW bağlantısız ESP32↔ESP32 mesajlaşma: peer'ler + broadcast, teslim ACK'leri, RSSI ile RX, PMK/LMK şifreleme; Wi-Fi ve BLE ile birlikte çalışır
RMT genel amaçlı darbe dizisi oynatma/yakalama; neopixel, ir, dht, hcsr04, stepper sürücülerinin ortak temeli
1-Wire herhangi bir pinde bus primitive'leri; ROM search + CRC8 Python'da (esp.onewire, DS18B20 sürücüsü dahil)
CAN TWAI controller: 25k-1M bit/s, filtreler, send/recv + callback'ler (esp.can; transceiver çipi gerekir)
I2S MEMS mikrofonlar ve DAC/amp'ler için PCM giriş/çıkış (esp.i2s; bağlantı bant genişliği yaklaşık 16-bit/32 kHz mono ile sınırlar)
Files dahili flash üzerinde LittleFS + SD kartlar: open/read/write/list/... (esp.fs)
NVS kart üzerinde kalıcı key/value depolama (esp.nvs)
Watch kart üstü kurallar: kart ADC/GPIO/touch/heap değerlerini kendi örnekler, koşul tetiklenince olay gönderir ve host bağlantısına bağlı kalmadan yaklaşık 5 ms içinde kart üzerinde tepki verebilir (do=("gpio", pin, level) / do=("pwm", pin, duty))
Sleep timer/GPIO uyandırmalı deep + light sleep (esp.deep_sleep(); çip notlarına bakın)
Power esp.radio_off(): Wi-Fi + ESP-NOW + tüm BT stack'i kapanır; radyo kesmeleri kalkar, yaklaşık 110 KB heap boşalır, USB üzerinden jitter hassas gerçek zamanlı işler için ADC2 pinleri açılır; esp.cpu_freq(), esp.power_mode()
OTA firmware'i USB veya Bluetooth üzerinden yeniden flash etme (esp.ota.flash("fw.bin"); dual-app partition scheme)
Ethernet RMII (WT32-ETH01, Olimex POE...) veya SPI (W5500); NET soketleri otomatik olarak bunun üzerinden çalışır (firmware'de etkinleştirme gerekir)
Camera ESP32-CAM / XIAO-S3-Sense / ESP-EYE'dan JPEG görüntü (firmware'de etkinleştirme, PSRAM gerekir)
MCPWM H-bridge'ler için donanımsal deadtime'lı tamamlayıcı PWM çifti (esp.mcpwm; S2/C3'te yok)

Saf Python cihaz sürücüleri RMT/1-Wire/I2C primitive'leri üzerine kuruludur; kendi sürücünüzü eklemek için firmware değiştirmeniz gerekmez:

from espbridge.drivers.neopixel import NeoPixel   # WS2812/SK6812 şeritler
from espbridge.drivers.dht import DHT             # DHT11/DHT22 sıcaklık+nem
from espbridge.drivers.ds18b20 import DS18B20     # 1-Wire termometreler (multi-drop)
from espbridge.drivers.hcsr04 import HCSR04       # ultrasonik mesafe ölçümü
from espbridge.drivers.ir import IrSender, IrReceiver  # NEC kumandalar + ham IR
from espbridge.drivers.stepper import Stepper     # rampalı A4988/DRV8825

NeoPixel(esp, pin=5, n=30).fill((0, 0, 64))
print(DHT(esp, 4).read())                 # (23.1, 65.5)
Stepper(esp, step_pin=12, dir_pin=14).move(400, speed=800, accel=1600)

Kendi sürücünüzü getirin

Bunlar referans uygulamalardır, sınır değildir. Paketle gelen her sürücü espbridge/drivers/ altında durur. Bir sürücü, constructor'ı ilk argüman olarak bridge alan ve yukarıdaki primitive'lerle cihazla konuşan normal bir Python sınıfıdır. Örneğin drivers/dht.py 75 satırdır. Yani herhangi bir sensör, ekran ya da protokol host tarafında yazılmış bir sınıfla eklenebilir; firmware değişmez:

class MyTempSensor:                          # bridge'i ilk alan herhangi bir sınıf
    def __init__(self, esp, address=0x48):
        self._i2c, self._addr = esp.i2c, address
    def read_c(self):
        hi, lo = self._i2c.read_reg(self._addr, 0x00, 2)
        return ((hi << 8 | lo) >> 4) * 0.0625

MyTempSensor(esp).read_c()                    # olduğu gibi çalışır, kayıt gerekmez

esp.<name>(...) kısayolu için bir ad kaydedebilir ya da başkalarının kurduğu anda sürücünüzün her bridge üzerinde görünmesini sağlayan bir pip paketi dağıtabilirsiniz:

from espbridge import register_driver
register_driver("mytemp", MyTempSensor)
esp.mytemp(address=0x48).read_c()             # == MyTempSensor(esp, address=0x48)

espbridge drivers kullanılabilen her şeyi listeler: paketle gelen drivers/ ve kurulu eklentiler. Tam rehber: DRIVERS.md. Adafruit / luma / gpiozero / smbus2 ekosistemlerinde hazır bir sürücü varsa, uyumluluk katmanları üzerinden değiştirmeden çalışır; yeniden yazmanız gerekmez.

Firmware FreeRTOS üzerinde tamamen olay güdümlüdür. Serial TX, komut işleme ve ağ yığını ayrı task'lerde çalışır; bu yüzden bloklayan bir Wi-Fi/BLE işlemi GPIO okumasını geciktirmez. Tipik gidiş-dönüş yaklaşık 1 ms'dir. Bağlantı, USB bridge çipinin desteklediği hıza otomatik yükselir: CP210x'te 1.5 Mbaud, CH340'ta 2 Mbaud.

Eşzamanlılık ve entegrasyon

Bir kartın bağlantısı aynı anda iki kez açılamaz; ama tek bir Bridge thread-safe'tir. Aynı bridge'i thread'ler arasında paylaşabilirsiniz. İstekler kablo üzerinde pipeline edilir ve sequence number ile eşlenir; bir thread'deki yavaş çağrı başka bir thread'deki hızlı çağrıyı bekletmez. Firmware tarafında da buna karşılık gelen task ayrımı vardır; örnek için rtos_concurrency.py.

Kolay entegrasyon için her yere Bridge taşımayın. İhtiyacınız olan yerde connect() çağırın; aynı paylaşılan, otomatik yeniden bağlanan bağlantıyı alırsınız:

import espbridge

esp = espbridge.connect(ble=False)      # her thread/modülden aynı canlı bağlantı
esp.gpio.write(2, 1)                     # eşzamanlı çağrılar için güvenli

# örn. FastAPI/Flask route'u; tüm istekler tek bağlantıyı paylaşır:
@app.get("/adc/{pin}")
def read(pin: int):
    return {"mV": espbridge.connect(ble=False).adc.read_mv(pin)}

await kullanıyorsanız herhangi bir bridge'i sarın ve eşzamanlı I/O'yu asyncio.gather ile dağıtın (async_fanout.py):

from espbridge import AsyncBridge

async with AsyncBridge(ble=False) as esp:        # veya AsyncBridge.wrap(espbridge.connect())
    t, h = await asyncio.gather(esp.adc.read(34), esp.adc.read(35))

Birden çok process gerekiyorsa bağlantının sahibi tek process olsun; örneğin MCP ya da bir HTTP sunucusu. Diğer process'ler onunla konuşsun. Bkz. shared_connection.py.

Zaten bildiğiniz kütüphaneleri kullanın

espbridge popüler Python donanım ekosistemlerinin wire protokollerini konuşur. Bu yüzden mevcut kodlar, sürücüler ve eğitimler değişmeden çalışır; sadece Raspberry Pi pinlerinin yerini ESP32 pinleri alır.

gpiozero - tam pin factory (LED, Button, PWMLED, edge callback'leri, ...):

from gpiozero import LED, Button
from espbridge.compat.gpiozero import EspBridgeFactory

factory = EspBridgeFactory(esp)
led, btn = LED(2, pin_factory=factory), Button(4, pin_factory=factory)
btn.when_pressed = led.toggle

Adafruit CircuitPython sürücüleri - yüzlerce sensör/ekran için busio/digitalio uyumlu I2C, SPI ve DigitalInOut:

from adafruit_bme280.basic import Adafruit_BME280_I2C
from espbridge.compat.blinka import I2C

bme = Adafruit_BME280_I2C(I2C(esp))     # sürücü köprü üstünden çalıştığını bilmez
print(bme.temperature)

smbus2 - klasik Pi I2C kodu, değiştirmeden:

from espbridge.compat.smbus import SMBus
bus = SMBus(esp)                        # smbus2.SMBus(1) yerine
temp = bus.read_byte_data(0x48, 0x00)

luma.oled / luma.lcd I2C ve SPI ekran arayüzleri (LumaI2C, LumaSPI), RPi.GPIO için espbridge.compat.rpi_gpio uyumluluk katmanı ve native nesneler de stdlib alışkanlıklarını izler: UART portları pyserial benzeridir (in_waiting, readline), köprülenmiş TCP/UDP soketleri settimeout/recv/sendall destekler.

I2C OLED'ler (SSD1306 / SH1106 / yaygın klonları) doğrudan desteklenir. pip install "python-esp-bridge[oled]" kurun ve PIL ile çizin:

from espbridge.drivers.oled import OLED

oled = OLED(esp)                # bus init + auto-detect + klonlara güvenli power-up
with oled.draw() as d:          # d bir PIL ImageDraw'dur
    d.text((0, 10), "Hello!", fill="white")

Bir AI agent üzerinden kullanın (MCP)

Bridge'in tamamını bir Model Context Protocol sunucusu olarak LLM'e açabilirsiniz. 100'den fazla araç GPIO, ADC/DAC, PWM, I2C, SPI, UART, Wi-Fi, NVS, dosya sistemi, 1-Wire, ESP-NOW, CAN, MCPWM, Ethernet, kamera ve OTA'yı kapsar. Agent sensör okuyabilir, pin değiştirebilir, I2C tarayabilir ve bunları doğal dille yönetebilir.

Sunucuyu bir kez kurun, sonra kartı takın; port otomatik algılanır:

uv tool install "python-esp-bridge[mcp]"     # veya: pip install "python-esp-bridge[mcp]"

Claude Code, Gemini CLI, Codex CLI, Antigravity, Cursor/Windsurf ve Ollama ile çalışır. Hepsi aynı espbridge-mcp komutunu başlatır. Bu repo Claude Code (.mcp.json) ve Gemini CLI (.gemini/settings.json) için hazır ayarlarla gelir; asistanı repo içinde açmanız yeterlidir. Diğer istemciler aynı tek satırlık yapılandırmayı kullanır (mcpServers anahtarı):

{ "mcpServers": {
    "espbridge": { "command": "espbridge-mcp", "args": [] }
} }

Araçlar çevre birimine göre gruplanır (gpio_*, i2c_*, wifi_*, ...); ham byte payload'ları hex string olarak girer ve çıkar. Kendi sunucunuza gömmek için from espbridge.mcp import build_server kullanın. Codex, Antigravity ve Ollama dahil asistan bazlı kurulum: MCP.md.

Birden çok ESP32

Her karta bir kez kalıcı ad verin (espbridge -p COM7 set-name relays); ad ESP32'nin flash'ına yazılır, yeniden başlatmadan ve port numarası değişiminden etkilenmez. Sonra:

import espbridge
from espbridge import Bridge

esp = Bridge(name="relays")                  # veya Bridge(mac="aa:bb:cc:dd:ee:ff")

with espbridge.connect_all() as boards:    # ya da hepsini açın
    boards.by_name("sensors").adc.read(34)
    boards.by_name("relays").gpio.write(2, 1)

Sorun giderme

Hatalar komut adını söyler ve neyi kontrol etmeniz gerektiğini belirtir: I2C_WRITE (0x4003) failed: IO — no ACK on the wire — check wiring, power, device address and pull-ups. Timeout durumunda karta ek olarak ping atılır; mesaj, bağlantının mı koptuğunu yoksa tek bir frame'in mi kaybolduğunu söyler. Yararlı ayarlar:

esp = Bridge(retries=1)         # varsayılan: timeout'ta güvenli komutları bir kez tekrar gönderir
esp.free_heap()                 # firmware'den heap + düşen frame sayaçları
ESPBRIDGE_DEBUG=1 python app.py   # her istek/yanıtı adlarıyla izler

Yoğun bağlantıda frame kayıpları artık baştan engellenir: pipeline edilen patlamalar (OLED frame'leri, NeoPixel güncellemeleri) USB serial ve Bluetooth üzerinde firmware'in link buffer'ının kaldırabileceği hıza otomatik kısılır.

Repo düzeni

Repo kökü Arduino kütüphanesinin kendisidir; bu sayede Arduino Library Manager'a yayımlanabilir. Python paketi python/ altında yer alır.

yol açıklama
../src/ + ../examples/Bridge/ Arduino kütüphanesi: bir kez flash edilen firmware (C/C++) + örnek sketch (EspBridge.begin())
../library.properties, ../keywords.txt Arduino Library Manager metadata'sı (registry'nin istediği gibi repo kökünde)
../python/ Python paketi python-esp-bridge (import espbridge), kendi tests/ klasörü ve gruplanmış examples/ dizinleri (basics/, devices/, system/, wireless/, network/, displays/, compat/)
MCP.md MCP sunucusu (espbridge-mcp): bridge'i bir AI agent üzerinden kullanma
PROTOCOL.md binary wire protocol tanımı (framing, transport'lar, auth)
FIRMWARE.md firmware flash etme, partition scheme ve build flag referansı

Desteklenen donanım

Ana hedef klasik ESP32 DevKit'lerdir (ESP-32S / ESP-32D, 30 ve 38 pin, CP2102/CH340 USB). ESP32-S2/S3/C3/C6/H2 aynı sketch ile derlenir (native USB; ESP-NOW her yerde çalışır; S3/C3/C6/H2'de DAC yoktur). Yetenekler bağlantı sırasında firmware tarafından bildirilir; Python API, çipinizde olmayan özellikler için hızlı ve açık hata verir.

Klasik ESP32 (CP2102) üzerinde arduino-esp32 core 3.3.6 ile test edildi. Firmware Minimal SPIFFS partition scheme ile flash edildi (1.9 MB app + OTA; firmware bu slotun yaklaşık %95'ini kullanır). OTA gerekmiyorsa Huge APP de çalışır. Doğrulananlar: 1.5 Mbaud USB, BLE bağlantısı, ESP-NOW ve Wi-Fi/BLE/ESP-NOW birlikte çalışma. Kullanılan soak/coex paketi için python/examples/wireless/stress_test.py dosyasına bakın.

Bluetooth notu: arduino-esp32 core 3.x, S3/C3/C6/H2 üzerinde NimBLE host ile gelir. Bridge'in Bluetooth kodu (BLE bağlantısı + esp.ble) Bluedroid konuştuğu için bu çiplerde firmware şu an yalnızca USB olarak derlenir. Klasik ESP32 Bluedroid kullanmaya devam eder: tam BLE bağlantısı + Wi-Fi + ESP-NOW birlikte çalışır.

Klasik ESP32 IRAM ödünü: Wi-Fi ve Bluetooth birlikte yüklendiğinde çipin instruction RAM'i dolar. Bu nedenle varsayılan klasik derleme SD kart desteğini (LittleFS çalışmaya devam eder) ve deep/light sleep'i atlar. SD + sleep'i geri almak için BRIDGE_ENABLE_BLE 0 ile USB-only derleyin. S2/S3/C3/C6/H2'de bu özellikler her durumda vardır. Python API iki durumda da net bir UnsupportedError yükseltir (Cap.SLEEP, Cap.SDMMC sorguları).

Çip bazlı destek matrisi (v0.3.5 modülleri)

ESP32 S2 S3 C3 C6 H2
RMT / 1-Wire / CAN / I2S / NVS / OTA
LittleFS
SD (SPI) / sleep yalnızca BLE kapalı
SDMMC slot yalnızca BLE kapalı
MCPWM (deadtime çifti)
Camera (opt-in) ✓ (PSRAM) ✓ (PSRAM) ✓ (PSRAM)
Ethernet RMII (opt-in)
Ethernet SPI W5500 (opt-in)