Problem z odczytem RS-a
Problem z odczytem RS-a
Witam
Mam mały problem z prawidłowym czytaniem RS-a. Przesyłam obrazek RS-em do komputera, Obrazek jest zakodowany na 470400 bajtach. Nie mogę czekać az przesłany zostanie caly obrazek gdyż wcześniej zapełni mi się bufor (rozmiar bufora to 4096). Postanowiłem więc czytać z bufora jak na obrazku poniżej po jednym wierszu który składa się z 1120 bajtów.
[img]http://bobo.ds5.agh.edu.pl/~bizona/RS.jpg[/img]
Problem jest taki że czasami zostaje przekroczona porównywana wartoś z bufora z liczba 1120 i zostaje przepełnony bufor ( program nie wychodzi z pętli nigdy). Dlaczego tak się dzieje? Jak na obrazku widać pomiedzy odczytywanymi wartosciami bajtow dla kolejnych wierszy nie wkonuję żadnych operacji co mogłoby wprowadzić opóźnienia i spowodować błedne działanie programu. Wie ktoś jak temu zaradzić? albo inaczej to rozwiązać?
Mam mały problem z prawidłowym czytaniem RS-a. Przesyłam obrazek RS-em do komputera, Obrazek jest zakodowany na 470400 bajtach. Nie mogę czekać az przesłany zostanie caly obrazek gdyż wcześniej zapełni mi się bufor (rozmiar bufora to 4096). Postanowiłem więc czytać z bufora jak na obrazku poniżej po jednym wierszu który składa się z 1120 bajtów.
[img]http://bobo.ds5.agh.edu.pl/~bizona/RS.jpg[/img]
Problem jest taki że czasami zostaje przekroczona porównywana wartoś z bufora z liczba 1120 i zostaje przepełnony bufor ( program nie wychodzi z pętli nigdy). Dlaczego tak się dzieje? Jak na obrazku widać pomiedzy odczytywanymi wartosciami bajtow dla kolejnych wierszy nie wkonuję żadnych operacji co mogłoby wprowadzić opóźnienia i spowodować błedne działanie programu. Wie ktoś jak temu zaradzić? albo inaczej to rozwiązać?
Re: Problem z odczytem RS-a
Witam
Oczywiście wykonujesz operacje, które wprowadzają opóźnienia !! Poza tym porównujesz typ całkowity z double lub single itd.
Należy tak:
1. Skonfigurować port szeregowy i przed wysyłaniem danych przez port szeregowy wyczyścić bufor
2. rozpocząć odbieranie danych (VISA Read) z określonym timeout. Dane odbierane w wielkości np. 1120 (lub innej np. 2240) dodajemy do tablicy. Ta liczbę bajtów należy podpiąć do bloczka VISA Read.
3. Koniec albo po odebraniu 420 (lub 210) buforów po 1120 bajtów lub po otrzymaniu znaku końca obrazka
4. Złożyć dane z tablicy - to można robić na bieżąco w pętli czytającej z portu szeregowego
pozdrawiam
pmaj
Oczywiście wykonujesz operacje, które wprowadzają opóźnienia !! Poza tym porównujesz typ całkowity z double lub single itd.
Należy tak:
1. Skonfigurować port szeregowy i przed wysyłaniem danych przez port szeregowy wyczyścić bufor
2. rozpocząć odbieranie danych (VISA Read) z określonym timeout. Dane odbierane w wielkości np. 1120 (lub innej np. 2240) dodajemy do tablicy. Ta liczbę bajtów należy podpiąć do bloczka VISA Read.
3. Koniec albo po odebraniu 420 (lub 210) buforów po 1120 bajtów lub po otrzymaniu znaku końca obrazka
4. Złożyć dane z tablicy - to można robić na bieżąco w pętli czytającej z portu szeregowego
pozdrawiam
pmaj
Nie jestem leniwy
Mam zawyżone wymagania motywacyjne
Mam zawyżone wymagania motywacyjne
Re: Problem z odczytem RS-a
Witam
Jedyne co może wprowadzać opóźnienie to jest porównywanie tych dwóch wartości. Praktycznie nie jest możliwe aby trwało to dłużej niż przesłanie jednego bajtu RS-em z prędkością 9600 bitów.
Wiec nie wiem co dalej moze byc zle jezeli zauwaza ktos jakies bledy to prosze o pomoc.
Pozdrawiam
jedrek
Zmieniłem stałą na typ całkowity i nie przyniosło to żadnych rezultatów.PMaj pisze:Witam
Oczywiście wykonujesz operacje, które wprowadzają opóźnienia !! Poza tym porównujesz typ całkowity z double lub single itd.
pmaj
Jedyne co może wprowadzać opóźnienie to jest porównywanie tych dwóch wartości. Praktycznie nie jest możliwe aby trwało to dłużej niż przesłanie jednego bajtu RS-em z prędkością 9600 bitów.
Czyż nie jest to tak zrobione jak widać na poprzednim obrazku. Zerowanie bufora przeniosłem przed pętle for aby tylko raz czyściło bufor.PMaj pisze: Należy tak:
1. Skonfigurować port szeregowy i przed wysyłaniem danych przez port szeregowy wyczyścić bufor
pmaj
Timeout nie odegra tu żadnej roli. Gdyż jeżeli przekroczy mi ustaloną wartość bajtów np. 1120 to już będę miał póżniej błędnie interpretowane wyniki. Zresztą nie mam dokładnie określonego czasu po jakim po wysłaniu danej mam otrzymac odpowiedz. Zalezne jest to jak długo bedzie przebiegała transmisja radiowa, gdyż wczesniej zanim wysle dane na port COM dane te sa wlasnie przesylane eterem. Reszta przecież jest tak zrobiona!!!PMaj pisze: 2. rozpocząć odbieranie danych (VISA Read) z określonym timeout. Dane odbierane w wielkości np. 1120 (lub innej np. 2240) dodajemy do tablicy. Ta liczbę bajtów należy podpiąć do bloczka VISA Read.
pmaj
Koniec powinien nastąpić po odebraniu 420 buforów i taka mam ustawiona liczbe wykonania petli. Na obrazku jest niższa wartośc alto to była ustawiona dla celów testowych. Nie ma czegos takiego jak znak konca obrazka.PMaj pisze: 3. Koniec albo po odebraniu 420 (lub 210) buforów po 1120 bajtów lub po otrzymaniu znaku końca obrazka
pmaj
Wykonuje to po odczytaniu wszystkich danych wlasnie zeby nie wprowadzac opoznien.PMaj pisze: 4. Złożyć dane z tablicy - to można robić na bieżąco w pętli czytającej z portu szeregowego
pmaj
Wiec nie wiem co dalej moze byc zle jezeli zauwaza ktos jakies bledy to prosze o pomoc.
Pozdrawiam
jedrek
Re: Problem z odczytem RS-a
Witam
petli FOR w buforze mogły już być dane, które są czyszczone
Reszta nie "jest tak zrobiona" - bo czytasz tyle danych ile jest w buforze, jeżeli pomiędzy opuszczeniem pętli while a rozpoczęciem VISA READ dotrze ci jakiś bajt, to stracisz najstarszy
poniżej pomysł aby nie być gołosłownym - ale nie ręcze że od razu zadziała - to tylko zarys i jeszcze brakuje kilku rzeczy - to juz wedle uznania Dodatkowo pętlę FOR można zamienić na WHILE z koncem po wykonaniu 420 iteracji lub po błędzie VISA - tak byloby poprawniej
pozdrawiam pmaj
To, że zmiana na typ całkowity nie przyniosła rezultatu to nie znaczy, że nie mogła - liczba niecałkowita mogła nie być równa całkowitej - to sie zdarza.jedrek pisze:Zmieniłem stałą na typ całkowity i nie przyniosło to żadnych rezultatów
Wykonanie porównania nie trwa długo, ale odwołanie sie do biblioteki VISA, czyli do portu szeregowego i odebranie żądanej odpowiedzi niekoniecznie jest szybkie i zależy od wielu czynników, nawet od Windowsa - tu jest bardzo duże prawdopodobieństwo na "przegapienie" momentu spełnienia warunku równości i to z pewnością sie dzieje.jedrek pisze:Jedyne co może wprowadzać opóźnienie to jest porównywanie tych dwóch wartości. Praktycznie nie jest możliwe aby trwało to dłużej niż przesłanie jednego bajtu RS-em z prędkością 9600 bitów."
Jeżeli przeniosłeś czyszczenie przed pętle for to OK, jak jest tak jak na rysunku, to jest źle, ponieważ po odczycie danych i przed kolejną iteracjąjedrek pisze:Czyż nie jest to tak zrobione jak widać na poprzednim obrazku. Zerowanie bufora przeniosłem przed pętle for aby tylko raz czyściło bufor.
petli FOR w buforze mogły już być dane, które są czyszczone
Nie po to jest timeout !!!!!!!!! (te wykrzykniki są niepotrzebne, podobnie jak w Twoim poście) Napisałem wyraĹşnie, że należy rozpocząć odbieranie przy użyciu VISA READ - jeżeli nie ustawisz wcześniej odpowiedniego timeoutu to jeżeli nie otrzymasz bitów to nie opuścisz funkcji! (timeout jest domyślny na 10s) - po to jest timeout. Idea polega na tym, ze nie czytasz dopiero jak sprawdzisz czy w buforze jest odpowiednia ilość bajtów, tylko bez sprawdzania czekasz na odpowiednią ilość bajtów.jedrek pisze:Timeout nie odegra tu żadnej roli. Gdyż jeżeli przekroczy mi ustaloną wartość bajtów np. 1120 to już będę miał później błędnie interpretowane wyniki. Zresztą nie mam dokładnie określonego czasu po jakim po wysłaniu danej mam otrzymać odpowiedz. Zależne jest to jak długo będzie przebiegała transmisja radiowa, gdyż wcześniej zanim wyśle dane na port COM dane te sa wlasnie przesyłane eterem. Reszta przecież jest tak zrobiona!!!
Reszta nie "jest tak zrobiona" - bo czytasz tyle danych ile jest w buforze, jeżeli pomiędzy opuszczeniem pętli while a rozpoczęciem VISA READ dotrze ci jakiś bajt, to stracisz najstarszy
To zależy jaki jest rozmiar bufora, który może być rózny - to raczej oczywistejedrek pisze:Koniec powinien nastąpić po odebraniu 420 buforów i taka mam ustawiona liczbę wykonania petli. Na obrazku jest niższa wartość alto to była ustawiona dla celów testowych. Nie ma czegos takiego jak znak konca obrazka.
To akurat żadno opóĹşnieniejedrek pisze:Wykonuje to po odczytaniu wszystkich danych wlasnie zeby nie wprowadzać opóĹşnień
Jeżeli nie zmieniłeś struktury programu to nadal jest Ĺşle. Wszystko się rozbija o tego wewnętrznego WHILEaWiec nie wiem co dalej moze byc zle jezeli zauwaza ktos jakies bledy to prosze o pomoc. Pozdrawiam
poniżej pomysł aby nie być gołosłownym - ale nie ręcze że od razu zadziała - to tylko zarys i jeszcze brakuje kilku rzeczy - to juz wedle uznania Dodatkowo pętlę FOR można zamienić na WHILE z koncem po wykonaniu 420 iteracji lub po błędzie VISA - tak byloby poprawniej
pozdrawiam pmaj
Nie jestem leniwy
Mam zawyżone wymagania motywacyjne
Mam zawyżone wymagania motywacyjne
Re: Problem z odczytem RS-a
Witam
Dzieki PMAJ za wyjasnienie sprawy, przy pierwszym poscie inaczej to rozumialem. Teraz wprawdzie odbiera mi odwiednia ilosc bajtow tzn. nie gubi mi juz bajtow ale jest inny problem. Odebranych jest pewna ilosc bajtow jest to okolo 9618 bajtow i nastepuje jakby przepelnienie bufora i dalszy odbior danych nie nastepuje. Wyglada na to jakby po odbiorze ustawionej liczby bajtow (u mnie jest to wartosc dlugosci wiersza obrazka) nie nastepowalo zerowanie bufora. Czy jest to mozliwe? Jaki jest maksymalny rozmiar bufora? Prubowalem ustawiac za pomoca bloczka VISA Set I/O Buffer Size ale nie dalo to zadnych rezultatow:( Po co w swojej idei uzywasz bloczka Flush I/O buffer?
A moj program wygladam tak:
Dzieki PMAJ za wyjasnienie sprawy, przy pierwszym poscie inaczej to rozumialem. Teraz wprawdzie odbiera mi odwiednia ilosc bajtow tzn. nie gubi mi juz bajtow ale jest inny problem. Odebranych jest pewna ilosc bajtow jest to okolo 9618 bajtow i nastepuje jakby przepelnienie bufora i dalszy odbior danych nie nastepuje. Wyglada na to jakby po odbiorze ustawionej liczby bajtow (u mnie jest to wartosc dlugosci wiersza obrazka) nie nastepowalo zerowanie bufora. Czy jest to mozliwe? Jaki jest maksymalny rozmiar bufora? Prubowalem ustawiac za pomoca bloczka VISA Set I/O Buffer Size ale nie dalo to zadnych rezultatow:( Po co w swojej idei uzywasz bloczka Flush I/O buffer?
A moj program wygladam tak:
Re: Problem z odczytem RS-a
Hej !
Flush I/O buffer używam dlatego, że w buforze mogło coś być na początku i zostałoby to wczytane jako początkowa część obrazka. Osobiście uważam, że konfigurując port należy założyć, że jest on pusty, a że może nie być pusty to należy go wyczyścić.
Jeżeli po odebraniu pewnej części informacji funkcja READ przestaje zwracać dane, to znaczy że dane przestają docierać do portu.
To z kolei może oznaczać np. różne prędkości wysyłania i odbierania, (wysalanie szybciej a odbieranie wolniej)
Możesz też spróbować odbierać jednorazowo więcej bajtów - np. 2 razy więcej bajtów jednorazowo i wtedy 2 razy mniej iteracji pętli FOR = mniej wywołań funkcji READ. Chociaż wątpię czy to mogłoby pomóc.
Nie wiem czy poprawnie wpisujesz "termination char" na wejściu funkcji CONFIG SERIAL PORT - jeżeli go nie używasz to powinien być nie aktywny a widzę, że jest aktywny i domyślny. Czy na pewno linia kończy się "n" ? - nie powinieneś w takim przypadku używać termination char.
Albo czytasz linia po linii wykorzystując znak końca linii albo czytasz po kawałku nie używając tego znaku. Nie potrafię teraz powiedzieć czy to jest powodem błędu.
Niestety teraz więcej nie pomogę, bo mam za mało informacji. Spróbuj podejrzeć na "żarówce" co się dzieje jak przestajesz odbierać dane.
pozdrawiam
pmaj
Nie wiem teraz jaki jest maksymalny rozmiar bufora, ale w takiej konfiguracji bufor sie nie przepełnia. Ja stosuje podobną konfigurację do ciągłego czytania portu szeregowego i nawet po kilku dniach nie mam takiej sytuacji. Stąd odpowiedź, ze przepełnienie bufora w takiej konfiguracji jest mało prawdopodobne.jedrek pisze:...jest inny problem. Odebranych jest pewna ilosc bajtow jest to okolo 9618 bajtow i nastepuje jakby przepelnienie bufora i dalszy odbior danych nie nastepuje. Wyglada na to jakby po odbiorze ustawionej liczby bajtow (u mnie jest to wartosc dlugosci wiersza obrazka) nie nastepowalo zerowanie bufora. Czy jest to mozliwe? Jaki jest maksymalny rozmiar bufora?
Flush I/O buffer używam dlatego, że w buforze mogło coś być na początku i zostałoby to wczytane jako początkowa część obrazka. Osobiście uważam, że konfigurując port należy założyć, że jest on pusty, a że może nie być pusty to należy go wyczyścić.
Jeżeli po odebraniu pewnej części informacji funkcja READ przestaje zwracać dane, to znaczy że dane przestają docierać do portu.
To z kolei może oznaczać np. różne prędkości wysyłania i odbierania, (wysalanie szybciej a odbieranie wolniej)
Możesz też spróbować odbierać jednorazowo więcej bajtów - np. 2 razy więcej bajtów jednorazowo i wtedy 2 razy mniej iteracji pętli FOR = mniej wywołań funkcji READ. Chociaż wątpię czy to mogłoby pomóc.
Nie wiem czy poprawnie wpisujesz "termination char" na wejściu funkcji CONFIG SERIAL PORT - jeżeli go nie używasz to powinien być nie aktywny a widzę, że jest aktywny i domyślny. Czy na pewno linia kończy się "n" ? - nie powinieneś w takim przypadku używać termination char.
Albo czytasz linia po linii wykorzystując znak końca linii albo czytasz po kawałku nie używając tego znaku. Nie potrafię teraz powiedzieć czy to jest powodem błędu.
Niestety teraz więcej nie pomogę, bo mam za mało informacji. Spróbuj podejrzeć na "żarówce" co się dzieje jak przestajesz odbierać dane.
pozdrawiam
pmaj
Nie jestem leniwy
Mam zawyżone wymagania motywacyjne
Mam zawyżone wymagania motywacyjne
Re: Problem z odczytem RS-a
Witam
Błąd tkwił nie w tym programie tylko w aplikacji która wysyłała dane. Miałem ustawiony krótki czas timeout i nie zdążyło wysłać wszystkich danych bo nastepował timeout.
Jednak nie dokońca wszystko działa, program zachowuje się troche dziwnie, bo przy niektórych uruchomieniach wychodzi mi z tej pętli po mniejszej liczbie iteracji niż jest ustawiona. Nie zawsze się tak dzieje i nie widze reguły żadnej. O co tu może chodzić??
P.S. Rzeczywiście nie używam żadnego końca linii ale po zmienieniu tego nie wpłyneło to na działanie mojego programu.
Błąd tkwił nie w tym programie tylko w aplikacji która wysyłała dane. Miałem ustawiony krótki czas timeout i nie zdążyło wysłać wszystkich danych bo nastepował timeout.
Jednak nie dokońca wszystko działa, program zachowuje się troche dziwnie, bo przy niektórych uruchomieniach wychodzi mi z tej pętli po mniejszej liczbie iteracji niż jest ustawiona. Nie zawsze się tak dzieje i nie widze reguły żadnej. O co tu może chodzić??
P.S. Rzeczywiście nie używam żadnego końca linii ale po zmienieniu tego nie wpłyneło to na działanie mojego programu.
- wino
- Posty: 549
- Rejestracja: 23 gru 2005 00:00
- Wersja środowiska: Nie mam LabVIEW
- Lokalizacja: Kraków
Re: Problem z odczytem RS-a
zauważ, że do terminala N w twojej pętli podłączyłeś kabel, który ma inny typ danych niż wspomniany wyżej terminal.
Może to sprawia, że pętla kręci się mniej razy niż tego sobie życzysz.
Może to sprawia, że pętla kręci się mniej razy niż tego sobie życzysz.
Re: Problem z odczytem RS-a
Witam
Wino: rzeczywiście jest inny typ danych, ale U32 to zdecydowanie wystarczy - poza tym to nie może być przyczyną błędu skoro program sie czasem dobrze wykona
Jedrek: Możesz próbować popatrzeć na informacje o błędzie - tzn. czy był jakiś błąd ze wyszedł z pętli? Generalnie nawet jak był błąd to powinien wykonać poprawną ilość iteracji tyle że bez danych.
Podejrzewam, że problem jest ciągle w komunikacji. Jak masz możliwość to weź oscyloskop i popatrz co idzie w kablu jak otrzymujesz błąd. Wydaje mi się, ze jeżeli otrzymujesz błędne dane, to dlatego ze nie ma synchronizacji - ale tego nie wiem. Powinieneś najpierw włączyć twój program do czytania i potem (aby sie zmieścić w timeout tak, że funkcja nie wyjdzie za wcześnie) włączyć nadawanie.
Powodzenia w walce
pmaj
Wino: rzeczywiście jest inny typ danych, ale U32 to zdecydowanie wystarczy - poza tym to nie może być przyczyną błędu skoro program sie czasem dobrze wykona
Jedrek: Możesz próbować popatrzeć na informacje o błędzie - tzn. czy był jakiś błąd ze wyszedł z pętli? Generalnie nawet jak był błąd to powinien wykonać poprawną ilość iteracji tyle że bez danych.
Podejrzewam, że problem jest ciągle w komunikacji. Jak masz możliwość to weź oscyloskop i popatrz co idzie w kablu jak otrzymujesz błąd. Wydaje mi się, ze jeżeli otrzymujesz błędne dane, to dlatego ze nie ma synchronizacji - ale tego nie wiem. Powinieneś najpierw włączyć twój program do czytania i potem (aby sie zmieścić w timeout tak, że funkcja nie wyjdzie za wcześnie) włączyć nadawanie.
Powodzenia w walce
pmaj
Nie jestem leniwy
Mam zawyżone wymagania motywacyjne
Mam zawyżone wymagania motywacyjne