简体   繁体   中英

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. 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.


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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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