2013-04-22 4 views
0

Klerkscale SASCALE에서 읽었던 weighbridge 응용 프로그램이 있습니다. 이제 LS210 Opticon weighbridge에서 읽어야합니다. 전송 속도 등을 설정하는 코드를 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

'timeout'은 무엇으로 설정되어 있습니까? –

+0

timeout = 10000 – Privesh

+0

그런데'WaitForMultipleObjects' 함수가 시간 초과되거나 실패하는지 알 수 없습니다. 이 두 가지를 다르게 처리 할 수도 있습니다 (예 : 실패시 오류보고). –

답변

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의 포트를 설정하고 있기 때문에 setu를 덮어 씀으로써 기본 "else"조건을 위해 포트를 다시 설정합니다 OPTO에 대한 p.

+0

거룩한 연기, 나는 그것을 놓쳤다 믿을 수 없어. 나는 지금 그렇게 느껴야한다 – Privesh

+0

어이, 걱정하지 마라, 모두에게 일어난다. 그래서 {}에 한 줄짜리 조건문을 동봉해야합니다. 이렇게하면 나중에 코드를 쉽게 확장 할 수 있습니다. 어쨌든 코드가 지금 작동합니까? 그렇지 않다면, 무슨 일이 일어나고 있습니까? –

+0

코드의 일부가 이제 작동합니다. 3 라인 각각의 코드를 작성할 수 있도록 문자열을 살펴보기 위해 거짓말을 사용하여 인라인 디버깅을 수행하는 인라인 디버깅을 수행합니다. 즉 시작점 광고를 결정한 다음 하위 문자열을 읽는 등의 작업을 수행합니다. 임무. 어쨌든 내 booooo을 발견해 주셔서 빅터 감사합니다 :) – Privesh