Arduino PyQt5 Haberleşmesi

Arduino ile ölçtüğüm sensör verilerini pyqt5 ile tasarladığım arayüzde göstermem gerekiyor threading diye bir modül varmış ama tam olarak nasıl kullanacağımı anlamadım yardımcı olabilirmisiniz

Bunun için öncelikle pyserial kütüphanesini araştırmanız lazım.

2 Beğeni

Bir çok örnek var.

GitHub - AasaiAlangaram/Arduino-Python-PYQT5-Serial-Communication: Read Sensor Data using arduino adc ports and Print them in Python PyQt Panel

Buraya bakabilirsin.

2 Beğeni

pyserialden veriyi alıp terminale yazdırıyorum onda bir problem yok arayüze yazdırınca veri kendini güncellemiyor

hocam ben pythonda biraz yeniyimde daha basit bir örnek var mıdır acaba?

Merhaba,
Öncelikle daha iyi yardımcı olabilmek için kodunuzdan parçalar olması işimizi kolaylaştıracaktır.

İkinci olarak bu sorununu pyqt deki signal-slot mekanizması ile çözebilirsin. Sana incelemen için bu forumdaki cevaplardan birini aşağıya bırakıyorum. Kafana takılan yerler olursa buradan sor yardımcı olmaya çalışırım.

Edit:

Arduino dan gelen veriyi bir thread de kontrol falan edersin. Veriler geldikçe emit ile gui yi guncellersin. Şu anlık aklıma bu geliyor.

dosya

import sys
from PyQt5.QtWidgets import *
from PyQt5.QtGui import QFont
import threading

#import RPi.GPIO as GPIO
from time import sleep
#GPIO.setmode(GPIO.BOARD)
#GPIO.setwarnings(0)
#GPIO.setup(12,GPIO.OUT)

import serial                                 # add Serial library for Serial communication

Arduino_Serial = serial.Serial('com3',9600)  #Create Serial port object called arduinoSerialData
print(Arduino_Serial.readline())              #read the serial data and print it as line
print("Enter 1 to ON LED and 0 to OFF LED")

class TesterThread(threading.Thread):
    def __init__(self, flag1):
        threading.Thread.__init__(self)
        self.flag  =0
        self.flag1 = flag1
        
        
    def run(self):
                
        while True:
            if self.flag1 == 0:
                print(self.flag1)
                #GPIO.output(12,self.flag)
                #print(self.flag)
                sleep(1)
                self.flag ^=255
            
            
    def changeFlag(self, flag):
        self.flag1 = flag

class Window(QWidget):
    def __init__(self):
        QWidget.__init__(self)
        layout = QGridLayout()
        self.contorl =0
        
        self.setLayout(layout)
        self.setWindowTitle("LED TEST GUI")
        self.setGeometry(200, 200, 500, 300)
        self.setFixedSize(820, 320)
        self.show()

        self.button = QPushButton("LED ON")
        self.button.clicked.connect(self.on_button_clicked)
        setFnt = QFont("Times", 14, QFont.Bold)
        self.button.setFont(setFnt)
        self.button.setFixedSize(300, 30)
        self.button.move(20, 20)
        layout.addWidget(self.button)

        self.button = QPushButton("LED OFF")
        self.button.clicked.connect(self.off_button_clicked)
        setFnt = QFont("Times", 14, QFont.Bold)
        self.button.setFont(setFnt)
        self.button.setFixedSize(300, 30)
        self.button.move(20, 20)
        layout.addWidget(self.button)
        
        self.button = QPushButton("LED Blink")
        self.button.clicked.connect(self.blink_clicked)
        setFnt = QFont("Times", 14, QFont.Bold)
        self.button.setFont(setFnt)
        self.button.setFixedSize(300, 30)
        self.button.move(20, 20)
        layout.addWidget(self.button)
        
        self.t = TesterThread(self.contorl)
        self.t.start()


    def on_button_clicked(self):
        Arduino_Serial.write(str.encode('1'))
        print("LED ON")
        self.t.changeFlag(1)
        #print(self.control)
        #GPIO.output(12, 1)

    def off_button_clicked(self):
        Arduino_Serial.write(str.encode('0'))
        print("LED OFF")
        self.t.changeFlag(1)
        #GPIO.output(12, 0)

    def blink_clicked(self):
        self.t.changeFlag(0)
        print("LED Blink's")

    
        '''
        while 1:
            GPIO.output(12,1)
            sleep(1)
            GPIO.output(12,0)
            sleep(1)
        '''
    
