Skocz do zawartości
Komentator

Kurs Qt – #2 – komunikacja z Arduino przez UART

Pomocna odpowiedź

@Matthew11 Nie chce go blokować na określony czas tylko na okres w którym Arduino wysyła jakieś dane, a gdy dane przestana napływać to a on się znowu uaktywnić. Czyli pokombinuje coś z druga metoda jaką podałeś.

Udostępnij ten post


Link to post
Share on other sites

Zadanie rozwiązałem jedynie połowicznie czyli bardzo dobrze przydały się wskazane przez Ciebie „setEnabled”. Nie podołałem niestety  z QTimer-em, ale to nie tyle on jest problemem tylko ja, bo nie ogarnąłem tego jak program ma sprawdzić że odbieranie danych się skończyło. Dlatego kluczowe jest bym znalazł sposób określania czy coś się w Arduino odbiera czy nie. Kombinowałem coś z pętlą warunkiem:

if(this->device->isOpen() && this->device->isReadable())

Potem po prostu dołączyłem wyłączniki „setEnabled” do: 

while(this->device->canReadLine())

ale nic sensownego nie stworzyłem bo każda z metod i kilka innych na które wpadłem co prawda blokuje przycisk  ale już go nie odblokowuje. Ciągle czuje że umyka mi jakaś drobnostka. Gdybym wiedział czym tu jest jednoznaczny sygnał czy dane są odbierane czy już nie są to ruszyłbym z miejsca.

Udostępnij ten post


Link to post
Share on other sites
(edytowany)

@Wrona Ok, należy zacząć od tego jak po stronie mikrokontrolera są wysyłane dane: czy
a) jest to kilka paczek wysyłanych w określonych odstępach czasu na jedno kliknięcie wyślij czy
b) jedna dłuższa paczka wysłana raz na jedno kliknięcie wyślij.

Jeśli a) to musisz określić najdłuższy z tych odstępów załóżmy,  że 200ms, to bezpiecznie po stronie programu ustalasz, że jak dane nie pojawiają się od ostatnich 250ms to oznacza, że transmisja się zakończyła i można odblokować przycisk.
Jeśli opcja b) to pod warunkiem, że nic nie blokuje wysyłania paczki danych po stronie mikrokontolera i zaczyna on wysyłać dane natychmiast po odebraniu komendy z PC to możesz śmiało założyć jakiś krótki okres czasu, że np. po czasie 20ms (lub krótszym) po ostatnim odebranym bajcie możesz odblokować przycisk. 

I teraz po stronie aplikacji istotne są dwie rzeczy: 1) zablokowanie przycisku przy kliknięciu, 2) obsługa timera w slocie odbierania danych.
Czyli klikasz przycisk -> zablokuj go i uruchom timer z odpowiednim interwałem dostosowanym do twojego układu. Następnie w slocie odbierania danych resetujesz timer - dlaczego? Dlatego, że do tego slotu możesz wejść kilka razy, na jedną paczkę danych - i nie obchodzi Cię ile razy tam wejdziesz, tylko to, żeby resetować timer dopóki dane są odbierane - i teraz jak wszystkie dane zostaną odebrane to już slot odbioru danych nie będzie wywoływany, a tym samym nie zrestujesz timera, który ostatecznie wyemituje sygnał triggered() w którym odblokujesz przycisk.

(Natomiast najlepszą opcją było by tu wprowadzenie pakietowej transmisji, gdzie odebranie całego pakietu z danymi było by równoznaczne z zakończeniem transmisji, lub po prostu wysyłanie pakietu o jej zakończeniu.)

Edytowano przez Matthew11
  • Lubię! 1
  • Pomogłeś! 1

Udostępnij ten post


Link to post
Share on other sites

@Matthew11 Dzięki za cierpliwość. Wczoraj namordowałem się z tym QTimer-em tak mocno że z niego zrezygnowałem. Jednak dziś znów o nim napisałeś więc na nowo uparcie zacząłem rozgryzać sposób z jego wykorzystaniem. Problem okazał się trywialny czyli nie ogarniam jeszcze tego wszystkiego i po prostu należało poprawnie zdefiniować kolejny obiekt. Tak czy inaczej mozół przyniósł efekty i w zasadzie cel został osiągnięty czyli pierwszy użyteczny program działa tak jak chciałem. Mogę teraz z czystym sumieniem zacząć w miarę możliwości systematyczną naukę. 

Zanim jednak opuszczę ten wątek wspomnę o pewnej wisience na torcie, której mi brakuje.   Wzorem do programu był kod prezentowany w drugim odcinku kursu Qt i w nim posługiwano się standardowo ustawianym nazewnictwem głównej klasy czyli MainWindow. Czyli jak otwieram swój program to w lewym górnym rogu okna mam takie właśnie napis. Próby jego zmiany po wielokroć kończą się błędami w kodzie. Jak to zrobić najprościej?

Udostępnij ten post


Link to post
Share on other sites
(edytowany)
19 minut temu, Wrona napisał:

Zanim jednak opuszczę ten wątek wspomnę o pewnej wisience na torcie, której mi brakuje.   Wzorem do programu był kod prezentowany w drugim odcinku kursu Qt i w nim posługiwano się standardowo ustawianym nazewnictwem głównej klasy czyli MainWindow. Czyli jak otwieram swój program to w lewym górnym rogu okna mam takie właśnie napis. Próby jego zmiany po wielokroć kończą się błędami w kodzie. Jak to zrobić najprościej?

