2013-04-22 108 views
0

我有一個地磅應用程序,用於在Klerkscale SASCALE之前讀取,現在還需要從LS210 Opticon地秤讀取數據。我添加了代碼設置波特率等fot它作爲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

什麼是超時設置? – 2013-04-22 13:09:36

+0

timeout = 10000 – Privesh 2013-04-22 14:30:00

+0

順便說一句,你不知道'WaitForMultipleObjects'函數是超時還是失敗。您可能想要以不同的方式處理這兩個問題(例如,報告失敗時的錯誤)。 – 2013-04-22 14:32:36

回答

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」條件,覆蓋setu p代表OPTO。

+0

聖煙,我不相信我錯過了。我現在覺得很k – Privesh 2013-04-22 17:59:55

+0

嘿,別擔心,發生在每個人身上。這就是爲什麼我在{}中放入單行條件語句的原因,這樣以後可以更容易地擴展代碼。無論如何,代碼現在工作嗎?如果沒有,發生了什麼? – 2013-04-23 13:50:37

+0

這部分代碼現在工作。我做一些內聯調試(斷點和步驟)謊言來看看收到的字符串,所以我可以爲三個尺度的每一個編寫代碼,即確定起始點廣告,然後讀取子字符等等。一個任務。無論如何感謝維克多發現我booooo :) – Privesh 2013-04-23 18:25:04