简体   繁体   English

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

[英]opening serial port and reading a data string

I have a weighbridge application that used to read from a Klerkscale SASCALE before and now it also needs to read from a LS210 Opticon weighbridge. 我有一个地磅应用程序以前从Klerkscale SASCALE读取,现在它还需要读取LS210 Opticon地磅。 I have added code to set the baud rates etc fot it as OPTI but Im still getting an error of" no response from the comm port" this error comes from the ERR00009 (if you look at the default part of the swith statement. Can anyone help me rectify the code please. 我添加了代码来设置波特率等等它作为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();
}

Please add more curly braces to the code to separate different choices, like this: 请在代码中添加更多花括号以分隔不同的选项,如下所示:

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);
}

because currently your code setups the port for OPTO and then sets the port again for the default "else" condition, overwriting the setup for OPTO. 因为目前您的代码设置OPTO的端口,然后再次为默认的“else”条件设置端口,覆盖OPTO的设置。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM