[C++] Problem z odbiorem danych rs232

0

Witam,

mam takie urządzenie:
<url>http://instrumentation2000.com/aalborgdfc26serieslowcostlowrangedigitalmassflowcontrollerupto10slminn2.aspx
</url>
moim celem jest nawiązać z nim połączenie i pobrać z niego jakieś dane. Niestety on nie chce ze mną współpracować.

Poniżej zamieszczam kod z którego korzystam... (dodam, że kod w znacznej części jest wzięty z książki RS232-praktyczne programowanie - Borland)

#include <vcl.h>
#pragma hdrstop
#include "Unit_05_10.h"
#pragma package(smart_init)
#pragma link "CSPIN"
#pragma resource "*.dfm"
#include <iostream>
#include <sstream>
#include <string>

using namespace std;


#define cbOutQueue 16    //rozmiar bufora danych wyjściowych
#define cbInQueue  16    //rozmiar bufora danych wejściowych

TForm1 *Form1;

    LPCTSTR query = "!02,F<CR>"; //  zapytanie


    char    bufferOut[cbOutQueue]; // bufor danych wyjściowych
    char    bufferIn[cbInQueue]; // bufor danych wejściowych
    DWORD   bytesRead;          // liczba bajtów do czytania
    HANDLE  hCommDev;      // identyfikator portu
    LPCTSTR portName;      // wskaźnik do nazwy portu
    DCB     dcb;           // struktura kontroli portu szeregowego
    DWORD a = (EV_TXEMPTY | EV_RXFLAG);
    DWORD   &fdwEvtMask =a;//informacja o aktualnym stanie transmisji
    COMSTAT comstat;        // dodatkowa informacja o zasobach portu
    DWORD   errors;         // reprezentuje typ ewentualnego błędu

    LPCTSTR sbuffer2 = "Uwaga !";
    LPCTSTR sbuffer1 = "Niewłaściwa nazwa portu lub port jest"
                       " aktywny.";
    LPCTSTR sbuffer3 = "Port szeregowy nie został prawidłowo"
                       " otwarty.";
    LPCTSTR tutaj = "tutaj";
    LPCTSTR tutaj2 = "tutaj2222222";

//--------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
{
}
//--------------------------------------------------------------
BOOL __fastcall TForm1::closeSerialPort(HANDLE hCommDev)
{
    return CloseHandle(hCommDev);
}
//--------------------------------------------------------------
BOOL __fastcall TForm1::writeSerialPort(HANDLE hCommDev,
                                        DWORD numberOfBytesToWritte/* jest 9*/)
{
    DWORD numberOfBytesWritten;      //jest 1 - po if jest 9 (tyle ile ma zapytanie query)

   
    if (WriteFile(hCommDev, &bufferOut[0], numberOfBytesToWritte,
                  &numberOfBytesWritten,  NULL) == TRUE){

       if (WaitCommEvent(hCommDev, &fdwEvtMask, NULL)==TRUE){return TRUE;}
      else return FALSE;
       }
}
//--------------------------------------------------------------
BOOL __fastcall TForm1::readSerialPort(HANDLE hCommDev, LPDWORD
                                       lpNumberOfBytesRead,
                                       DWORD bufSize) //wielkosc sizeof(bufferIn)
{
   DWORD numberOfBytesToRead;
     /*//jest zero bo tu jeszcze nie ma przypisane
    char Cstr[20];
    sprintf(Cstr, "%i", numberOfBytesToRead);
    MessageBox(NULL,Cstr,Cstr,MB_OK);
    */
   *lpNumberOfBytesRead = 0;
   ClearCommError(hCommDev, &errors ,&comstat);




   if (comstat.cbInQue > 0) {
      if (comstat.cbInQue > bufSize)
         numberOfBytesToRead = bufSize;
         else
            numberOfBytesToRead = comstat.cbInQue;
   }





     //po ponizszej funkcji bufferIn jest zero
    return ReadFile(hCommDev, &bufferIn[0], numberOfBytesToRead,
                   lpNumberOfBytesRead, NULL);;
}
//--------------------------------------------------------------
void __fastcall TForm1::CloseCommClick(TObject *Sender)
{
   Timer1->Enabled = FALSE;
   closeSerialPort(hCommDev);
   Application->Terminate();
}
//--------------------------------------------------------------
void __fastcall TForm1::FormCreate(TObject *Sender)
{
   Timer1->Enabled = FALSE;
   CSpinEdit1->Value = 500;
   CSpinEdit1->ReadOnly = FALSE;
   CSpinEdit1->Cursor = crNo;
   CSpinEdit1->Hint="Ręczne wpisywanie może być niebezpieczne !";
   CSpinEdit1->ShowHint = TRUE;
   CSpinEdit1->Increment = 1;
}
//--------------------------------------------------------------
void __fastcall TForm1::CSpinEdit1Change(TObject *Sender)
{
   if (CSpinEdit1->Value < 0)
   // uniemożliwia ustalenie wartości ujemnej
      CSpinEdit1->Value = abs(CSpinEdit1->Value);
   Timer1->Interval = CSpinEdit1->Value;
}
//--------------------------------------------------------------
void __fastcall TForm1::MeasureOFFClick(TObject *Sender)
{
   Timer1->Enabled = FALSE;
}
//--------------------------------------------------------------
void __fastcall TForm1::OpenCommClick(TObject *Sender)
{
   if (CheckBox1->Checked == TRUE)         // wybór portu
      portName = "COM1";
   if (CheckBox2->Checked == TRUE)
      portName = "COM9";

   hCommDev = CreateFile(portName, 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);



      if (CheckBox3->Checked == TRUE)
      // wybór prędkości transmisji
         dcb.BaudRate=CBR_300;
      if (CheckBox4->Checked == TRUE)
         dcb.BaudRate=CBR_1200;
      if (CheckBox5->Checked == TRUE)
         dcb.BaudRate=CBR_9600;


          dcb.fParity = TRUE;
      dcb.Parity = NOPARITY;      // ustawienie parzystości
      dcb.StopBits = ONESTOPBIT;   // bity stopu
      dcb.ByteSize = 8;            // bity danych
           


      SetCommState(hCommDev, &dcb);
      GetCommMask(hCommDev, &fdwEvtMask);
      SetCommMask(hCommDev, a);
   }
    else {
        switch ((int)hCommDev) {
           case IE_BADID:
              MessageBox(NULL, sbuffer1, sbuffer2, MB_OK);
           break;
        };
    }
}
//--------------------------------------------------------------
void __fastcall TForm1::MeasureONClick(TObject *Sender)
{
    if ((hCommDev != INVALID_HANDLE_VALUE) && (hCommDev > 0)) {
    // powtórnie sprawdza czy port jest otwarty
      strcpy(bufferOut, query);
      Timer1->Enabled = TRUE;
    }
     else{
        MessageBox(NULL, sbuffer3, sbuffer2, MB_OK);

        }
}
//--------------------------------------------------------------
void __fastcall TForm1::TimerOnTimer(TObject *Sender)
{
    writeSerialPort(hCommDev, strlen(bufferOut));
    //MessageBox(NULL,"tak","tak",MB_OK);
    // else MessageBox(NULL,"nie!!!!","nie!!!!",MB_OK);


    Beep();
    //FlushFileBuffers(hCommDev);
     /*//  jest zero
    char Cstr[20];
    sprintf(Cstr, "%i",strlen(bufferIn));
    MessageBox(NULL,Cstr,Cstr,MB_OK);
     */

    readSerialPort(hCommDev, &bytesRead, sizeof(bufferIn));
 
   

    if (bytesRead == 0) {
       LPVOID MsgBuf;
       Timer1->Enabled = FALSE;
       System::SetLastError(ERROR_READ_FAULT);
       FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
                     FORMAT_MESSAGE_FROM_SYSTEM,NULL,
                     GetLastError(), MAKELANGID(LANG_NEUTRAL,
                     SUBLANG_DEFAULT), (LPTSTR) &MsgBuf, 0, NULL );
       MessageBox(NULL, (LPTSTR) MsgBuf, "Błąd transmisji",
                  MB_OK|MB_ICONINFORMATION);
       // zwolnienie bufora
       LocalFree(MsgBuf);
    }
    else
      RichEdit1->Text = bufferIn;

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

