Skocz do zawartości
Komentator

Kurs Qt – #2 – komunikacja z Arduino przez UART

Pomocna odpowiedź

26 minut temu, Matthew11 napisał:

@Filip4444 Strzelałbym, że problem leży prawdopodobnie w tym, że port pod którym masz Arduino jest już otwarty, albo system otworzył i nie zamknął go poprawie, gdy używałeś go np. do wgrania programu. Natomiast... analizując Twój zrzut ekranu widać tam, że system znalazł dwa urządzenia, a Ty nie wybrałeś portu COM3 gdzie faktycznie jest Arduino, tylko wybrałeś COM1.

Tak, na zrzucie jest wybrany com1, ale gdy chce się podłączyć do arduino wyskakuje taki sam błąd. Przepiszę program i zobaczę czy po porostu nie mam jakiejś literówki.

Udostępnij ten post


Link to post
Share on other sites

Witam, tez mam podobny problem z tym że program wszystko wysyła lecz nie odbieram żadnych wiadomości, jakieś sugestie co jest nie tak?

Udostępnij ten post


Link to post
Share on other sites

Cześć @kulfi27 Na drugiej stronie komentarzy w tym wątku, kilka osób sygnalizowało podobne/same problemy jak Ty opisujesz. Sprawdź proszę tamte sugestie - niektórzy wskazywali na błędy w biblioteki QSerialPort na niektórych wersjach. Jest też przykład Terminal Example - https://doc.qt.io/qt-5/qtserialport-terminal-example.html uruchom go u siebie i sprawdź czy to działa poprawnie - od razu mówię, że nigdy z niego nie korzystałem ale jest to dobre źródło do weryfikacji co nie działa. Sprawdź też swoją wersję Qt i poszukaj czy anglojęzyczni koledzy nie mają podobnego problemu co Ty - polecam w tym celu przeszukać forum Qt https://forum.qt.io/

Daj znać po testach czy coś się udało.

Udostępnij ten post


Link to post
Share on other sites
Anonim

Wiem, że trochę nie na temat ale jak zrobić aby móc wywoływać skrypty pythona z wnętrza slotów pisząc na widgetach? @Matthew11 masz jakąś metodę do tego? Próbowałem stosować api pythona dla c++ ale wykorzystanie całego gotowego skryptu było by chyba łatwiejsze. Jedyny problem to przekazywanie danych pomiędzy modułem pythona i Qt inaczej jak za pośrednictwem plików tymczasowych. Dzięki temu oprócz uarta można by było wykorzystać inne sterowniki z pythona. Pozdrawiam

Udostępnij ten post


Link to post
Share on other sites

Witam ponownie, odpaliłem terminal z przykładów w Qt i działa mogę odbierać dane. wersja Qt jaką posiadam to 5.14 więc teraz pytanie co jest nie tak? Mam jeszcze takie pytanie z racji iż nigdy nie programowałem na PC tylko uC czy mógł byś trochę nakreślić jak działa taki program  nie chodzi mi o wykonywanie zdarzeń po kliknięci przycisku bo to zostało opisane w kursie a o strukturę takiego programu czy również tutaj występuje coś w rodzaju głównej funkcji jak się to ma w uC.

Udostępnij ten post


Link to post
Share on other sites
1 godzinę temu, kulfi27 napisał:

Witam ponownie, odpaliłem terminal z przykładów w Qt i działa mogę odbierać dane. wersja Qt jaką posiadam to 5.14 więc teraz pytanie co jest nie tak?

Wygląda na to, że problem leży w kodzie, który używasz. Stosujesz swój własny, czy ten dołączony do kursu? Jeśli nie działa Twój własny, no to musisz porównać Twoją implementację z implementacją z przykładu. Natomiast jeśli ten załączony do kursu nie działa, a oficjalny przykład Qt już tak, to w takim prosiłbym Cię o porównanie obu programów i poszukanie różnic ostatecznie możesz podesłać mi w wiadomości prywatnej źródła obu tych wersji - mógłbym to zrobić u siebie, ale mam inną wersję Qt, stąd przykład w mojej wersji może być zmieniony. 

1 godzinę temu, kulfi27 napisał:

Mam jeszcze takie pytanie z racji iż nigdy nie programowałem na PC tylko uC czy mógł byś trochę nakreślić jak działa taki program  nie chodzi mi o wykonywanie zdarzeń po kliknięci przycisku bo to zostało opisane w kursie a o strukturę takiego programu czy również tutaj występuje coś w rodzaju głównej funkcji jak się to ma w uC.

Zakładam że na uC piszesz w C lub C++. Każdy program napisany w C lub C++ niezależne czy jest pisany na uC czy PC będzie miał funkcję main() - czy przez nią rozumiesz "funkcję główną"? My programujemy w Qt w C++, więc też mamy taką funkcję - i mamy ją zawsze w projekcie w pliku o nazwie main.cpp. Dla czystego projektu QtWidgets ma ona taką formę:

#include <QApplication>
#include "mainwindow.h"

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();

    return a.exec();
}

Jeśli miałbyś to porównać do main() z projektu dla systemu wbudowanego to pierwsze trzy linie w main() to taka konfiguracja układu, a ostatnia return a.exec() to uruchomienie pętli zdarzeń - dzięki której działają między innymi sygnały i sloty - porównując to do programu uC jest to odpowiednik nieskończonej pętli, w której realizowana jest logika układu. @kulfi27 czy te odpowiedzi Cię satysfakcjonują?

  • Lubię! 1

Udostępnij ten post


Link to post
Share on other sites