app = QApplication(sys.argv)
screen = Window()
screen.show()
sys.exit(app.exec_())

Kodun neresinde takıldın?

import serial                                 # add Serial library for Serial communication

Arduino_Serial = serial.Serial('com3',9600)  #Create Serial port object called arduinoSerialData
print(Arduino_Serial.readline())              #read the serial data and print it as line
print("Enter 1 to ON LED and 0 to OFF LED")

Com3 portundan 9600 boud hızında oku ve yazdır.

Geri kalan da qt5 arayüz oluşturmak için.

Zaten arduino ve seri haberleşme için en basit kod.

Geri kalan kısmı arayüz bilgisi. Daha basit derken daha ne kadar basitleştirilebilir bilemedim.

Merhaba, burada qt nin kendi sağlamış olduğu qthread lerin kullanılması daha iyi bir seçim olmaz mıydı? Ben olsam threading deki thread yerine qthread in sağlamış olduğu thread leri kullanırdım. PyQt de kullanılmak için daha kullanışlı olduğunu düşünüyorum (signal slot).

Açıkcası, ben çok takılmadım. Sağolsun adam, yazmış, güzelce github a yüklemiş. Thread konusunda tercihi sorgulamadım.

Benim tercihimi sorarsanız, asenkron haberleşir threadle bile uğraşmayabilirdim. Sensörün türünü bilmediğimden atıyorum saniyede bir kez portu dinler kullanırken ruhunu bile duyurmazdım qt ye.

Şöyle koda göz ucuyla baktığımda gördüğüm. seri haberleşme esnasında programı tutmamak.

Zevkleri ve renkleri tartışmam. qtthreads kullanmak ilave ne katkı sağlayabilir varsa fikriniz yazarsanız zevkle okurum.

Ben de zevkle yazarım. Aslında attığım linkte çok bir farkı yok aslında tarzı bir cevap vardı. ( yazdığım cevaptaki linke bakmadığınızı zannediyorum ama mühim değil)

İlk olarak QThread, qt yi yapan geliştiriciler tarafından ortaya konan bir şey. Qthread ile yapılabilecek işleri threading.Thread de de yapabilirsiniz belki, ama Panama kanalından geçmek varken neden Amerika’yı dolasasiniz ki?

Yani, qthread ile bir bakıma thread leri daha kolay yönetmeniz, kontrol etmeniz mümkün. Qthread bunun için hazır mekanizmalar sağlıyor size signal-slot vs.

Buna benzer bir mekanizma, gtk 'da da vardı yanılmıyorsam. Belki sonra editleyebilirim bu kısmı.

Yanılıyor olabilirim ama, guideki widgetlere falan başka bir thread den müdahale etmek iyi bir alışkanlık değil. Ama bu qthread ile çok basit. Forumda bu konu ile alakalı bir cevap olacaktı. Bulursam buraya eklemek isterim. Bu widget işi de nereden çıktı derseniz de (demeyin, bunu threading i yermek(qt uygulamalarındaki kullanımı için), slot-signal mekanizmasını övmek için yazdım. :upside_down_face:)
#Edit1: PyQt5/PySide2, QTextEdit için setText() ve setPlainText() uygularken hata - aib tarafından #2

Şuraya bir link bırakıyorum bakmak isteyenler için: Effective Threading Using Qt

