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

Odbiór danych z RS232 w C++ – jak rozdzielić 3 pomiary na osobne RichEdit?

fojta 19 Maj 2007 16:42 15792 11
REKLAMA
  • #1 3900829
    fojta
    Poziom 11  
    Posty: 11
    Witam
    Chodzi o rs232 w C++

    wiem że temat poruszany nie raz i w 90% chyba wszystkie wątki przeczytałem :) potrafie szperać poprzez "szukaj" i znajdywałem zawsze wiele cennych informacji - jednak teraz chce wam przedstawić mój problem ... który jest zapewne BARDZO banalny

    wykonałem na atmeg8 "cudo" co wykonuje pomiary trzech napięć. Teraz chciałbym aby wyniki tych pomiarów były pokazywane w ładny sposób na monitorze. Atmega i rs232 działa poprawnie bo na monitorze za pomocą Hyperterminala wyniki się pojawią. .... jednak nie potrafie tego przenieśc do C++.

    Po części mi sie udało bo wskazania się wyświetlają jednak wszystkie 3 pomiary ukazują mi się w jednym polu RichEdit. Dodam że transmisja jest bufforowa. Nie potrafie dojśc do tego jak to rozdzielić na 3 osobne okna RichEdit. Nie ma co ukrywac że w C++ to moje pierwsze kroki ale z pomocą ksiązki Daniluka mam jakieś minimalne pojęcie.



    Byłbym wdzięczy za wskazówki
  • REKLAMA
  • #2 3901046
    dafit1987
    Poziom 11  
    Posty: 9
    a mógłbyś podesłać jak to wykonałeś w c++, ja się męczę nad tą komunikacją i też nie mogę dojść do skutku :/
  • REKLAMA
  • #3 3901339
    mirekk36
    Poziom 42  
    Posty: 9195
    Pomógł: 964
    Ocena: 2289
    zasysacie koledzy sobie komponent ComPort z www.sourceforge.net , instalujecie i patrząc na wiele przykładowych programików, które w pakiecie się znajdują piszecie na spokojnie używając CPort dowolną aplikacyjkę gadającą przez RS232
  • #4 3904063
    Konto nie istnieje
    Konto nie istnieje  
  • REKLAMA
  • #5 3904126
    mirekk36
    Poziom 42  
    Posty: 9195
    Pomógł: 964
    Ocena: 2289
    Gusioo napisał:

    Potem przychodzą na inny komputer, gdzie nie ma ComPort i mają zimę bo się nie kompiluje.


    nie chcę się spierać, że w oparciu o WinApi można równie szybko i łatwo obsłużyć transmisję RS232 - ale dla nieco zaawansowanych. Po to podałem ten komponent aby ułatwić kolegom pewne sprawy na początku, dzięki niemu nie muszą się zajmować najpierw przygotowaniem sobie procedur obsługi RS232 tylko korzystają z gotowych rozwiązań.

    ... a tak nawiasem mówiąc to o jakim przejściu na inny komputer i zimie mówisz kolego Gusioo ? ..... dla ciebie to taka zima??? ... skoro na jednym możesz szybko zassać z netu i zainstalować jakiś komponent to tak samo możesz zrobić na drugim, trzecim, czwartym itd

    więc myślę, że cenniejszą poradą z twojej strony byłoby wrzucenie kolegom jakichś przykładowych procedur w WinApi i wyjaśnień odnośnie takiej obsługi a nie (sorry) ale takie troszkę przechwalanie się, że to takie proste. Proste to dla nich będzie jak im to dobrze wytłumaczysz - więc spróbuj.

    pozdrawiam
  • #6 3905016
    fojta
    Poziom 11  
    Posty: 11
    oto moja obecna aplikacja "napisana" na podstawie innych programów przykładowych. Po kliknięciu w button pojawia mi się wartość w wybranym okienku i jest OK. Jednak gdy klikne kolejny button (w celu odczytania drugiego pomiaru) zaczynają się schody. Pojawia się najpierw wartość pomiaru 1 a dopiero po 5 kliknięciu wartośc z pomiaru nr2. czy to wina buforów i ich czyszczenie ?

    Cytat:


    #include <vcl.h>
    #pragma hdrstop
    #include "pulpit.h"
    #pragma package(smart_init)
    #pragma resource "*.dfm"



    TForm1 *Form1;

    DWORD cbOutQueue = 32 ; //rozmiar bufora danych wyjściowych
    DWORD cbInQueue = 32 ; //rozmiar bufora danych wejściowych


    char*Buffer_O = new char[cbOutQueue] ;
    char*Buffer_I = new char[cbInQueue] ;

    //char Buffer_O[cbOutQueue]; // bufor danych wyjściowych
    // char Buffer_I[cbInQueue]; // bufor danych wejściowych
    DWORD Number_Bytes_Read; // liczba bajtów do czytania
    HANDLE hCommDev; // identyfikator portu
    DWORD fdwEvtMask;
    COMSTAT Stat;
    DWORD Errors;

    //BOOL bResult = TRUE;
    //int hThread_SR;
    //unsigned ThreadID_SR;
    //Cardinal intVar; // licznik pomiaru

    LPCTSTR sbuffer1 = "Uwaga !";
    LPCTSTR sbuffer2 = "Błąd !";
    LPCTSTR sbuffer3 = "Niewłaściwa nazwa portu lub port jest"
    " aktywny.";
    LPCTSTR sbuffer4 = " Port nie został otwarty do transmisji.";
    LPCTSTR sbuffer5 = " Działanie aplikacji zostanie zakończone.";
    //-------------------------------------------------
    __fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
    {
    }
    //--------------------------------------------------
    BOOL __fastcall Write_Comm(HANDLE hCommDev,
    DWORD nNumberOfBytesToWrite)
    {
    DWORD NumberOfBytesWritten;

    //if (WriteFile(hCommDev, &Buffer_O[0], nNumberOfBytesToWrite,
    //&NumberOfBytesWritten , NULL) == TRUE)

    if (WriteFile(hCommDev,Buffer_O,nNumberOfBytesToWrite,
    &NumberOfBytesWritten , NULL)>0)
    {
    WaitCommEvent(hCommDev, &fdwEvtMask, NULL);
    return True ;
    }
    else
    return FALSE;
    }
    //--------------------------------------------------
    BOOL __fastcall Read_Comm(HANDLE hCommDev,
    LPDWORD lpNumberOfBytesRead, DWORD Buf_Size)
    {
    DWORD nNumberOfBytesToRead;

    *lpNumberOfBytesRead = 0;

    ClearCommError(hCommDev, &Errors ,&Stat);

    if (Stat.cbInQue > 0)
    {
    if (Stat.cbInQue > Buf_Size)
    nNumberOfBytesToRead = Buf_Size;
    else
    nNumberOfBytesToRead = Stat.cbInQue;
    }
    return ReadFile(hCommDev, &Buffer_I[0],
    nNumberOfBytesToRead,
    lpNumberOfBytesRead, NULL);
    }
    //----------------------------------------------------
    void __fastcall TForm1::CloseCommClick(TObject *Sender)
    {
    switch(MessageBox(NULL, sbuffer5, sbuffer1,
    MB_YESNO | MB_ICONQUESTION))
    {
    case ID_YES :
    {
    //SuspendThread((HANDLE)hThread_SR);
    CloseHandle(hCommDev);
    Application->Terminate();
    break;
    }
    case ID_NO :
    Abort();
    break;
    }
    }
    //------------------------------------------------


    //--------------------------------------------------
    void __fastcall TForm1::OpenCommClick(TObject *Sender)
    {
    LPCTSTR lpFileName;
    DCB dcb;

    lpFileName = "COM1";

    hCommDev = CreateFile(lpFileName, GENERIC_READ |
    GENERIC_WRITE, 0, NULL,
    OPEN_EXISTING, 0, NULL);

    if (hCommDev != INVALID_HANDLE_VALUE)
    // sprawdza, czy port jest otwarty prawidłowo
    {
    SetupComm(hCommDev, cbInQueue, cbOutQueue);
    dcb.DCBlength = sizeof(dcb);
    GetCommState(hCommDev, &dcb);

    dcb.BaudRate = CBR_9600;
    dcb.Parity = ODDPARITY; // ustawienie parzystości
    dcb.StopBits = ONESTOPBIT; // bity stopu
    dcb.ByteSize = 7; // bity danych

    //-przykładowe ustawienia flag sterujących DCB-
    dcb.fParity = TRUE; // sprawdzanie parzystości
    dcb.fDtrControl = DTR_CONTROL_DISABLE;
    dcb.fRtsControl = RTS_CONTROL_DISABLE;
    dcb.fOutxCtsFlow = FALSE;
    dcb.fOutxDsrFlow = FALSE;
    dcb.fDsrSensitivity = FALSE;
    dcb.fAbortOnError = FALSE;
    dcb.fOutX = FALSE;
    dcb.fInX = FALSE;
    dcb.fErrorChar = FALSE;
    dcb.fNull = FALSE;

    SetCommState(hCommDev, &dcb);
    GetCommMask(hCommDev, &fdwEvtMask);
    SetCommMask(hCommDev, EV_TXEMPTY);
    }
    else
    {
    switch ((int)hCommDev)
    {
    case IE_BADID:
    MessageBox(NULL, sbuffer3, sbuffer2, MB_OK);
    break;
    };
    }
    }
    //----------------pomiar 1------------------------------
    void __fastcall TForm1::MeasureONClick(TObject *Sender)
    {
    Buffer_O = "A"; // wyslanie znaku "A" do buffora wyj.
    //uC odpowiada na ten znak pomiarem nr.1
    Write_Comm(hCommDev,1); // wyslanie znaku z buffora do uC

    memset(Buffer_I,0,cbOutQueue); //czyszczenie bufora wyjsciowego

    Read_Comm(hCommDev,&Number_Bytes_Read,sizeof(Buffer_I)); //odczytanie pomiaru1 z bufora wejsciowego
    Form1->RichEdit1->Text = Buffer_I; // wyswietlenie pomiaru
    FlushFileBuffers(hCommDev);



    }

    //---------------pomiar 2------------------------------------------

    void __fastcall TForm1::Button1Click(TObject *Sender)
    {
    Buffer_O = "B"; // wyslanie znaku "B" do buffora wyj.
    Write_Comm(hCommDev,1); //uC odpowiada na ten znak pomiarem nr.2
    memset(Buffer_I,0,cbOutQueue); //czyszczenie bufora wyjsciowego


    Read_Comm(hCommDev,&Number_Bytes_Read,sizeof(Buffer_I)); //odczytanie pomiaru2 z bufora wejsciowego
    Form1->RichEdit2->Text = Buffer_I; // wyswietlenie pomiaru
    FlushFileBuffers(hCommDev); //czyszczenie bufora wej.



    }

    //---------------------------------------------------------
    void __fastcall TForm1::FormClose(TObject *Sender,
    TCloseAction &Action)
    {
    Action=caFree;
    }
    //-------------------------------------------------------




    p.s. Panowie bez awantur ;)
  • REKLAMA
  • #7 3906718
    Konto nie istnieje
    Konto nie istnieje  
  • #8 3906756
    mirekk36
    Poziom 42  
    Posty: 9195
    Pomógł: 964
    Ocena: 2289
    ooo i to nazywa się rzeczowa dyskusja na elektrodzie.... stronka, którą polecił kolega Gusioo bardzo dobrze oddaje aspekty "macania" RSa przez WinAPI - więc zapewne należy się koledze od autora "klawisz pomógł" ;)

    pozdrawiam
  • Pomocny post
    #9 3906791
    Konto nie istnieje
    Konto nie istnieje  
  • #11 3928351
    SACZI
    Poziom 16  
    Posty: 302
    Pomógł: 6
    Ocena: 14
    Cytat:

    Potem przychodzą na inny komputer, gdzie nie ma ComPort i mają zimę bo się nie kompiluje.

    Kilka razy już tak się przejechałem. Warto zainteresować się WinAPI - to nie jest takie trudne ;)

    A co to jest CPort?
    Przecież to API Windowsa ... !
    To chyba najlepsza kontrolka do obsługi portów szeregowych dla BCB i Delphi.
  • #12 3928376
    Konto nie istnieje
    Konto nie istnieje  

