제발 용서해주십시오. 꽤 긴 게시물이 될 것입니다. 현재 C#에서 SerialPort 클래스를 사용하여 Fluke 5500A라는 장치와 통신하는 응용 프로그램을 작성하고 있습니다. 필자는 과거에 장치가 명령을 내리고 결과가 무엇이든 예측할 수없는 상태로 반환하는 데 걸리는 시간으로 많은 문제를 겪었습니다. 나는 어제 질문을했다. System.Timers.Timer Usage 질문에 대한 답은 훌륭하고 대부분의 경우 완벽하게 작동하는 것으로 보인다.명백한 IO.Ports.SerialPort C# 또는 가능한 하드웨어 결함의 결함
public class SerialPortConnection
{
private SerialPort serialPort;
private string ping;
double failOut;
bool isReceiving;
public SerialPortConnection(string comPort = "Com1", int baud = 9600, System.IO.Ports.Parity parity = System.IO.Ports.Parity.None, int dataBits = 8, System.IO.Ports.StopBits stopBits = System.IO.Ports.StopBits.One, string ping = "*IDN?", double failOut = 2)
{
this.ping = ping;
this.failOut = failOut * 1000;
try
{
serialPort = new SerialPort(comPort, baud, parity, dataBits, stopBits);
serialPort.NewLine = ">";
serialPort.ReadTimeout = 1000;
}
catch (Exception e)
{
serialPort = null;
}
}
//Open Serial Connection. Returns False If Unable To Open.
public bool OpenSerialConnection()
{
//Opens Initial Connection:
try
{
serialPort.Open();
serialPort.Write("REMOTE\r");
}
catch (Exception e)
{
return false;
}
serialPort.Write(ping + "\r");
var testReceived = "";
try
{
testReceived += serialPort.ReadLine();
return true;
}
catch
{
return false;
}
}
public string WriteSerialConnection(string SerialCommand)
{
serialPort.Write(String.Format(SerialCommand + "\r"));
var received = "";
try
{
received += serialPort.ReadLine();
return received;
}
catch
{
received = "Error: No Data Received From Device";
return received;
}
}
public bool CloseSerialConnection()
{
try
{
serialPort.Write("LOCAL\r");
serialPort.Close();
return true;
}
catch (Exception e)
{
return false;
}
}
}
당신이 볼 수 있듯이, 나는이 경우에 대한 연결을 열 때, Com1
는 난을 작성하여 연결을 테스트 : 예를 들어 나는하여 SerialPort에 연결하는 데 사용하는 내 클래스는 이제 다음과 같습니다 SerialPort에 *IDN?
명령을 보내십시오. 이 명령에 대한 리턴 그래서 다음과 같습니다
FLUKE,5500A,8030005,2.61+1.3+2.0+*
66>
그것을 그 토큰을 발견까지 SerialPort.ReadLine()가 완료되지 않도록 내가 줄 바꿈 속성으로 ">"
을 설정 한 클래스에서. 한 번도 클래스 자체에서 예외를 throw하지는 못했지만 예외가 발생하지 않고 코드가 제대로 실행되면서도 testReceived
이 반환 된 데이터를 제대로 캐치하지 않는 디버깅 중에 알았습니다. 대신 received
은 반환 된 문자열을 잡을 : 내가 아는 것이 중요 SerialPort.Write();
뭔가를 통해 내 첫 번째 명령을 통과 할 때마다
FLUKE,5500A,8030005,2.61+1.3+2.0+*
66>
해당 데이터가 완전히 반환하지 않고 명령을 실행할 수 있다는 것입니다. 제 우려는 처음의 ReadLine()
은 가끔씩 전체 수익을 포기하지 않고 지나치는 것처럼 보입니다. 내 생각으로는이 문제를 일으키는 장치에 고유 한 결함이 있지만 계속하기 전에 전체적으로 확신하고 싶습니다.
내 명령 순서는 그래서 다음과 같습니다
먼저 나는 시작에 명령을 제출
는REMOTE
이 장치의 수동 인터페이스와 상호 작용을 비활성화하고 나를 직렬 포트를 통해 명령을 제출할 수 있습니다.
은 그 때 나는 장치가 연결되어 있는지 확인하기 위해,이 경우, *IDN?
을 실행
*IDN?
아무것도 반환 응용 프로그램은 다음 FailFast
메시지 상자에 오류를 표시하도록 설정하고,없는 경우. 모두가된다면 아니라 명령과 같이 제출 될 수
STBY
OUT 30MV,60HZ
OPER
여기에 직접 제출하는 유일한 명령은 OUT 30,MV,60HZ
입니다. STBY
및 OPER
은 응용 프로그램 사용에 불필요한 단계 만 추가하기 때문에 app.config에 설정됩니다. STBY
명령은 안전상의 이유로 기계를 대기 상태로 만듭니다. OPER
명령은이를 작동 모드로 설정하고 장치는 설정된 매개 변수로 작동을 시작합니다.
그러면 응용 프로그램에서 기술자가 결과를 텍스트 상자에 입력하고 제출할 때까지 기다립니다.이러한 결과의 내용은 특히 관련 아니지만 결과 버튼을 눌렀을 때 컴퓨터가 대기에 다시 넣어 :
STBY
마지막으로, 응용 프로그램이 닫힐 때 두 가지 이상의 명령이 제출 :
*RST
LOCAL
먼저 *RST
은 전원을 켰을 때와 동일한 상태 (IE가 작동 중이 아니며 매개 변수가 설정되지 않음)인지 확인하기 위해 기기를 재설정합니다. 그런 다음 LOCAL
은 사용자 상호 작용을 위해 수동 인터페이스를 다시 활성화하고 다시 REMOTE
이 발행 될 때까지 직렬 포트를 통한 액세스를 비활성화합니다.
본 그림에서 알 수 있듯이 *IDN?
이후와 첫 번째 수동 명령 (이 경우 명령은 OUT 30MV,60HZ
이라고 가정) 앞에 명령이 실행됩니다. 문제는 때로는 OUT 30MV,60HZ
의 출력이 무엇인지를 확인할 때마다 *IDN
의 출력을 수신하는 것입니다. 내 코드 또는 프로 시저 내에서 기계 작동에 문제가없는 것을 확인할 수 있습니다. 이것이 일어날 수있는 이유가 있습니까?
내가 말했듯이, 오류는 재현하기가 극히 어렵습니다 (나는 40 번 실행했을 때 두 번 본 적이 있습니다). 그렇더라도 프로덕션 환경에서는이 유형의 모든 오류를 허용 할 수 없으며 응용 프로그램 전체를 테스트하기 전에 오류를 수정해야합니다. 나는 오류를 재현하려고 계속 노력할 것이므로 예제를 제공하고 문제가 무엇인지에 대해 더 명확하게 설명해 줄 수 있기를 바랍니다. 나는 또한 내가 버그가 코드와 내 응용 프로그램 자체 내에서 어딘가에 위치하지 꽤 확신 명확히하고 싶습니다
자연에서 다소 단순한입니다
:public string SubmitCommand()
{
if (_command_Input != "No further commands to input.")
{
string received;
serialPort.WriteSerialConnection("STBY");
received = serialPort.WriteSerialConnection(_command_Input);
serialPort.WriteSerialConnection("OPER");
//Controls Enabled:
_input_IsEnabled = false;
_user_Input_IsEnabled = true;
_results_Input_IsEnabled = false;
RaisePropertyChanged("Input_IsEnabled");
RaisePropertyChanged("User_Input_IsEnabled");
RaisePropertyChanged("Results_Input_IsEnabled");
return received;
}
else
return "";
}
수신 EDIT
다음과 같이 조작되어있을 필요하지만 현재 당면한 문제에 관련 될 수있는 다른 코드를 볼 수없는 경우
public bool SetOutput()
{
string inter1 = SubmitCommand();
try
{
string[] lines = inter1.Split(Environment.NewLine.ToCharArray()).ToArray();
_results_Changed = lines[2];
RaisePropertyChanged("Results_Changed");
}
catch
{
_results_Changed = inter1;
RaisePropertyChanged("Results_Changed");
}
return true;
}
나는 더 코드를 제공 할 수 있습니다.
결함이 장치에 없다는 것을 어떻게 확인할 수 있습니까? –
@BradRem 그래서 제가 묻고 있습니다. 그것이 장치 결함인지 확신 할 수는 없지만 프로그래밍 결함보다는 문제 해결이 훨씬 어렵습니다 (불가능하지는 않지만). 그 문제를 해결하려고 계속하기 전에 그것이 내 코드 어딘가에 또는 SerialPort 클래스에 결함이 없는지 확인하고 싶습니다. – DanteTheEgregore
사용하는 Win32 통신 API와 비교할 때,'IO.Ports.SerialPort'는 몹시 망가졌습니다. 나는 스스로 곤란을 겪었고 다양한 문제에 관한 다른 사람들의보고를 보았습니다. Win32를 직접 사용하기 위해 전환 한 후에 모두 사라졌습니다. –