hocam ben 17 yaşındayım yaklaşık 4 - 5 sene önce arduino aracılığıyla pragramcılığa merak saldım pythonu da yeni öğreniyorum. Yapmak istediğim şey aslında arduinodan sensör verilerini okumak bunu serial modüü araclığıyla yapmayı başardım bir while döngüsüyle verileri terminale yazdırabiliyorum ama arayüze yazdırma konusunda biraz takıldım bu kod sanırım bir ledi yakıp söndürmek için PyQt de threading özelliği olduğunu bilmiyordum biraz bu konu üzerinde araştırma yapacağım farklı örnekler varsa atarsanız mutlu olurum…

Evet bir ledi yakıp söndürmekle bir sensörden veri alıp göndermek mantık olarak farklı değil aslında. Burada veri olarak ne gönderdiğin önemli değil.

Sensör hakkında bilgi verirsen ona spesific bir örneği beraber yazarız. Burada sorun veriyi almak değil sanırım, asıl eksik kaldığın kısım, qt5 kullanamamak. Bunun için de bu arayüzü çalışman gerekir.

İster qt5 çalışmaya başla, ister bir modül üzerinden beraber bir kod yazalım. Hangi modülü kullanacağını belirt bakarız.

Neden linki okumadığımı düşündünüz?

“And some earlier comment on this subject from PyQt’s author: “they are both wrappers around the same native thread implementations”. And both implementations use GIL in the same way.”

Demiş birileri.

Oradaki tartışma linkine kadar gittim. Her programlama konusunda olduğu gibi tavuk mu yumurtadan yumurta mı tavuktan çıkara kadar gitmişler.

Dediğim gibi zevk meselesi benim için çok farketmez. Sonda bakış açımı topluca özetlerim.

Övmek derken, kullanışlı bulmanız güzel. Sonuçta kullanılsın diye tasarlanmıştır muhtemelen.

Benim bakış açıma gelince;

Öncelikle soruyu soran kişinin bilgi seviyesini yakalamamız gerekir. Yani neyi ne kadar bildiğini bilmediğim birine tavsiye verirken en asgari yöntemleri önermeye çalışırım. Onda dahi bazan anlayamayabilir.

Çünkü düşündüğümden daha azına hakim olabiliyor. Soru odaklı gidersek. Arduino sensör datası alınacak bir seri porttan gönderilecek. Bu durumda bu veriyi dinleyen bir proses/ thread ile data alınır, ara yüze aktarılır diye düşündüm. Derinlemesine bir qt konuşmak ve tüm özelliklerini konuşmak gerekir mi diye kafa yormadım. Çünkü tahminimce daha fazlasına şu an için hazır değil.

Basit bir kod linkinde dahi (bana göre basit olması bilmeyen birine basit gelecek anlamı taşımaz) zorlanması nedeniyle daha da basite indirgemeye odaklanıyorum şu an.

Sizin tartışmak istediğiniz konuya gelince;

C ve C++ dilinin uzun süre hayatta kalmasının tek nedeni, dilin standart olması, az anahtar kelime içermesi vs. vs.

Konu python olunca, durum biraz değişiyor. 2.x versiyonunda print “text” olan kod, 3.x versiyonunda print(“text”) e dönüşüyor ve bu bir kaç sene içinde oluyor.

Henüz şimdiye kadar bir python projesini indirip de bir seferde çalıştırabildiğim oldu diyemem. Ya kütüphanesi eksik çıkar, ya version tutmaz yada sınıfın için de bir alt yordam kaldırılmıştır.

Kodu çalıştırmak için mutlaka, hangi kütüphane sürümü kullandıysa onları da geri yüklemeyi gerektirir. Evet bunu otomatize eden text dosyalar, scriptler vs var ve ben uğraşabiliyorum, ama yeni öğrenen biri bütün bunlarla uğraşmak ister mi başaçıkabilir mi bilemedim.

Python kötüdür demedim yanlış anlaşılmasın ama, hala her şey bir düzene girmiştir diyemeyiz. O an için düzgün çalışan bir kodun ertesi gün bir güncelleme ile çalışmaz hale gelmeyeceğini kimse garanti edemez.

