打开串口并读取数据字符串

时间:2013-04-22 13:00:09

标签: c++

我有一个地磅应用程序以前从Klerkscale SASCALE读取,现在它还需要读取LS210 Opticon地磅。我添加了代码来设置波特率等等它作为OPTI但是我仍然得到“来自通信端口没有响应”的错误,这个错误来自ERR00009(如果你看一下swith语句的默认部分。可以任何人请帮我纠正代码。


AnsiString TfrmWeighDetails::GetMass()
{
LONG    lLastError = ERROR_SUCCESS;
bool flag;AnsiString s;
AnsiString port;
bool vTrapErrors, vIgnoreRecvEvent;

DM->vErrLineNo="GCS-21052008-70";
if ( Scale == "INVALID PORT")
{
    return "ERR0011";
}

// Attempt to open the serial port (COM1)
lLastError = serial.Open(_T(Scale.c_str()),0,0,true);

MessageBox(NULL,AnsiString(lLastError).c_str(),"Privesh Test",MB_OK);

if (lLastError != ERROR_SUCCESS)
{
    return "ERR0001";
}

// Setup the serial port (9600,8N1, which is the default setting)

// lLastError = serial.Setup(CSerial::EBaud9600,CSerial::EData8,CSerial::EParNone,CSerial::EStop1);
 lLastError = serial.Setup(CSerial::EBaud19200,CSerial::EData8,CSerial::EParNone,CSerial::EStop1);
if (BridgeSupplier == "OPTO")
        MessageBox(NULL,AnsiString(lLastError).c_str(),"Privesh Test1",MB_OK);
        lLastError = serial.Setup(CSerial::EBaud19200,CSerial::EData8,CSerial::EParNone,CSerial::EStop1);
if (BridgeSupplier == "KLERKSCALE")
    lLastError = serial.Setup(CSerial::EBaud2400,CSerial::EData7,CSerial::EParOdd,CSerial::EStop1);
else
    lLastError = serial.Setup(CSerial::EBaud1200,CSerial::EData7,CSerial::EParEven,CSerial::EStop1);

if (lLastError != ERROR_SUCCESS)
{
    return "ERR0002";
}

// Setup handshaking (default is no handshaking)
lLastError = serial.SetupHandshaking(CSerial::EHandshakeHardware);
MessageBox(NULL,AnsiString(lLastError).c_str(),"Handshake",MB_OK);
if (lLastError != ERROR_SUCCESS)
{
    return "ERR0003";
}

// Register only for the receive event
lLastError = serial.SetMask(CSerial::EEventBreak |
    CSerial::EEventCTS   |
    CSerial::EEventDSR   |
    CSerial::EEventError |
    CSerial::EEventRing  |
    CSerial::EEventRLSD  |
    CSerial::EEventRecv);
MessageBox(NULL,AnsiString(lLastError).c_str(),"Receive Event",MB_OK);
if (lLastError != ERROR_SUCCESS)
{
    return "ERR0004";
}

// Use 'non-blocking' reads, because we don't know how many bytes
// will be received. This is normally the most convenient mode
// (and also the default mode for reading data).
lLastError = serial.SetupReadTimeouts(CSerial::EReadTimeoutNonblocking);
MessageBox(NULL,AnsiString(lLastError).c_str(),"Setup Read Timeouts",MB_OK);
if (lLastError != ERROR_SUCCESS)
{
    return "ERR0005";
}

// Create a handle for the overlapped operations
HANDLE hevtOverlapped = ::CreateEvent(0,TRUE,FALSE,0);;

if (hevtOverlapped == 0)
{
    return "ERR0006";
}

// Setup the overlapped structure
OVERLAPPED ov = {0};
ov.hEvent = hevtOverlapped;
// Open the "STOP" handle
HANDLE hevtStop = ::CreateEvent(0,TRUE,FALSE,_T("Overlapped_Stop_Event"));

if (hevtStop == 0)
    {
    return "ERR0007"  ;
}

// Keep reading data, until an EOF (CTRL-Z) has been received
bool fContinue = true;
do
{
    // Wait for an event
    lLastError = serial.WaitEvent(&ov);
    MessageBox(NULL,AnsiString(lLastError).c_str(),"Serial Wait Event",MB_OK);

    if (lLastError != ERROR_SUCCESS)
    {
        return "ERR0010";
    }
    // Setup array of handles in which we are interested
    HANDLE ahWait[2];
    ahWait[0] = hevtOverlapped;
    ahWait[1] = hevtStop;
    // Wait until something happens
    switch (::WaitForMultipleObjects(sizeof(ahWait)/sizeof(*ahWait),ahWait,FALSE,timeout.ToInt()))
    {
        case WAIT_OBJECT_0:
        {
            // Save event
            const CSerial::EEvent eEvent = serial.GetEventType();
            // Handle break event
            if (eEvent & CSerial::EEventBreak)
            {
                MessageBox(NULL," BREAK received ","Comm Program",MB_OK);
            }
            // Handle CTS event
            if (eEvent & CSerial::EEventCTS)
            {
                flag =   serial.GetCTS();
                if (flag)
                    s = "ON";
                else
                    s = "OFF";
                MessageBox(NULL,(AnsiString("Clear to send ") + s).c_str(),"Comm Prog",MB_OK);
            }
            // Handle DSR event
            if (eEvent & CSerial::EEventDSR)
            {
                flag  = serial.GetDSR();
                if (flag)
                    s = "ON";
                else
                    s = "OFF";
                MessageBox(NULL,(AnsiString("Data set ready ") + s).c_str(),"Comm Prog",MB_OK);
            }
            // Handle error event
            vTrapErrors=false;
            if ((eEvent & CSerial::EEventError)&&
                 (vTrapErrors))  // Although errors encountered, mass still read on XP OS. Therefore, errors suppressed on XP i.e.vTrapErrors=false - MZI12112007
            {
                //MessageBox(NULL,"### ERROR: ");
                switch (serial.GetError())
                {
                    case CSerial::EErrorBreak:        MessageBox(NULL,"Break condition","Com Prog",MB_OK);            break;
                    case CSerial::EErrorFrame:        MessageBox(NULL,"Framing error","Com Prog",MB_OK);            break;
                    case CSerial::EErrorIOE:        MessageBox(NULL,"IO device error","Com Prog",MB_OK);            break;
                    case CSerial::EErrorMode:        MessageBox(NULL,"Unsupported mode","Com Prog",MB_OK);            break;
                    case CSerial::EErrorOverrun:    MessageBox(NULL,"Buffer overrun","Com Prog",MB_OK);            break;
                    case CSerial::EErrorRxOver:        MessageBox(NULL,"Input buffer overflow","Com Prog",MB_OK);    break;
                    case CSerial::EErrorParity:        MessageBox(NULL,"Input parity error","Com Prog",MB_OK);        break;
                    case CSerial::EErrorTxFull:        MessageBox(NULL,"Output buffer full","Com Prog",MB_OK);        break;
//                    default:                  MessageBox(NULL,"Unknown","Com Prog",MB_OK); break; // Error 0 is UNKNOWN but is a Success error therefore no need to handle -- MZI12112007
                }
                //printf(" ###\n");
            }

            // Handle ring event
            if (eEvent & CSerial::EEventRing)
            {
                Sleep(2000);
            }
            // Handle RLSD/CD event
            if (eEvent & CSerial::EEventRLSD)
            {
                flag  = serial.GetRLSD();
                if (flag)
                    s = "ON";
                else
                    s = "OFF";
                MessageBox(NULL,(AnsiString("RLSD/CD ") + s).c_str(),"Comm Prog",MB_OK);
            }
            Timer1->Enabled = false; //switch off the timeout
            // Handle data receive event
            Sleep (1000);    // when no pause, no mass read on XP. Therefore, this ensures system gets in sync with Comm Device - MZI12112007
            vIgnoreRecvEvent=true; // On XP, the Receive event does not seem to be triggered. Therefore this code was included to forcce WBR to work on Xp -- MZI12112007
            if ((eEvent & CSerial::EEventRecv)||vIgnoreRecvEvent)
            {
                // Read data, until the reading from scale is stable
                DWORD dwBytesRead = 0;
                do
                {
                    char szBuffer[101];
                    // Read data from the COM-port
                    lLastError = serial.Read(szBuffer,sizeof(szBuffer)-1,&dwBytesRead);
                    if (lLastError != ERROR_SUCCESS)
                    {
                        ShowError(serial.GetLastError(), _T("Unable to read from COM-port."));
                        return "ERR0008";
                    }
                    if (dwBytesRead > 0)
                    {
                        // Finalize the data, so it is a valid string
                        szBuffer[dwBytesRead] = '\0';
                        AnsiString result = GetStableReading(szBuffer,BridgeSupplier);
                        // Display the data
                        if ( result == "OVERCAPACITY" || result == "BELOWCAPACITY")
                        {
                            serial.Close();
                            return result;
                        }
                        else if ( result != "ERROR" && result != "")
                        {
                            serial.Close();
                            return result;
                        }
                    }
                }
                while ((dwBytesRead > 0 )&&(result == ""));
            }
        }
        break;
    case WAIT_OBJECT_0+1:
    {
        // Set the continue bit to false, so we'll exit
        fContinue = false;
    }
    break;
    default:
    {
        //No response from comm port
        serial.Close();
        return "ERR0009";
    }
}
}
while (fContinue);
// Close the port again
serial.Close();
}

1 个答案:

答案 0 :(得分:2)

请在代码中添加更多花括号以分隔不同的选项,例如:

if (BridgeSupplier == "OPTO") {
    MessageBox(NULL,AnsiString(lLastError).c_str(),"Privesh Test1",MB_OK);
    lLastError = serial.Setup(CSerial::EBaud19200,CSerial::EData8,CSerial::EParNone,CSerial::EStop1);
} else if (BridgeSupplier == "KLERKSCALE") {
    lLastError = serial.Setup(CSerial::EBaud2400,CSerial::EData7,CSerial::EParOdd,CSerial::EStop1);
} else {
    lLastError = serial.Setup(CSerial::EBaud1200,CSerial::EData7,CSerial::EParEven,CSerial::EStop1);
}

因为目前您的代码设置了OPTO的端口,然后再次为默认的“else”条件设置端口,覆盖了OPTO的设置。