Elektroda.pl
Elektroda.pl
X
Proszę, dodaj wyjątek www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

Delphi&Arduino - Prosta komunikacja USB/RS-232

CrisELDi 04 Lis 2015 22:36 966 24
  • #1 04 Lis 2015 22:36
    CrisELDi
    Poziom 14  

    Witam.

    Szukam prostego rozwiązania na komunikację Delphi Arduino, szukają po necie sprawa nie jest tak prosta tym bardziej iż nie jestem programistą. Ale znalazłem rozwiązanie tak przynajmniej myślę :)

    Może na początek Arduino -> USB ->Delphi 7(ComPort)

    Kod: vbnet
    Zaloguj się, aby zobaczyć kod


    Arduino wysyła bardzo proste komunikaty np: P100 w tym przypadku kod (paczka) "P" oznacza przeznaczenie czyli wskaźnik/ProgressBar "100" wartość jaką ma wskazywać ten wskaźnik zaś S1 - "S" oznaczenie dla włącznika oraz pozycja "1" ON lub "0" OFF... Proste ...

    Kod: delphi
    Zaloguj się, aby zobaczyć kod


    W Delphi dane są odfiltrowane czyli początek i wartość według zapotrzebowania...
    np:P100 zostaje rozpoznane jako Date1= "P"(przeznaczenie) Date2="100"(wartości) I wszystko ładnie działa i jest wyświetlone w Label1 or Label2
    Nie jestem jeszcze pewny ale występuje delikatne opóźnienie otrzymaniem paczki Memo a wyświetleniem jej w Label. Nie wiem z czego wynika?

    Kod: delphi
    Zaloguj się, aby zobaczyć kod


    I tu jest mój problem aby użyć odfiltrowane dane dla wybranych obiektów. :|

    Można prosić o pomoc?

    0 24
  • #2 04 Lis 2015 22:41
    -psiak-
    Poziom 32  

    Wywal te wiersze:

    Kod: delphi
    Zaloguj się, aby zobaczyć kod
    wraz z odpowiednim end'em i powiedz czy nadal są opóźnienia.

    0
  • Pomocny post
    #4 04 Lis 2015 23:54
    -psiak-
    Poziom 32  

    Więc przerób na przyszłość na:

    Kod: delphi
    Zaloguj się, aby zobaczyć kod

    Gdzie, bardzo przydatna funkcja prawie w każdym projekcie:
    Kod: delphi
    Zaloguj się, aby zobaczyć kod

    0
  • Pomocny post
    #5 05 Lis 2015 06:37
    oloam
    Poziom 20  

    Po pierwsze :

    CrisELDi napisał:
    Str:=Memo.Lines[Memo.Lines.Count-2+Ord(P=Length(str))];

    po co to skoro w Str masz juz to co potrzebujesz ?
    Po drugie:
    Nie jestem pewien na 100% ale w com port mozna bylo odbieraz ramke gdzie ty wyznaczasz co ma byc poczatkiem ramki. Jezeli zmieniesz wysylanie paczki z uc na format np na 'RP100' a ustawisz znak R jako poczatek ramki, to nawet nie musisz sprawdzac w programie czy wszystkie dane przeszly (czego teraz nie masz) a i dane bedziesz mial od razu jak na tacy. Nie pamietam czy poczatek ramki tez byl w odbieranym striingu ale zakladajac, ze tak to:
    Kod: delphi
    Zaloguj się, aby zobaczyć kod

    i nic wiecej kodu nie potrzebujesz...

    0
  • #6 06 Lis 2015 00:51
    CrisELDi
    Poziom 14  

    Dzięki za pomoc i usprawnienie projektu.
    Jak można prosić o przykład najlepszy (optymalny) warunek aby moje paczy zaczęły
    pracować według przeznaczenia dla ProgressBar lub CheckBox. Proszę o przykłady bo tak poznaje ten świat :)

    Thx.

    0
  • Pomocny post
    #7 06 Lis 2015 08:13
    oloam
    Poziom 20  

    Najpierw 'wykrywasz' dla ktorego komponentu przeznaczona jest odebrana dana i w zaleznosci (przy zalozeniu ze nie odbierasz w ramce, w moim poscie wyzej jak odejmiesz jeden od kazdej liczby to bedziesz mial kod dla danych bez ramki):
    progressbar

    Kod: delphi
    Zaloguj się, aby zobaczyć kod

    checkboxy
    Kod: delphi
    Zaloguj się, aby zobaczyć kod

    0
  • Pomocny post
    #8 06 Lis 2015 10:39
    -psiak-
    Poziom 32  

    Kod: delphi
    Zaloguj się, aby zobaczyć kod

    0
  • #10 06 Lis 2015 11:46
    -psiak-
    Poziom 32  

    @oloam:
    1. Masz szanse pominięcia jednej lub kilku wartości o ile odbierzesz więcej niż jedną paczkę na raz.
    2. Życzę powodzenie w utrzymaniu takiej wersji po rozbudowie o kolejne kontrolki i kody.

    0
  • #11 06 Lis 2015 12:12
    oloam
    Poziom 20  

    -psiak- napisał:
    1. Masz szanse pominięcia jednej lub kilku wartości o ile odbierzesz więcej niż jedną paczkę na raz.

    Raczej nie ma takich mozliwosci - mniemam, ze transmijsa =115200 bez parzystosci a to = 14400 bajtow/sek. Kolega w przykladzie wysyla do 4 bajtow na 5sek.

    Nawet jezeli przyjac ze predkowci transmisji beda ekstremalnie wysokie (praktycznie bez przerwy) to twoj kod tez sie wysypie. Wiesz jak dziala procedure TForm1.ComPortRxChar(Sender:TObject;Count:Integer);? Jeszcze pod straym kontem to tlumaczylem wraz z przykladami kody zrodlowego comport. Jak wiadomo rs232 jest to transmisja szeregowa wiec wysylany jest bajt po bajcie. Co sie stanie jezeli w str znajdzie sie caly pakiet plus jeden znak nastepnego? Nastepne pakiety w buforze beda zaczynac sie od drugiego znaku. Zarowno twoj jak i moj program sie wysypie. Na koncu procedury trzeba wyczyscic bufor odbioru i na bledny pakiet zareagowac jak ja to zrobilem (case else);
    Dlatego w poscie wyzej zaproponowalem odbieranie ramki 'sprzetowo' przez comport. albo dostaniesz prawidlowa ramke albo wygeneruje ci sie timeout.
    -psiak- napisał:
    2. Życzę powodzenie w utrzymaniu takiej wersji po rozbudowie o kolejne kontrolki i kody

    Tu wogole nie widze problemu. jest tyle metod, zeby przerobic ten kod aby pozniej sie w nim nie zgubic, ze to chyba sam powinienes wiedziec (chociazby dla kazdego case stworzyc procedure). Sorry, to niech to nie zabrzmi jak antagonizm ale ty jakbys tylko w progressbear chcial tylko wykorzystac position, to napisalbys wlasna kontrolke, bo po co zbedny kod, ktorego nie wykorzystujesz.

    Ja w swoim kodzie wykorzystuje tylko i wylacznie procedury z modulow dolaczanych do delphi, w koncu po to one sa, a nie zeby pisac je od nowa...

    0
  • #12 06 Lis 2015 12:42
    -psiak-
    Poziom 32  

    1. Możliwość zawsze jest, na przykład główny wątek programu zostanie zamrożony na parę sekund. Fakt że w przykładzie widzimy wysyłanie długa pauza świadczy jedynie o tym że autor chce zobaczyć "naocznie" czy dzieje się to synchronicznie. Poza tym ewidentnie widać że przykład wysyłający nie jest jakimś gotowym programem, zaś swoistą zaślepką przyszłego kodu. Jeżeli zaś zostanie ustawiony StopString na #13 to nie powinno się zdarzać wczytywanie części ramki.
    2. Jak masz wszystko w tabelki to wystarczy tyle metod ile używasz rodzajów kontrolek (o ile się dołoży jeszcze jeden parametr do metody oraz jeszcze jedno pole do tabelki). Dowolna rozbudowa i/lub zmiana w projekcie jest wtedy łatwa w implementacji.
    Tak a propos jak uważasz że ma być minimalistyczne to po kiego tworzysz zbędne operacje? Czemu nie zwykły case w zależności od pierwszego znaku?

    Kod: delphi
    Zaloguj się, aby zobaczyć kod

    0
  • #13 06 Lis 2015 13:06
    oloam
    Poziom 20  

    -psiak- napisał:
    Jak masz wszystko w tabelki to wystarczy tyle metod ile używasz rodzajów kontrolek (o ile się dołoży jeszcze jeden parametr do metody oraz jeszcze jedno pole do tabelki). Dowolna rozbudowa i/lub zmiana w projekcie jest wtedy łatwa w implementacji.

    To samo moge powiedziec o moim kodze. Deklarujesz tablice jak const i w raze czego dopisujesz literke.
    -psiak- napisał:
    Tak a propos jak uważasz że ma być minimalistyczne to po kiego tworzysz zbędne operacje? Czemu nie zwykły case w zależności od pierwszego znaku?

    A co jak komenda bedzie wiecejznakowa ?
    -psiak- napisał:
    Możliwość zawsze jest, na przykład główny wątek programu zostanie zamrożony na parę sekund. Fakt że w przykładzie widzimy wysyłanie długa pauza świadczy jedynie o tym że autor chce zobaczyć "naocznie" czy dzieje się to synchronicznie. Poza tym ewidentnie widać że przykład wysyłający nie jest jakimś gotowym programem, zaś swoistą zaślepką przyszłego kodu. Jeżeli zaś zostanie ustawiony StopString na #13 to nie powinno się zdarzać wczytywanie części ramki.

    ComPortRxChar operuje na buforze kolowym, kazde nastepne wywolanie procedury uzupelnia odebrany bufor o kolejne nadplywajace dane (i zwraca towj count) a nie o kolejna ramke.
    Dla tak prostych programow nie uzywanie ramki jest ok. Ty piszesz od nowa sprawdzanie ramki czy jest prawidlowa. Po co? Wlasnie comport ma to juz wbudowane a ty piszesz od nowa.
    Czyz nawet ten przerobiony przez ciebie moj kod nie jest czytelniejszy i latwiejszy do zrozumienia(tylko tu wieloznakowosc komend sie wylozy).
    Ja propopnuje autorowi zostawic taki kod , ktory napisalem wczesniej i testowac. Jezeli beda sie zdazaly nieprawidlowe ramki to kod zostaje prawie taki sam tylko dodac do comport obsluge ramek i moze jeszcze (a le to juz dla calkowitej pewnosci) petle try except przy konwersji typow wtedy mozemy zareagowac na bledna ramke o ile sie zdarzy.

    0
  • #14 06 Lis 2015 13:57
    -psiak-
    Poziom 32  

    oloam napisał:
    A co jak komenda bedzie wiecejznakowa ?
    Genialnie, czy mógłbyś pokazać jak będzie wyglądać twój kod przy wiecejznakowej komendzie?

    Bo w moim wystarczy zamienić:
    Kod: delphi
    Zaloguj się, aby zobaczyć kod
    na:
    Kod: delphi
    Zaloguj się, aby zobaczyć kod
    oraz:
    Kod: delphi
    Zaloguj się, aby zobaczyć kod
    na:
    Kod: delphi
    Zaloguj się, aby zobaczyć kod

    0
  • #15 06 Lis 2015 14:15
    oloam
    Poziom 20  

    Naprawde?

    Masz racje jest to genialne w swojej prostocie:

    Kod: delphi
    Zaloguj się, aby zobaczyć kod


    Naprawde zle sie dzisiaj czuje i nie mam zamiaru ci udowadniac kolejnych twoich pytan o kod przy zadanym warunku.
    Jak nie wiesz jak zaimplementowac dany kod, to poprostu zaloz nowy temat...

    0
  • #16 06 Lis 2015 14:26
    -psiak-
    Poziom 32  

    @oloam, czyli owszem wieloznakowe ale koniecznie o tej samej długości, czyli kolejne ograniczenie dla twego rozwiązania?

    0
  • #17 06 Lis 2015 14:32
    oloam
    Poziom 20  

    -psiak- napisał:
    @oloam, czyli owszem wieloznakowe ale koniecznie o tej samej długości, czyli kolejne ograniczenie dla twego rozwiązania?


    Niekoniecznie.
    W 3-4 liniach 'wyulyskam' dlugosc komendy, podstawie zmienna do warunkow case i przy zmianie dlugosci komendy nawet nie trzeba bedzie zmieniac kodu..

    0
  • #18 06 Lis 2015 14:42
    -psiak-
    Poziom 32  

    oloam napisał:
    Niekoniecznie.
    W 3-4 liniach 'wyulyskam' dlugosc komendy, podstawie zmienna do warunkow case i przy zmianie dlugosci komendy nawet nie trzeba bedzie zmieniac kodu..
    W takim razie tabelka z kodami będzie bardzo daleko od jakiegokolwiek kojarzenia co przy tym kodzie się zrobi, rozwiązanie baaardzo błędotwórcze. Tak a propos nawet przy jednoliterowym kodzie już jest zbyt daleko. Radzę takie rzeczy trzymać blisko siebie, unikniesz wielu problemów, zwłaszcza przy dużych projektach.

    0
  • #19 06 Lis 2015 15:07
    oloam
    Poziom 20  

    Bzdura.
    1.Po to sa zmienne globalne.
    2.Podpowiedz do prostoty (i nieskomplikowania) kodu:
    -string jest jakby tablica, kazda litere w (w tym liczby) mozesz porownac do siebie
    - znaki od '1' do '9' leza kolo siebie
    -uzywam tylko operacji na stringach
    jezeli zmienie kocd na (chyba 4 linie) sprawdzanie dlugosci komendy, to komendy moga miec dowolna ilosc, program bedzie uniwersalny , i bedzie mimowolne sprawdzanie poprawnosci ramki...

    0
  • #20 06 Lis 2015 15:30
    -psiak-
    Poziom 32  

    Nie zrozumiałeś, wg twojego pomysłu na kody o różnej długości:

    Kod: delphi
    Zaloguj się, aby zobaczyć kod
    Patrze na tą 6-ke i się zastanawiam którego kodu literowego ona dotyczy? Dzeta czy Eta? Czy wszystko dobrze?
    A teraz wyobraź sobie że kodów będzie dużo, np 50.
    Poza tym przy każdym z 50 taka sama mało czytelna litania?
    Wydaje mi się że nigdy nie uczestniczyłeś w tworzeniu naprawdę dużych projektów.

    0
  • Pomocny post
    #21 06 Lis 2015 16:00
    oloam
    Poziom 20  

    -psiak- napisał:
    // dalej pobieranie napisu

    Cego nie rozumiesz? komenda jest indexem tablicy? chyba do 7 umiesz liczyc.
    -psiak- napisał:
    // sprawdzamy i wyliczamy
    // Indeks

    Nie sprawdzasz indeksy tylko wyliczasz dlugosc komendy w zwiazku z tym nie mozna pomylic dzeta z eta (rozna ilosc liter). indeks liczsz ze str minus dlugosc komendy (copy(str,1, len); - cos w tym stylu
    Prosciej sie nie da...
    -psiak- napisał:
    Poza tym przy każdym z 50 taka sama mało czytelna litania?

    Jak nie umiesz optymalizowac kodu, to taka bedzie.
    -psiak- napisał:
    Wydaje mi się że nigdy nie uczestniczyłeś w tworzeniu naprawdę dużych projektów.

    Mylisz sie...

    0
  • Pomocny post
    #22 06 Lis 2015 18:59
    -psiak-
    Poziom 32  

    oloam napisał:
    Cego nie rozumiesz? komenda jest indexem tablicy? chyba do 7 umiesz liczyc.
    Ja umiem nawet do 47 policzyć tylko że nie będę musiał, to ty będziesz musiał ze swoim podejściem.
    oloam napisał:
    Nie sprawdzasz indeksy tylko wyliczasz dlugosc komendy w zwiazku z tym nie mozna pomylic dzeta z eta ...
    Znowu nie zrozumiałeś, te komentarze pokazują wizualna odległość pomiędzy tablicą a numeracją w case Aby zobrazować że nie widać na pierwszy rzut oka że pomylona Eta i Dzeta
    oloam napisał:
    ... Prosciej sie nie da ...
    Od razu widać brak doświadczenia, podałem kilka wierszy kodu (ba wg twego pomysłu, lekko przerobione), a nie dałeś rady ich przeczytać, inaczej nie musiałbyś tłumaczyć jak zrobić to co w tym kodzie jest zawarte.
    oloam napisał:
    Jak nie umiesz optymalizowac kodu, to taka bedzie.
    Umiem, oraz próbuje nauczyć ciebie: - żadnych litanii tylko tablica struktur lub jeszcze lepiej lista obiektów.
    -psiak- napisał:
    Mylisz sie...
    I jakiego rozmiaru były projekty w których uczestniczyłeś?

    0
  • #23 08 Lis 2015 23:26
    CrisELDi
    Poziom 14  

    Mam nadzieje iż nie wywołałem awantury, ale miło poczytać jak mądrzy ludzie toczą inteligentną rozmowę. Może głupie pytanie ale zmodyfikować(w prosty sposób) paczkę i dodać dodatkowo sumy kontrolną paczki pozwoliło by zabezpieczyć komunikat/komunikację? Dziękuje za pomoc.

    0
  • #24 09 Lis 2015 00:01
    -psiak-
    Poziom 32  

    Skoro wysyłasz znak po znaku, to możesz (w teorii) stracić/zgubić dowolną część pakietu.
    Właśnie dlatego mają sens Prefix paczki oraz Suffix paczki (takie swoiste start stop) wewnątrz jakiś kod komendy (u ciebie: P,R,S) dalej jakieś parametry, na koniec suma kontrolna.
    Pamiętaj tyko, że niczego nie zabezpieczysz. Jedynie rozpoznasz, że jakaś komenda zwyczajnie nie dotarła i nie wykonasz jakiegoś Frankensteina (komendy sklejonej z kilku).

    0
  • #25 09 Lis 2015 00:33
    CrisELDi
    Poziom 14  

    OK, rozumiem .... Dziękuje za zainteresowanie tematem. Na czasie spróbuje w praktyce jak to działa i mam nadzieje, iż nie będę miał problemu z zaadaptowaniem zdobytej wiedzy.

    Thx.

    0