Bu şartlar altında ben de olabildiğince temel seviyede kodlar kullanmaya ve örneklerimi o seviyede tutmaya çalışıyorum. OOP bile kullanmamaya çalışıyorum, ola ki basit bir sorunu açıklamaya çalışırken sınıfları anlatmak zorunda kalmayayım diye.

Çünkü konuya odaklanmak yerine oturup sınıfları anlatmak çok da soru soranların işine yaramayabilir, sorusu sınıflar değilse tabi.

Bu nedenle qt thread meselesi benim için tali bir mesele. Çünkü ilerde ne ile kodu sarmalayıp(encapsulation) nasıl değiştireceklerinin garantisi yok.

Kullanım açısından kolay görünmesi, ileride değişebilecek bir çok değişken konuya odaklanmamı engelliyor.

Mesela şu an, esp32 ile c# ın haberleşmesine haber duyan bir proje üzerinde çalışıyorum ve adamların bakış açısı ve istekleri farklı, şu an buradaki farklı.

Bir diğerinde esp32cam ile python haberleşip, görüntü işlemek istiyorlar orada da odaklandıklarım farklı.

Yani olabildiğince standart kısımları üzerinden ilerlemeye çalışıyorum çünkü, herkesin diğer detaylara ihtiyacı olmuyor.

Ama kolaylaştırıyor diyebilirsin. Tabi ki , hatta kod yazmak yerine, hazır programlar kullanmak işi daha da kolaylaşıtırır değil mi? Ama neden bunu tercih etmiyoruz?

Özetle, qt thread zevkler renkler meselesi, kullanmak işleri kolaylaştırabilir (bilen biri için) işleri zorlaştırabilir (bilmeyen birine anlatan bir için). Ben her zaman C ruhu ile uzun süre çalışabilecek bağımlı olmaktan uzak temel kodlar üzerine inşa edilen kodları seviyorum.

Bu arada linkere bakmadığımı düşünmen üzdü, bakmak için sağ tıkladığında sayaç çalışmıyor :wink: Bir de tıkladığımda yeni sekmede açmak yerine forumda çıkıyor ben de alışkanlık olarak sağ tıklayıp yeni pencereden aç diyorum . Önemli olan orada yazan değil, sizin ne düşündüğünüz dü. Bu nedenle fikirlerinizi “hala” bekliyorum.

2 Beğeni

hocam benim kafamda şöyle bir proje var. Bir kutunun içindeki sıcaklık, nem ve kutuya koyacağım toprağı nemini istediğim dengede tutarak herhangi bir bitkiyi herhangi bir zaman aralığında yetiştirmek. Bu sistemi arayüz ile kontrol etmek istiyorum. (Sıcaklık ve nem değerlerini değiştirebilmek gibi)

Qt ile çalışmak şu an daha mantıklı geliyor çünkü bir süredir qt öğreniyorum benim için anlaması daha kolay olacaktı…

hocam timer kullanabilirsin arduino ile uğraştıysan MIT app invertoru kullanmış olmalısın en azından öyle var sayıyorum bluetoothtan gelen veriyi interval değeri 1000 olan yani 1 sn de bir çalışan bir timer ile alıyorduk aynısı PyQt için de geçerli

şöyle bir şey yapılabilir teoride zaten sana serialden veri akmakta loop fonksiyonu ile çalıştırıyorsun zaten hal böyle olunca timer ın süresi dolduğunda triggerlanacak bir signal-slot a ihtiyacın olacak o slot da ise veriyi alacaksın böylelilikle döngüye girmiş olacak

1 Beğeni

şöyle bir şey yapılabilir teoride zaten sana serialden veri akmakta loop fonksiyonu ile çalıştırıyorsun zaten hal böyle olunca timer ın süresi dolduğunda triggerlanacak bir signal-slot a ihtiyacın olacak o slot da ise veriyi alacaksın böylelilikle döngüye girmiş olacak

