logo elektroda
logo elektroda
X
logo elektroda
REKLAMA
REKLAMA
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

Jak wyodrębnić dane z bufora RS232 w Delphi do wykresu TChart?

MAREK74 28 Gru 2005 00:11 3609 9
REKLAMA
  • #1 2121399
    MAREK74
    Poziom 20  
    Posty: 475
    Pomógł: 3
    Ocena: 13
    Witam
    Niedawno zacząłem "walke" z DELPHI i chce napisać program który by dane odebrane przez RSa wyswietlał w formie wykresu.
    Mam przykład z książki "RS232 Praktyczne programowanie" RS_27.pas
    tam jest właśnie taki wykres , zmodyfikowałem program tak że pyta się wartością 54h atmela 89c2051 ,a on odpowiada "TEMP 023,#10,#13" czyli
    temepratura 23 w st C.
    Mam z tym taki problem ,że nie wiem jak z bufora w którym jest to wszystko wyłuskać własnie te 023 ,które będzie tworzyc ten wykres.
    Można by zmienić program w procku żeby wysyłał tylko wartość ,ale nie o to chodzi.
    Jest tam wzmianka o jakiejs procedurze

    procedure val(S; var V; var Code: Integer);

    ale jej nigdzie nie ma ?!

    Co ja biedny mam z tym zrobic ? :)
  • REKLAMA
  • #2 2122195
    Piotrek_P
    Poziom 18  
    Posty: 253
    Pomógł: 24
    Witam

    Co do procedury "val" to Help się kłania. Służy ona do zamiany ciągu znaków na liczbę. Ma ona tą zaletę że zwraca kod błędu konwersji. Nie wiem jak wygląda ten program z książki ale jeżeli ramka danych się nie zmienia to można zrobić np tak:

    _temperatura_ := StrToInt(Copy(_bufor_, _pozycja_ , _ilosc_znakow_));

    gdzie:
    _temperatura_ : to wynik zamiany stringa na integer
    _bufor_ : wiadomo, ciąg znaków z portu
    _pozycja_ : czytamy bufor od np 5-tego znaku
    _ilosc_znakow_ : interesują nas np tylko trzy

    Oczywiście zmienne muszą być wcześniej zadeklarowane.
    Pytanie, jak będzie wyglądać ramka jeżeli zmierzymy temeraturę ujemną?

    Pozdrawiam
    Piotrek
  • REKLAMA
  • #3 2140614
    MAREK74
    Poziom 20  
    Posty: 475
    Pomógł: 3
    Ocena: 13
    sytuacja wyglada tak:
    procek wysyła 15 , 10 , 13

    gdzie 15 to temperatura w hex
    10 i 13 to jakies tam wartości które sobie ot tak wysyłam

    bufor wejsciowy:
    const
    cbOutQueue = 32;

    var
    Buffer_I : ARRAY[0..cbInQueue] of Char; // bufor wejściowy

    zdefiniowany jako char bo przy zapytaniu 50h procek przedstawia się nazwą urządzenia która to nazwa wkładana jest do statusbar
    moge zrobic tak :

    temperatura := buffer_I[0];
    ale zmienna "temperatura" musiała by być tez jako char
    ale:
    Form1.Series1.AddXY(intVar, temperatura , '',clTeeColor);

    nie przyjmuje zmiennej "temperatura" jako char
    problem w tym że buffer_i jest ładowany raz danymi które są napisem a raz danymi w formie hex
    trza by przekonwertować buffer_I[0]; czyli pierwszą daną z bufora na byte lub integer żeby Form1.Series1.AddXY(intVar, temperatura , '',clTeeColor); ją przyjął

    jak by co to umieszcze tu cały program bo nie jest długi
  • REKLAMA
  • #4 2141203
    Piotrek_P
    Poziom 18  
    Posty: 253
    Pomógł: 24
    Jeżeli masz char a potrzebujesz integer to robisz tak:

    temperatura := StrToInt(bufor[0]);

    a potem robisz ze zmienną temperatura co chcesz.

    Pozdrawiam
    Piotrek
  • #5 2141437
    spros
    Poziom 17  
    Posty: 186
    Pomógł: 16
    Ocena: 26
    to 10 13 to znak konca wiersza. dostajesz poprostu wiersz jak ze strumienia?

    procedure val(S; var V; var Code: Integer);
    jest zdecydowanie lepsze od StrToInt. masz lepsza kontrole nad tym co otrzymasz.

    temperatura := StrToInt(bufor[0]); czy temperatura jest zawsze w zakresie 8bit? jesli nie to nie zadziala.

    a i jesli to przychodzi nie jako tekst to robi sie to prosto:
    temperatura = (byte)bufor[0];
    lub do dowolnego innego typu (_TYPE):
    temperatura = (_TYPE)bufor;

    jesli jako tekst to wykorzystaj "val". sprawdz wartosc code. jesli jest niezerowa to tylko tyle pierwszych liter w buforze da sie reprezentowac jako liczbe zmiennoprzecinkowa. mozesz wtedy probowac konwersji dokladnie takiej liczby znakow. umozliwia to np. konwersje lancucha "23.45ghskfdj"
    pierwszy val da code = 5 wiec teraz bierzemy tylko 5 pierwszych znakow "23.45" i konwertujemy do 23.45. co wiecej mozesz uzyskac prawidlowa wartosc jesli tekst bedzie np: "1.23456e-3" przekonwertuje ci jako 0.00123456
  • REKLAMA
  • #6 2147101
    MAREK74
    Poziom 20  
    Posty: 475
    Pomógł: 3
    Ocena: 13
    zmieniłem bufor wejściowy na byte i uruchomiłem temperature czyli jest odkładana na osi pionowej i wyswietlana w okienku
    ale nie moge uruchomic drugiej danej która jest dwubajtowa czyli w tym przykładzie 10 13 w dec (0Ah 0Dh) chce ją odkładac na osi poziomej kombinuje jak koń i nic

    Buffer_I : ARRAY[0..cbInQueue] of word; // bufor wejściowy
    obroty : word;

    obroty := Copy(buffer_i, 1, 2);

    lipa
    Buffer_I : ARRAY[0..cbInQueue] of byte; // bufor wejściowy
    obroty : word;

    obroty := Copy(buffer_i, 1, 2);
    lipa
  • #7 2148182
    spros
    Poziom 17  
    Posty: 186
    Pomógł: 16
    Ocena: 26
    10 13 w dec (0Ah 0Dh)

    to znak konca linii. prawdopodobnie informuje o koncu strumienia danych.

    lipa. jak dostajesz worda to zrob tak:

    Buffer_I : ARRAY[0..cbInQueue] of byte; // bufor wejściowy
    obroty : word;

    obroty := (word)Buffer_I;

    nie mam kompliatora ale zobacz.


    w porywach porwij sie na taka rzecz (tez bez testow):
    Buffer_I : ARRAY[0..cbInQueue] of byte; // bufor wejściowy
    bufptr : pointer;
    obroty : word;

    bufptr := ^Buffer_I;
    obroty := (word)bufptr^;
  • #8 2151110
    MAREK74
    Poziom 20  
    Posty: 475
    Pomógł: 3
    Ocena: 13
    HA
    zrobiłem łopatologicznie:

    Buffer_I : ARRAY[0..cbInQueue] of byte; // bufor wejściowy
    obrotyl : byte;
    obrotyh : byte;
    obroty : word;

    obrotyh :=(buffer_i[1]);
    obrotyl :=(buffer_i[2]);
    obroty :=(256*obrotyh);
    obroty :=(obrotyl+obroty);

    Form1.Series2.AddXY(obroty , buffer_I[0] , '',clTeeColor);

    i..... działa
    musze jeszcz popracowac na programem z procka żeby komunikacja nie bruździła w pomiarach
  • #9 2264852
    MAREK74
    Poziom 20  
    Posty: 475
    Pomógł: 3
    Ocena: 13
    witam ponownie
    wykres działa w trzech kolorach:)
    jak go teraz zapisać ale jako np .jpg
  • #10 2271296
    MAREK74
    Poziom 20  
    Posty: 475
    Pomógł: 3
    Ocena: 13
    ..to odpowiem sam sobie(i dla innych)

    Chart1.SaveToBitmapFile('wykres'); i mamy plik w formacie .bmp
    duży...ale na początek może być :)