Hej, udało mi się po części rozwiązać problem, na początek odpaliłem Qt z opcją Debug postawiłem kilka breakpoint  i zauważyłem że program nie wchodził do funkcji readFromPort, porównałem kod z przykładu Terminal i w miejscu konfiguracji portu podmieniłem tą linijkę kodu

            connect(this->device, &QSerialPort::readyRead, this, &MainWindow::readFromPort);

Po tym zabiegu już program zatrzymywał się w funkcji redFromPort z tym że nie wchodził do funkcji while więc dla testu ja wywaliłem i działa😀

Miałbym do Ciebie jeszcze pytanie czy możesz mi wyjaśnić jak się to odbywa że raz wywołana metoda connect będzie ciągle sprawdzała czy nie nadleciały jakieś dane do odczytu skoro jest wywoływana w funkcji on_pushButtonConect_clicked().

Dziękuje Ci za wszystkie wyjaśnienia i poświęcony czas.

Pozdrawiam

Udostępnij ten post


Link to post
Share on other sites

@kulfi27 connect łączy sygnał ze slotem. Jest to realizowane na poziomie meta systemu Qt (w skrócie Qt generuje kod C++, który pozwala na działanie mechanizmu signals & slots). W dużym uproszczeniu connect to rejestracja callbacku znanego z czystego C/C++. Za każdym razem gdy wywołany zostanie sygnał (np. SerialPort::readyRead) wywoływane są wszystkie połączone sloty. Do jednego sygnału może być podłączonych wiele slotów. Połączenie trwa dopóki nie wywołasz funkcji QObject::disconnect

Udostępnij ten post


Link to post
Share on other sites
(edytowany)

@kulfi27 
Okej w takim razie, jeśli problemem było użycie metody QObject::connect() z Qt4, która używa makr SIGNAL i SLOT:

connect(this->device, SIGNAL(readyRead()), this, SLOT(readFromPort()));

na connect z Qt5,

connect(this->device, &QSerialPort::readyRead, this, &MainWindow::readFromPort);

To sugeruje, że Qt nie mogło rozwiązać tego połączenia w czasie wykonywania programu. connect() z Qt4 jest rozwiązywany w czasie programu, natomiast connect() z Qt5 w czasie kompilacji. Ciężko powiedzieć dlaczego nie działa starsza wersja, ale to tylko znak, że należy używać tej z Qt5. Niestety wtedy kiedy pisałem kurs używałem connect() z Qt4 😞 
@kulfi27 Z ciekawości czy przy connect() z Qt4 po uruchomieniu programu w konsoli nie były drukowane jakieś ostrzeżenia? Jak się connect() z Qt4 nie powiedzie to jest drukowana informacja.

33 minuty temu, kulfi27 napisał:

nie wchodził do funkcji while więc dla testu ja wywaliłem i działa

Program do tego while'a wchodzi wtedy kiedy odczytany ciąg znaków zawiera znak końca linii, z przykładu z dokumentacji np: taką może mieć implementację metoda canReadLine():

bool CustomDevice::canReadLine() const
{
    return buffer.contains('\n') || QIODevice::canReadLine();
}

Czy dane, które wysyłałeś z uC zawierały znak końca linii? 😛 Jeśli nie to masz odpowiedź dlaczego nie wchodziło do while'a.

33 minuty temu, kulfi27 napisał:

Miałbym do Ciebie jeszcze pytanie czy możesz mi wyjaśnić jak się to odbywa że raz wywołana metoda connect będzie ciągle sprawdzała czy nie nadleciały jakieś dane do odczytu skoro jest wywoływana w funkcji on_pushButtonConect_clicked().

Za to odpowiada mechanizm Sygnałów i Slotów Qt. To nie connect() sprawdza czy w buforze odbiorczym są jakieś dane, connect() się wykonuje i zwraca sterowanie od razu - więc jak by mógł to robić? To co robi connect() to rejestruje dane połączenie w mechanizmie sygnałów i slotów. Wtedy w tej pętli zdarzeń:

int main(int argc, char *argv[])
{
    //...
    return a.exec(); // <- która startuje tutaj
}

Jeśli device wyemituje sygnał readyRead() to mechanizm sygnałów i slotów (nie connect()) wywoła w efekcie metodę readFromPort() klasy MainWindow@erulission akurat mnie ubiegł 😛 A jak to działa dokładnie, możesz sprawdzić tutaj

Edytowano przez Matthew11

Udostępnij ten post


Link to post
Share on other sites

Dziękuje wam za odpowiedzi właśnie to chciałem wiedzieć żeby zrozumieć ten mechanizm działania 😁

Nie będę ukrywał to moje kompletne początki więc trochę zabawy i nauki przede mną tym bardziej że uC to tylko w C więc poznanie C++ jak Qt zapewne trochę mi zajmie a że samego C++ jakoś nie miałem potrzeby się uczyć to teraz mam trochę motywacji do tego.

@Matthew11 przyznam szczerze że zapomniałem o końcu lini masz racje dlatego to nie zadziałało.

Jeszcze raz dzięki za pomoc😉

Udostępnij ten post


Link to post
Share on other sites

Dołącz do dyskusji, napisz odpowiedź!

Jeśli masz już konto to zaloguj się teraz, aby opublikować wiadomość jako Ty. Możesz też napisać teraz i zarejestrować się później.
Uwaga: wgrywanie zdjęć i załączników dostępne jest po zalogowaniu!

Anonim
Dołącz do dyskusji! Kliknij i zacznij pisać...

×   Wklejony jako tekst z formatowaniem.   Przywróć formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Twój link będzie automatycznie osadzony.   Wyświetlać jako link

×   Twoja poprzednia zawartość została przywrócona.   Wyczyść edytor

×   Nie możesz wkleić zdjęć bezpośrednio. Prześlij lub wstaw obrazy z adresu URL.


×
×
  • Utwórz nowe...