hocam kısmını biraz daha açıkça anlatırsanız sevinirim. Arduinodan veriyi almakta bir sıkıntı yok, bunları yaptığım yansıtmam gerekiyor. Şu ana kadar geldiğim nokta, projeye bir QPushButton ekleyerek bu butona her tıklandığında ekrandaki verilerin güncellenmesi. Ama benim yapmak istediğim gerçek zamanlı olarak bu verileri görmek. Yani arada bir buton olmasını istemiyorum. Bunun haricinde alt ve üst değerleri arayüz üzerinden belkirlemek istiyorum. Örneğin QSpinBox a 25 C değerini girdiğimde içeriyi 25 derece sıcaklıkta tutmasınıistiyorum. Arayüz olmadan bunu yapmak kolay ama ben birazdaha profesyonel olsun istiyorum.Mesela ben yazılım biliyorum Arduinonun yazılımıyla oynayarak bu değeri değiştirebilirim ama yazılım bilmeyen bir kişi bunu yapamayacaktır bunun için bir kullanıcı arayüzü geliştirmek istiyorum.

Kafanızda bir proje var ama ortada kod yok. Bunun için önce donanımı oluşturmak gerekir ondan sensörler nelerdir diye sordum.

Hani led yakıp söndürme arayüzünü anlamadınız ya sebebi bu. Bir arayüz oluştururken etkileşimin türü önemli.

Sonuçta ne değeri belirli değerin altına düştü mesela bir uyarı ışığı gibi buton gömek isteyebilirsin.

Veya sıcaklık değerlerini belirli aralıkta ta kaydeden bir grafikte görmek isteyebilirsin.

Nemi sağlamak için nasıl bir prosedür düşündüğünü belirtirsen, onun izleme ve kontrolü için de ayrı bir arayüz düşünmen gerekebilir.

Hele ki bir kutuya konulan bitkinin solunum sorununu nasıl halledeceksin onu da düşünmelisin.

Bunlar oluşmadan bir arayüz konuşamayız.

Neleri ölçeceksin, hangi sensörle, hangilerini takip edip manuel yöneteceksin hangilerini otomatik kontrol etmek istiyorsun bunların hepsini planlamadan bir arayüz tasarımından söz edemeyiz.

Qt ile çalışıp çalışmama meselesi değil. Önce bir kontrol mekanizması ve arayüz taslağı oluşturun sonrası sadece kodlama, qt dahil herhangi bir arayüz ile konu çözülebilir.

Bu nedenle arayüzü oluşturmadan önce yukarıdaki kriterleri netleştirin.

İlk yukarıdaki gibi sorduğunuzda, sanki her şey tamam tek sorun qt arayüzü programlama bilgisi eksikliği gibi görünürken, şu geldiğimiz noktada, henüz projenin donanımı dahil oturmamış fikir seviyesinde.

Toprak Nemi Algılama Sensörü (robitshop.com)

Mesela toprak nem sensörü.

Analog Sıcaklık Sensörü LM35 (robitshop.com)

Yukarıdaki hassas sıcaklık sensörü.

Sıcaklık ve Nem Sensörü Fiyatı ve Özellikleri (okuldunyasi.com)

Ortam nem ve sıcaklık sensörü.

Mini Dalgıç Su Pompası DC 2.5V-6V 120L/H (robitshop.com)

Sulamak için bir pompa.

Yetersiz ışık durumunda destek ışığı:

BİTKİ ÇİÇEK YETİŞTİRME LAMBASI LEDİ 200 LED EVDE BİTKİ YETİŞTİRME IŞIĞI LEDİ Fiyatı ve Özellikleri - GittiGidiyor

Ortam ışığı ölçecek bir sensör:

CJMCU-TEMT6000 Ortam Işığı Sensörü Satın Al | Robotistan

Belki kutuyu havalandırmak için bir fan:

CJMCU-TEMT6000 Ortam Işığı Sensörü Satın Al | Robotistan

Hadi olayı fantaziye götürelim:

Karbondioksit sensörü:

Gravity Arduino Analog Karbondioksit Gaz Sensörü (CO2) Uygun Fiyatıyla Satın Al - Direnc.net®