Podsumowanie tematu

✨ Dyskusja dotyczy problemu wyodrębnienia i konwersji danych odebranych przez port RS232 w Delphi do wyświetlenia na wykresie TChart. Autor próbuje przetworzyć dane temperatury przesyłane w formacie tekstowym, np. "TEMP 023,#10,#13", gdzie 023 to wartość temperatury, a 10 i 13 to znaki końca linii (CR, LF). Wskazano, że procedura val(S; var V; var Code: Integer) służy do konwersji ciągu znaków na liczbę z kontrolą błędów, co jest lepsze niż StrToInt. W przypadku danych binarnych (hex) wystarczy rzutowanie bajtów na typ liczbowy. Autor miał trudności z konwersją dwubajtowej wartości (np. 10 13) na typ word, co rozwiązał przez rozdzielenie bajtów i ręczne złożenie wartości: obroty := 256*obrotyh + obrotyl. Wykres temperatury i obrotów działa poprawnie, a zapis wykresu do pliku bitmapowego (.bmp) uzyskano przez metodę Chart1.SaveToBitmapFile('wykres'). Dyskusja zawiera praktyczne wskazówki dotyczące obsługi bufora RS232, konwersji danych tekstowych i binarnych oraz integracji z komponentem TChart w Delphi.
Wygenerowane przez model językowy.
REKLAMA