Wygląd programu:http://fatcat.ftj.agh.edu.pl/~filip/prog.JPG

Poniżej przesyłam wykaz przykładowych komend do tego urządzenia:
http://fatcat.ftj.agh.edu.pl/~filip/P1020168.JPG

Proszę o pomoc, jakieś wskazówki jak to uruchomić i z góry dziękuje...
(ewentualnie proszę na priva jeśli ktoś miałby jakiś pomysł, a zbyt dużo byłoby opisywania)

pzdr,

0

Jak ja robiłem takie rzeczy to robiłem tak.
Krok 1. Połączenie z urządzeniem poprze hyperTerminal (taki śmieć w Windows).
a. najważniejsze to ustawić właściwie parametry portu.
b. jeśli komunikacja działa prawidłowo to przez hyperTerminal ręcznie testuje różne komendy i obserwuje jaka jest odpowiedź, szczególnie ważne jest sprawdzenie co się dzieje jak się wyśle nieprawidłową komendę i jak to można wykryć.

Krok 2. napisanie małej aplikacji do testowania urządzenia (hyperTerminal nie jest wygodny), w celu dokładniejszego poeksperymentowania.
Krok 3. pisanie właściwej aplikacji.

Ja pisałem jakiś program kontrolujący kilka urządzeń podłączonych przez różne dziwne złącza. Był RS-232, USB, a nawet GPIB (czasami podłączone nawet do różnych komputerów). Jest taki fajny freamwork VISA (Virtual Instrument Software Architecture), który ładnie opakowuje wszystkie te standardy komunikacji umożliwiając łatwe tworzenie bardziej skomplikowanych systemów. Szczególnie polecam ten freamwork od National Instrument, bo dostarczają użyteczne narzędzia (np NiSpy podsłuch do komunikacji z urządzaniami).

0

może się jeszcze przydać jakisś monitor portu. Osobiście polecam ( bo sam korzystam ) http://www.serial-port-monitor.com/

0

Hym a czy zapytanie nie powinno przypadkiem być zamiast:
LPCTSTR query = "!02,F<CR>"; // zapytanie
o takie ?
LPCTSTR query = "!02,F\r"; // zapytanie

1 użytkowników online, w tym zalogowanych: 0, gości: 1