Python Pyserial ile Seri Porttan Veri Okumak

fide

Meraklı ve "nasıl" sorusunu seven biri
Katılım
8 Eylül 2021
Mesajlar
2,037
Merhaba.

Python ile seri porttan veri okumaya çalışıyorum. Veriyi okuyorum. Bunda sıkıntı yok ama veriyi belirli bir formatı, belirli bitiş karakteri, belirli uzunluğu olmadan nasıl okuyabilirim?

Örnek:
Bir cihazla konuşacağım. BT modül, GSM modül, yada herhangi bir cihaz.
Bu cihazın gönderdiği veriler arasında mükerrer enter (13, "/r", 0xD) olabilir. Veri uzunluğu değişebilir.
Bu veriyi python içinde almak istiyorum ama pyserial kütüphanesi bana sadece o anda bufferda olan verinin uzunluğunu veriyor. "ser.in_waiting" ile bunu alıyorum ama gelen verinin uzunluğu sabit değil. Rutin okuma yaptığımda bazen veri alımın ortasında iken veriyi okumuş oluyorum. Bu da veriyi işlerken hataya sebep oluyor.

Nasıl bir yöntem/algoritma kullanabilirim?
Teşekkür ederim.
 
Ortak bir "timeout" belilenemez mi?
 
GSM modül gibi iletişim kurmadan önce açılıp "boot up" prosedürünü tamamlaması gereken cihazlar için bir timeout belirledim.
Atıyorum 2sn cevap vermezse kapalıdır kabul edebilirim ama mesela saniyede 5 defa defa okumam gereken bir cihaz için 2sn timeout kullanamam.

Benim aslında veri alımının bittiğini algılamam gerekiyor. Python'da bunu nasıl yapacağımı bilmiyorum.
 
stm32 için line idle detection var belirsiz bir uzunlukta veri gelirken veri durduğu anda bir timeout süresi sonra veriyi buffera alıp int üretiyor.

ya da mesela gps için tüm nmea verileri $ işareti ile başlar ve /n/r (13-10) escape karakterleri ile biter. alt satır-satır başı.

genelde de pc iletişiminde eğer binary bir protokol yoksa hep satır sonu işaretçisi ile bu işler yapılır. bunun istisnası paket içinde ascii olmayan bir karakter olmamalı. gps ve gsm böyledir, tüm veriler ascii karakterler ile kodlanır.
 
GSM modül gibi iletişim kurmadan önce açılıp "boot up" prosedürünü tamamlaması gereken cihazlar için bir timeout belirledim.
Atıyorum 2sn cevap vermezse kapalıdır kabul edebilirim ama mesela saniyede 5 defa defa okumam gereken bir cihaz için 2sn timeout kullanamam.

Benim aslında veri alımının bittiğini algılamam gerekiyor. Python'da bunu nasıl yapacağımı bilmiyorum.
200-300ms arası olmaz mı bekleme süresi bu durumda?

 
Son düzenleme:
Şu şekilde bir yol buldum. Şimdilik çalışıyor. Kodu öğle arasından sonra paylaşırım.

Counter ve countEx değişkenleri tanımladım. Başta ikisi de 0
Sonsuz döngü içinde
counterEx değişkeni counter değişkene eşitle
1/100 sn bekle
Seri bufferdaki veri boyutunu okuyup counter değişkene aktar.

Eğer counter ve countEx değişkenler eşit ve counter 0'dan farklı ise veri alınmıştır. Eşit olana kadar dön.
 
Uart data read:
def checkResponse():
    counter = 0
    counterEx = 0
    timeoutDuration = 100
    timeoutCounter = 0
    timeout = False
    dataReceived = False
    text = "\r"
    ser.write(text.encode())
    while(dataReceived == False) and (timeout == False): #timeout olana kadar yada veri tamamlanana kadar bekle
         counterEx = counter
         print("tD: {}, t: {}, cEx: {}, dR: {}".format(timeoutDuration, timeout, counterEx, dataReceived))
         sleep(1/100)
         counter = ser.in_waiting
       
         if (counter == counterEx) and (counter > 0):
             dataReceived = True
         timeoutCounter += 1
         if timeoutCounter >= timeoutDuration:
             timeout = True
    print("EXIT tD: {}, t: {}, cEx: {}, dR: {}".format(timeoutDuration, timeout, counterEx, dataReceived))
     
    if counter >0:
        raw = ser.read(ser.in_waiting)
        data = raw.decode("utf-8")
        if data.startswith("@"):
           
            text = "\r\r"
            ser.write(text.encode())
            sleep(1/2)
            raw = ser.read(ser.in_waiting)
            data = raw.decode("utf-8")
        return data
    else:
        return ""
while( moduleWokeUp == False):
    text = checkResponse()
    print("check if module ready to communicate")
    #print("Response: {}, 1: {}, 2: {} ".format(text, ord(text[0]), ord(text[4])))
    if  "dwm" in text:
        moduleWokeUp = True
print("Module is ready to communicate")

Eksikleri var ama bu yapı şimdilik işimi görüyor.

Uart ile ilgili bir handle var. Veri alımı bittiği zaman bir fonksiyonu çağırıyor. Asıl aradığım o ama daha müsait bir zamanda bakıcam
 
#5'deki yeri onun için paylaştım. "serial.threaded.ReaderThread" ile örnek paylaşılmış.
 

Çevrimiçi üyeler

Forum istatistikleri

Konular
7,226
Mesajlar
122,344
Üyeler
2,918
Son üye
LostFearLess

Son kaynaklar

Son profil mesajları

Freemont2.0 wrote on herbokolog's profile.
nick iniz yakıyor
:D
Freemont2.0 wrote on posta's profile.
Merhabalar :)
az bilgili çok meraklı
Prooffy wrote on semih_s's profile.
Merhaba, sizden DSO2C10 hakkında bilgi rica ettim. Yanıtlarsanız sevinirim...
Unal wrote on taydin's profile.
Timur Bey, Arduino kontrollü bir akü şarj cihazı yapmaya çalışıyorum. Aklımdaki fikri basit bir çizim olarak konu açmıştım. Özellikle sizin fikirlerinizi çok önemsiyorum.
Back
Top