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.

AVR, Enkoder, Delphi Odczyt pozycji przez RS.

Proteus76 15 Lut 2011 11:17 4516 33
  • #1 15 Lut 2011 11:17
    Proteus76
    Poziom 9  

    Witam !

    Proszę o pomoc w rozwiązaniu takiego problemu. Mam układ obliczający długość przewodu za pomocą Enkodera Kubler (1000 imp.) wykonany na mikrokontrolerze
    ATmega8535. Procesorek ładnie zlicza impulsy z wyjścia INT0, rozpoznaje kierunki oraz wyświetla wszystko na LCD. Problem polega na tym że muszę mieć odczyt długości na aplikacji PC. Wszystko zrealizowałem na BASCOM-ie oraz Delphi. RS działa jednak występują problemy z komunikacją tzn. aplikacja wyświetla mi tylko część wysłanego z procesora poleceniem print komunikatu np. zamiast 1024 tylko 24 lub 024 itp. Na Delphi korzystam z komponentu Comport (wyświetla znak w oknie kiedy zajdzie zdarzenie RXchar). Próbowałem zwolnić transmisję, właczyć bufor wyjściowy portu w BASCOM-ie, powiesić wysyłanie z procesora na przerywaniu z timera. Niestety nic nie pomogło. Dodam że Delphi to dla mnie nowość więc przypuszczam że coś robie nie tak od strony aplikacji PC. Z góry dziękuję za każdy post bo może uda mi się popchnąć dzięki temu projekt do przodu.

    0 29
  • #2 15 Lut 2011 11:47
    mgyz
    Poziom 13  

    włącz w komponencie ComPort buforowanie danych.

    0
  • #3 15 Lut 2011 11:58
    Proteus76
    Poziom 9  

    Jak mówiłem Delphi to dla mnie nowość. Więc bardzo proszę o dokładniejsze informacje.

    0
  • #4 15 Lut 2011 12:45
    LordBlick
    VIP Zasłużony dla elektroda

    Najprościej, to jakby ATmega udawała klawiaturę (wysyłając kody klawiszy po wciśnięciu jakiegoś przycisku kończącego pomiar), to i nie trzeba by było cudować i działałoby na każdym systemie operacyjnym.

    0
  • #5 15 Lut 2011 21:54
    Proteus76
    Poziom 9  

    Tak, tylko że pomiar następuje w sposób ciągły i wymagane jest też wyświetlanie wyniku w czasie rzeczywistym. Wszystko wydawało się bardzo proste ale jak zwykle diabeł tkwi w szczegółach. Nie jestem przekonany że buforowanie pomoże.

    0
  • #6 15 Lut 2011 22:19
    asembler
    Poziom 32  

    Widze że gubi ci poczatkowe znaki. Możnaby dołączyć przedwynikiem kilka pustych znakow. Oczywiscie nie jest to rozwiazanie problemu ale jezeli tak jest to bedzie wiadomo gdzie szukac przyczyny.

    0
  • #7 15 Lut 2011 23:26
    mgyz
    Poziom 13  

    A mi się wydaje, że buforowanie może pomóc, bo jak odbierasz po jednym znaku to zanim program zajmie sie jego obsługą i go wyświetli (czy tam cokolwiek z nim zrobi) to przez ten czas może nadejść kolejny znak a program nie będzie na niego gotowy - będzie robił co innego a nie czekał na znak. Przy włączonym buforze jak program dojedzie do odbioru kolejnego znaku to po prostu wyjmie sobie go z bufora.

    Jeszcze jedno przyjżyj się ustawieniom time-out'ów na odbiór znaku/ ciągu znaków (w helpie jest to opisane)

    0
  • #8 16 Lut 2011 00:13
    asembler
    Poziom 32  

    Z tym że buforowanie od strony PC a autor pisał że od strony AVR spowalniał transmisje i nic nie dało.

    0
  • #9 16 Lut 2011 00:29
    mgyz
    Poziom 13  

    a co ja napisałem?

    mgyz napisał:
    włącz w komponencie ComPort buforowanie danych.

    0
  • #10 16 Lut 2011 12:19
    Proteus76
    Poziom 9  

    Hmm... Tylko na moim poziomie umiejętności w temacie Delphi stwierdzenie "włacz bufor w Comporcie jest" dosyć abstrakcyjne. Czy może ktoś dokładnie opisać co i jak a najlepiej wkleić kawałek niezbędnego kodu. Dalej mam nadzieję poradze sobie sam.

    0
  • #11 16 Lut 2011 14:25
    mgyz
    Poziom 13  

    Z tego co pamiętam to chyba wystarczy we właściwościach kontrolki znaleźć pole bufout oraz bufin i ustawić wartość większą od zera

    0
  • #12 16 Lut 2011 15:25
    Piotrek_P
    Poziom 18  

    nie wiem co tam masz w kodzie Delphi, ale procedura wzięta żywcem z przykładowych programów ComPort'a działa bez zarzutu. Sprawdzone wiele razy.

    Code:

    procedure TForm1.ComPortRxChar(Sender: TObject; Count: Integer);
    var
      Str: String;
    begin
      ComPort.ReadStr(Str, Count);
      Memo.Text := Memo.Text + Str;
    end;



    Mając zawartość bufora w zmiennej Str można już dalej bawić się po swojemu.
    Acha, bufor in/out jest domyślnie ustawiony na 1024 więc przy prostych zastosowaniach nic nie trzeba zmieniać.

    0
  • #13 01 Gru 2011 13:44
    GL4DI470R
    Poziom 10  

    Witam !
    Mam podobny problem z którym jeszcze się nie uporałem. Ale w tym poście chodzi mi o coś innego. Otóż napisałem malutki programik który w ramach możliwości będę rozwijał, narazie umiem odczytywać dane z avr po chłopsku czyli tak jak leci.
    A chodzi mi o to żeby AVR wysyłał z 4 różne zmienne które aplikacja będzie rozpoznawała i umieszczała wynik w odpowienim memo i nie mam pojęcia jak to zrobić. Dodam jeszcze że probram do atmegi jest pisany w Bascom.
    Własnymi siłami próbowałem zrobić to w taki sposób że od strony avr będą 4 zmienne np x,y,z,q i teraz avr najpierw wyśle znak "x" który zostanie odebrany w aplikacji przez pętlę if str=x, w następnej kolejności zostanie wysłana wartość tego x i wartość ta zostanie umieszczona w memo1, później y itd.

    Korzystam z kompomentu ComPort i odczytuję z Atmegi 16 dane w taki sposób :

    procedure TForm1.ComPortRxChar(Sender: TObject; Count: integer );
    var
    str: string;
    begin
    ComPort1.ReadStr(str,count);
    Memo1.text := str;
    end;
    Aplikacja wygląda tak:

    AVR, Enkoder, Delphi Odczyt pozycji przez RS.

    Na koniec dodam że inspiracją tego projektu jest Pan mirekk36 za co mu serdecznie dziękuję !
    Pozdrawiam i proszę o pomoc !

    0
  • #14 01 Gru 2011 18:17
    Piotrek_P
    Poziom 18  

    Ja bym to zrobił tak. Przed wysłaniem danej do PC, sformatował bym odpowiednio ramkę np do takiej postaci:
    *nr_zmiennej*wartość_zmiennej_jako_tekst

    Po odebraniu ramki, sprawdzamy nr_zmiennej:

    Kod: delphi
    Zaloguj się, aby zobaczyć kod


    Powinno działać. W razie dodatkowych pytań chętnie pomogę.

    Pozdrawiam
    Piotrek

    0
  • #15 02 Gru 2011 17:11
    GL4DI470R
    Poziom 10  

    niestety nie umiem z tego skorzystać. Jestem zielony jeśli chodzi o Delphi i ucze się na zasadzie prób i błędów.
    próbowałem w ten sposób:



    procedure TForm1.ComPortRxChar(Sender: TObject; Count: integer );
    var
    str: string;
    str2:string;




    begin
    ComPort1.ReadStr(str,count);
    if (str='1') then
    ComPort1.WriteStr('1');
    ComPort1.ReadStr(str2,count);
    memo1.text:=str2 ;

    ComPort1.ReadStr(str,count);
    if (str='1') then
    ComPort1.WriteStr('2');
    ComPort1.ReadStr(str3,count);
    memo1.text:=str3 ;
    end;

    I miało to wyglądać tak, że uC wysyła print "1" czyli 1 jako string, aplikacja to odbiera wchodzi w 1 pętlę if, wysyła uC "1" jako znak że jest gotowa do odbioru pierwszej zmiennej do memo1. uC po wysłaniu tej zmiennej miałby wysłać "2" aplikacja mialaby wejsc w nastepna petle if i wpisac kolejna wartosc do memo2 niestety ten sposob nie dziala i ni cholery nie wiem dlaczego.

    0
  • #17 05 Gru 2011 06:50
    mirekk36
    Poziom 42  

    Bardzo przepraszam, że się wcześniej nie odezwałem w tym temacie ale mail mi umknął :(

    Kolega zdaje mi się (tak na szybko) o ile dobrze pamiętam komponent ComPort źle korzysta z jego zdarzeń :( .... a przecież razem z ComPort są przykładowe programy i tam można podejrzeć jak się to robi. Zaglądał tam kolega ?

    0
  • #18 05 Gru 2011 17:00
    GL4DI470R
    Poziom 10  

    Cytat:
    Ciekaw jestem szczegolow projektu, mozna sie dowiedziec czegos wiecej?

    A więc cały komputer mam chłodzony wodą, do tego pasjonuję się elektroniką i wpadłem na pomysł żeby wszystko co się da, wentylatory, pompkę, temperaturę, oświetlenie, kontrolować przy pomocy uC. Potem postanowiłem ustawić poprzeczkę wyżej i kontrolować to nie tylko za pomocą uC ale i myszką z poziomu Windowsa. Patrząc na projekty Pana "mirekk36" pomyślałem że też tak chcę (wtedy jeszcze nie wiedziałem że Pan Mirek robi to zawodowo :) ), tak to się mniej więcej zaczęło.

    Cytat:
    Kolega zdaje mi się (tak na szybko) o ile dobrze pamiętam komponent ComPort źle korzysta z jego zdarzeń .... a przecież razem z ComPort są przykładowe programy i tam można podejrzeć jak się to robi. Zaglądał tam kolega ?

    Mój obraz działania programu jest "wypracowany" w Bascom, nie znam innego mimo że na studiach troszkę pisałem w C. Cała ta moja aplikacje jest mniej lub bardziej żywcem zerżnięta (przepraszam za słowo) właśnie z programów dołączonych do komponentu, także tak, zaglądałem tam i dzięki temu doszedłem do tego miejsca w którym jestem. Starałem się to "pchnąć" na różne sposoby przez ok. 4 dni i dalej lipa. Proszę o pomoc

    0
  • #19 05 Gru 2011 17:21
    mirekk36
    Poziom 42  

    Przyznam, że założenia projektu fajniutkie ;) ....

    Odnośnie programu, teraz przyjrzałem się tej procedurze to niestety hmm nie mam już dawno tego komponentu i nie pamiętam dokładnie obsługi, ale patrząc na kod widać jednak bardzo poważne błędy. I nie chodzi o to że coś tam jest źle napisane w jednym czy drugim miejscu.

    Po prostu kolega jeszcze nie czuje jak odbierać dane asynchronicznie. Ten komponent oczywiście to umożliwia ale nie na zasadzie, że cały twój kod programu do obsługi odbieranych danych wstawisz do tego zdarzenia :(

    Przecież pomyśl sobie - taka prosta rzecz, masz parametr Count, a to już świadczy o tym, że może zostać odebrany string o różnej długości .... tymczasem ty poniżej robisz proste (zbyt proste i niestety złe porównanie)

    if (str='1') then

    a zastanowiłeś się co stanie się ze znakami ENTER jeśli je w ogóle używasz ? a jeśli nie to źle - lepiej użyć wtedy można w takim zdarzeniu sprawdzać kiedy nadleciał enter i dopiero wtedy porównywać odebrany string (wyłączając z niego enter za pomocą chociażby Trim) i zakładając że będziesz sprawdzał dokładnie to co wysyłasz z procka.

    Generalnie chodzi jak zwykle o wyrobienie sobie i nauczenie się najprostszych mechanizmów parsowania (analizowania) nadlatujących danych. Dlatego wskazówka - przesyłaj je przede wszystkim jako znaki ASCII. A ty nie pokazałeś jak robisz to na procku - a też możesz robić wszystko "do góry nogami" - dlatego ciężko z uruchomieniem tego :(

    dlatego przemyśl przede wszystkim poprawne wysyłanie tych zmiennych i jeszcze raz podpowiadam jako znaki ASCII a nie binarnie

    na końcu każdej przesyłki dawaj SAM ENTER

    a w Delphi sprawdzaj kiedy nadleciał ENTER i to co jest przed nim to twoja zmienna jako string ;)

    Może chociaż taka wskazówka na coś cię naprowadzi ..... A jeszcze raz powiem, że fajny projekt i sam z chęcią zobaczyłbym efekt końcowy ;)

    powodzenia

    0
  • #20 05 Gru 2011 19:10
    GL4DI470R
    Poziom 10  

    Cytat:
    a zastanowiłeś się co stanie się ze znakami ENTER jeśli je w ogóle używasz ? a jeśli nie to źle

    To pierwszy słuszny zarzut, znak Enter (czyli znak przejścia do początku następnej linii) jest automatycznie wysyłany przez Basom, a dokładniej instrukcję Print.

    Cytat:
    Dlatego wskazówka - przesyłaj je przede wszystkim jako znaki ASCII. A ty nie pokazałeś jak robisz to na procku - a też możesz robić wszystko "do góry nogami" - dlatego ciężko z uruchomieniem tego

    W Bascom to jest tak, że do wysyłania danych przez usart jest kilka instrukcji, z czego instrukcja PRINT wysyła zmienne/stałe wartości znaków w kodzie ASCII.

    Cytat:
    i dopiero wtedy porównywać odebrany string (wyłączając z niego enter za pomocą chociażby Trim)

    czy wystarczy zastosować coś takiego ?
    Write(Trim(zmienna));

    Cytat:
    a w Delphi sprawdzaj kiedy nadleciał ENTER i to co jest przed nim to twoja zmienna jako string

    może jakaś próbka kodu w jaki sposób to sprawdzić?

    0
  • #21 05 Gru 2011 19:30
    Piotrek_P
    Poziom 18  

    Nie wiem czy moje posty są niewidoczne? Dałem wyżej przykład i komentarz, że jak wysyłamy jakiś "string" z BASCOMA to należy po odebraniu odciąć DWA ostatnie bajty którymi są znaki końca linii (CRLF)

    0
  • #22 07 Gru 2011 16:42
    GL4DI470R
    Poziom 10  

    Cytat:
    Nie wiem czy moje posty są niewidoczne? Dałem wyżej przykład i komentarz, że jak wysyłamy jakiś "string" z BASCOMA to należy po odebraniu odciąć DWA ostatnie bajty którymi są znaki końca linii (CRLF)

    próbowałem zastosować, narazie nie idzie także bez nerwów :)

    aplikacja minimalnie ewoluowała,
    AVR, Enkoder, Delphi Odczyt pozycji przez RS.

    co do odbioru wielu zmiennych dalej lipa ;/
    Pozdrawiam

    0
  • #23 15 Gru 2011 10:44
    GL4DI470R
    Poziom 10  

    Witam!
    mam problem ze znikającymi znakami z memo i w końcu wiem skąd to się bierze ale nie wiem dlaczego .
    Otóż wygląda to tak że memo1.text:=str posiada jakby 80 miejsc na znaki.
    znaki z uC wysyłam za pomocą Print (zmienna);chr(13) czyli z komendą powrotu do początku lini co oznacza że po odczytaniu liczby "3.23 V" powinienem zając od początku 6 znaków. Przed następnym odczytem czyszczę memo za pomocą memo1.clear i odczytuje kolejną wartość. Tak to wygląda w teorii w praktyce jest tak że po odczycie 13x danych z uC (13x5znaków =78) dochodzi do jakiegoś dziwnego przepełnienia i odczytane zostają 2 liczby i wpisane do memo i dopiero w kolejnym odczycie wszystko wraca do normy.
    Mam nadzieje że opisałem to w miarę dokładnie, ktoś pomoże?

    0
  • #24 17 Gru 2011 13:07
    GL4DI470R
    Poziom 10  

    masakara jakie tu jest zainteresowanie.

    0
  • #25 17 Gru 2011 13:43
    Piotrek_P
    Poziom 18  

    Wyluzuj kolego :-) Jak Ci napisałem kawałek kodu i nie mogłeś z tego skorzystać to też byłem lekko poirytowany, bo poświęciłem trochę czasu. Od Bascoma odszedłem 5 lat temu i starych działających kodów chyba już nie mam, ale mogę pomóc jak trzeba (na ile pamiętam). Zamieść kod Bascomowy, albo poślij do mnie na PW to zobaczę o co biega.

    PP

    0
  • #26 17 Gru 2011 17:10
    GL4DI470R
    Poziom 10  

    Kod: basic4gl
    Zaloguj się, aby zobaczyć kod



    Kod: delphi
    Zaloguj się, aby zobaczyć kod


    W sumie nie ma znaczenia czy wysyłam poprzez "PRINT T" CZY "PRINT T;" CZY "PRINT T;"CHAR(13);zawsze jest to samo po kilkunastu odczytach robi się bałagan i po chwilli wraca do normy. Nie ma też znaczenia czy w memo1.text odczytam poprostu "str", czy poszczególne bajty jak to widać w listingu, robi się to samo dołączam filmik żeby pokazać o co chodzi.

    Link

    0
  • #27 17 Gru 2011 18:53
    Piotrek_P
    Poziom 18  

    A co dostajesz po RSie na terminalu Windows :?:
    Może to coś pomoże w analizie. Aplikacją w Delphi można zająć się później

    0
  • #28 17 Gru 2011 20:06
    GL4DI470R
    Poziom 10  

    Sorry, ale nie za bradzo wiem o czym mówisz :)

    0
  • #29 18 Gru 2011 11:54
    Piotrek_P
    Poziom 18  

    Na początek skonfiguruj sobie połączenie COM w Terminalu Windows z prędkością transmisji jaką masz ustawioną w programie procka. Jak transmisja będzie OK to w oknie terminala będziesz widział jakie dane przychodzą do komputera i zweryfikujesz to z tym co wysyłasz.

    PP

    0
  • #30 18 Gru 2011 12:17
    GL4DI470R
    Poziom 10  

    Tak wygląda odbiór w dwóch różnych terminalach, 1 to Bascom a 2 to przykładowy dorzucony do komponentu comport, widać na nich że nie ma żadnego problemu z transmisją w obie strony, po wysłaniu do uC "1" kontroler odpowiada zmierzoną temperaturą.
    Dlatego od początku mówiłem że problem jest z prezentacją odebranego wyniku w aplikacji, gdybym każdy odebrany wynik wyświetlał tak jak w terminalu linijkę niżej niż poprzedni to nie ma problemu, natomiast jak chcę żeby wynik był cały czas w tym samym wierszu to wychodzi jak wychodzi.

    AVR, Enkoder, Delphi Odczyt pozycji przez RS.

    0