Python Pyserial ile Seri Porttan Veri Okumak

fide

Meraklı ve "nasıl" sorusunu seven biri
Katılım
8 Eylül 2021
Mesajlar
2,005
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.
 
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 personel

Forum istatistikleri

Konular
6,950
Mesajlar
118,722
Üyeler
2,822
Son üye
lalemasall

Son kaynaklar

Son profil mesajları

hakan8470 wrote on Dede's profile.
1717172721760.png
Dedecim bu gul mu karanfil mi? Gerci ne farkeder onu da anlamam. Gerci bunun anlamini da bilmem :gulus2:
Lyewor_ wrote on hakan8470's profile.
Takip edilmeye başlanmışım :D ❤️
Merhaba elektronik tutsakları...
Lyewor_ wrote on taydin's profile.
Merhabalar. Elektrik laboratuvarınız varsa bunun hakkında bir konunuz var mı acaba? Sizin laboratuvarınızı merak ettim de :)
Lyewor_ wrote on taydin's profile.
Merhabalar forumda yeniyim! Bir sorum olacaktı lcr meterler hakkında. Hem bobini ölçen hemde bobin direnci ölçen bir lcr meter var mı acaba?
Back
Top