Podsumowanie tematu

✨ Temat dotyczy odbioru danych z interfejsu RS232 w języku C++ i problemu rozdzielenia trzech pomiarów napięć wykonywanych przez mikrokontroler Atmega8 na trzy osobne pola RichEdit w aplikacji Windows. Autor potwierdza poprawność działania transmisji RS232, co widać w Hyperterminalu, jednak w aplikacji C++ wszystkie pomiary wyświetlają się w jednym polu RichEdit. Dyskusja porusza kwestie buforowania danych i problemów z synchronizacją odczytu kolejnych pomiarów. Proponowane rozwiązania obejmują użycie gotowych komponentów do obsługi portu szeregowego, takich jak CPort dostępny na SourceForge, oraz alternatywnie bezpośrednią obsługę RS232 przez WinAPI, co jest bardziej przenośne i nie wymaga dodatkowych bibliotek, choć jest trudniejsze dla początkujących. Wskazano również literaturę, m.in. książkę A. Daniluka „RS 232 C. Praktyczne programowanie” oraz przydatne linki do materiałów o RS232 i WinAPI. Autor podzielił się fragmentem swojego kodu, który działa częściowo, ale ma problemy z buforowaniem i wyświetlaniem pomiarów w odpowiednich polach. Dyskusja podkreśla znaczenie właściwego zarządzania buforami i synchronizacji odczytu danych, a także wybór między komponentami a natywnym API Windows.
Podsumowanie wygenerowane przez AI na podstawie treści dyskusji.
REKLAMA