Generalnie zmienić każde wystąpienie "MainWindow" na "Inne" - najlepiej użyć globalnego "zamień na" powinna być taka opcja w QtCreatorze, (możliwe, że w pliku .ui, też coś jest wykorzystane, nie pamiętam trzeba sprawdzić), zmienić prawdopodobnie nazwy plików mainwindow.h/cpp na inne.h/cpp, zmienić #include, które includują mainwindow.h na include inne.h/cpp. Może wtedy kompilacja się uda, jak nie to patrz co mówią błędy. Ostatecznie możesz stworzyć projekt od nowa z odpowiednią nazwą (ale to dużo więcej pracy).

Edytowano przez Matthew11
  • Lubię! 1

Udostępnij ten post


Link to post
Share on other sites

@Matthew11 Próbowałem już podmieniania wszystkiego i wszędzie nawet w .ui i zawsze cos się sypało. Więc pomyślałem że pewnie jest jakiś lepszy sposób. No ... nic to, dam rade z tym żyć 🙂 Dzięki raz jeszcze i wszystkiego dobrego.

Udostępnij ten post


Link to post
Share on other sites
(edytowany)

Z innej beczki, choć nie zupełnie. Nadszedł czas by program popracował samodzielnie bez Qt. Próbuje uruchomić .exe. i dostaje komunikat o braku Qt5core.dll. Ten problem chyba rozwiązałem dodając ręcznie plik do Windowsa. Pisze "chyba" bo pojawił się kolejny komunikat o braku Qt5cored.dll. Tu jest problem poważniejszy gdyż widzę  necie pliki dla Windowsa x32 ale ja mam x64. Jak sobie z tym poradzić?

Edytowano przez Wrona
Literówka utrudniajaca zrozumienie tekstu

Udostępnij ten post


Link to post
Share on other sites

Ło matko ... bardziej tego zakręcić spece od Qt nie mogli!

Błagam Cię "rozrysuj" to jakoś bo na razie wpisałem ścieżkę według twego przepisy i dostałem jedynie "Unable to find binary in "C:\dev\Test_build" lub w innym przypadku "Unable to find binary in "C:\aaa\ccc". Specjalnie robię króciutkie te ścieżki by było łatwiej ale nie wiem gdzie jest problem. Zajmę się hodowlą gołębi na płycie krakowskiego rynku bo do informatyki tracę już siły.

Udostępnij ten post


Link to post
Share on other sites
(edytowany)
8 minut temu, Wrona napisał:

Błagam Cię "rozrysuj" to jakoś bo na razie wpisałem ścieżkę według twego przepisy i dostałem jedynie "Unable to find binary in "C:\dev\Test_build" lub w innym przypadku "Unable to find binary in "C:\aaa\ccc".

@Wrona W samym błędzie masz podpowiedź co robisz źle, podajesz katalog w którym nie ma pliku wynikowego (.exe). Sprawdź w QtCreatorze gdzie jest katalog build twojego projektu (przycisk Projects i tam szukasz tego katalogu) - pisałeś, że jak klikałeś .exe to pojawiały się komunikaty o brakujących dll-kach, no to właśnie to jest ten katalog i jego musisz podać dla windeployqt. 

Edytowano przez Matthew11
  • Lubię! 1

Udostępnij ten post


Link to post
Share on other sites
(edytowany)

@Matthew11 No właśnie mam go w systemie tzn. specjalnie jest stworzony i tam jest wszystko wkopiowane. Dlatego nie rozumiem dlaczego wyskakuje błąd skoro mam taki folder w systemie i go widzę w eksploratorze. Oryginalne pliki są na pulpicie z długą ścieżką dostępu ale problem był dokładnie ten sam.  Teraz z cmd przerzucam się na powershell by kolejne próby robić już szybciej.

Edit:

Dało się to w końcu ogarnąć. Jest to mozolne ale do zrobienia 🙂

Edytowano przez Wrona
Pojawiły się nowe fakty :)

Udostępnij ten post


Link to post
Share on other sites
(edytowany)

Po krótkiej przerwie postanowiłem wrócić do tego kursu (zwłaszcza zachęcony nową częścią o QML) i mam kilka pytań co do tej części:

1. Czy stosowanie this (np this->device) co do metod i zmiennych wewnątrz klasy jest wymagane? Rozumiem, że to dobra praktyka?

2. Lista devices. Do każdego elementu dostajemy się za pomocą .at(i) . Czy to jest równoważne [ i ]?

3. 

Musimy mieć jednak pewność, że na liście znajdują się jakieś obiekty. Dlatego bezpieczniej będzie jeśli napiszemy to w następujący sposób:

int index = 0;
if((devices.count() - 1) >= index) {
 devices.at(index);
}

Czy nie prościej tutaj skorzystać z devices.isEmpty()? 

4. 

Cytat

Dane przesyłam w postaci zdefiniowanych i opisanych pakietów złożonych z bajtów. Każdy pakiet posiada również sumę kontrolną w postaci CRC, dzięki czemu wiem, że odebrane dane są poprawne. Ramka pakietu (złożona z bajtów) składa się z kilku fragmentów np.: preambuły, danych i CRC. Polecam, a wręcz nakłaniam do napisania czegoś podobnego. Jest to ciekawe ćwiczenie, które może przydać się w późniejszych projektach.

Dla osoby która nie ma pojęcia nawet jak coś takiego zacząć, jakie źródło informacji na ten temat moglibyście polecić?

Edytowano przez Shog
Błędnie skopiowany kod

Udostępnij ten post


Link to post
Share on other sites

Czesć,

Próbowałem uruchomić komunikację między arduino nano i programem z kursu.

Qt widzi nano jako COM9 port łączy sie. Ale nie dochodzą żadne komunikaty z ardiuno.

Dziwne bo z putty wszystko działa super komunikatu biegają ! Tak jakby program w Qt nie dostawał  żadnych sygnałów z portu. (nano jest na CH340)

 

 

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!

Gość
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...