Bunlar işin yeterli pin sayısına sahip bir arduino modülü, bunun haberleşmesi için bir modül.

NodeMCU V3 ESP8266 ESP-12E Geliştirme Kartı - CH340 Satın Al | Robotistan

Yani süreki bilgisayara seri porttan bağlanmaz. Bari ağda kablosuz çalışsın.

İlgini çekerse:

İnternetten sizin suladığınız bitki - Yaşatmayı başarabilecek misiniz? - YouTube

Enteresan bir sosyoloji deneyi hem de bir bitki için bakış açısı verebilir.

Buraları aştıktan sonra.

QT konusuna geliriz.

Yani önce sınırları çiz ondan sonra arayüzde neleri nasıl kontrol edeceğimizi konuşuruz.

Yoksa burada qt referansı gibi bütün özellikleirni yazamak zorunda kalmayalım.

1 Beğeni

Straforla bir kutu yaptım sistemi bu kutu üzerine kurmak istiyorum Sıcaklık için ilk önce DHT11 kullanmayı denedim ama hassasiyeti istediğim düzeyde değildi onun yerine lm35 kullanmaya karar verdim nem için ise DHT11 kullanacağım elimde bir DH 11 modülü ve bir toprak nem sensörü var toprak nemini dalgıç pompa yardımıyla dengede tutmayı planlıyorum sıcaklık için basit bir akkor ampul kullanacağım ama ilerde bir rezistans ile değiştirebilirim bu sistemi Arduino UNO üzerinde kurmak istiyorum. Kod kısmına gelecek olursak sıcaklık dengesi için Kodlarım hazır toprak nemi dengesi için bir dalgıç pompa almam gerekiyor onu da aldıktan sonra onun da kodlarını yazacağım aslında elektronik kafamda bu şekilde oturmuş durumda takıldığım şey bu sistemi PC ile nasıl haberleştireceğimdi bunu da Pyserial modülü ile yapmayı başardım ama burada karşıma iki sorun çıktı;

1- Arduinodan kolaylıkla veri okuyabiliyorum burada bir problem yok tıldığım yer, mesela; sıcaklık değerinin tutulması gereken değeri nasıl gönderebileceğimi çözemedim. Aslında tek bir veri olsa kolay ama birden fazla verinin manuel olarak seçilmesi gererekiyor ve bunu nasıl yapacağımı çözemedim

2- Aslında konuyu açma sebebim yani okuduğum verileri güncel olarak ekranda gösterebilmek istiyorum .

Süreki PC’ye bağlı USB üzerinden seri haberleşme doğru bir yöntem m?

Wifi üzerinden daha rahat olmaz mı?

Verdiğim ilk örnek.

Arduino-Python-PYQT5-Serial-Communication/LedCurrent.py at master · AasaiAlangaram/Arduino-Python-PYQT5-Serial-Communication · GitHub

Arduino_Serial = serial.Serial('com3',9600)

import serial ile seri haberleşme kütüphanesini yüklüyorsun.

Sonra Arduino serial nesnesi ile seri porta bağlanıyorsun.

Tabi burada Com3 değişir hangi port görünüyorsa onu seç, baud hızı da arduino da ne ayarladıysan aynısı olacak.

Yine kodun içinde;

def read_data(self):
        
        k = Arduino_Serial.readline().decode()
        print("Voltage:",k)
        
        self.Txtbrowser.setText(str(k))
        self.Txtbrowser1.setText(str(k))
        self.Txtbrowser2.setText(str(k))
        self.Txtbrowser3.setText(str(k))
        self.Txtbrowser4.setText(str(k))
        self.Txtbrowser5.setText(str(k))

Seri porttan readline ile datayı okumuş, Txtbrowser içinde seText ile datayı yazdırmış.

Burada ha voltaj okumuşsun, ha kendi gönderdiğin sıcaklık değerini göndermişsin varkeden bir şey yok.

Kod çok basit. İncelesen çokta çözerdin.