/// <summary> /// Obsługa komunikatów z klasy RS232. /// </summary> /// <param name="arg"></param> private void OnRS232Communicate(RS232CommunicateEventArgs arg) { if (InvokeRequired) { // Aktualizacja kontrolki z innego wątku. RS232.RS232CommunicateDelegate d = new RS232.RS232CommunicateDelegate(OnRS232Communicate); Invoke(d, new object[] { arg }); return; } switch (arg.Type) { case CommunicateType.TextDataReceived: uxReceivedTextTextBox.AppendText(arg.TextData + "\n"); break; case CommunicateType.BinaryDataReceived: DynamicByteProvider data = (DynamicByteProvider)uxReceivedHexBox.ByteProvider; data.InsertBytes(data.Length, arg.BinaryData); uxReceivedHexBox.Invalidate(); break; case CommunicateType.ErrorOccured: ShowError(arg.ErrorMessage); break; default: break; } }
/// <summary> /// Funkcja odpowiadająca za odbiór danych tekstowych. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void TextDataHandler(object sender, SerialDataReceivedEventArgs e) { // Jeśli nie napotkano znaku końca linii to nie odczytujemy // bufora wejściowego. SerialPort sp = sender as SerialPort; try { string indata = sp.ReadLine(); RS232CommunicateEventArgs arg = new RS232CommunicateEventArgs(CommunicateType.TextDataReceived); arg.TextData = indata; Communicate(arg); } catch { } }
////////////////////////////////////////////////////////////////////////// /// METODY INTERPRETUJĄCE DANE ////////////////////////////////////////////////////////////////////////// /// <summary> /// Funkcja odpowiadająca za odbiór danych binarnych. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void BinaryDataHandler(object sender, SerialDataReceivedEventArgs e) { // Odczyt wszystkich danych z bufora wejściowego. SerialPort sp = sender as SerialPort; byte[] buf = new byte[sp.BytesToRead]; sp.Read(buf, 0, buf.Length); RS232CommunicateEventArgs arg = new RS232CommunicateEventArgs(CommunicateType.BinaryDataReceived); arg.BinaryData = buf; Communicate(arg); }
/// <summary> /// Obsługa zdarzenia przekroczenia czasu oczekiwania na odpowiedź /// w ramach transakcji. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void OnTransactionTimeout(object sender, ElapsedEventArgs e) { _transactionTimeoutTimer.Stop(); RS232CommunicateEventArgs arg = new RS232CommunicateEventArgs(CommunicateType.ErrorOccured); arg.ErrorMessage = "Nie otrzymano odpowiedzi w ramach transakcji w wyznaczonym czasie."; Communicate(arg); }
/// <summary> /// Reakcja na komunikaty z RS232. /// </summary> /// <param name="arg"></param> private void OnRS232Communicate(RS232CommunicateEventArgs arg) { switch (arg.Type) { case CommunicateType.ErrorOccured: MODBUSCommunicateEventArgs modbusArg = new MODBUSCommunicateEventArgs(MODBUSCommunicateType.ErrorOccured); modbusArg.Text = arg.ErrorMessage; break; case CommunicateType.BinaryDataReceived: _intercharInterval.Stop(); // Unieważnienie danych z powodu nieciągłości ramki. if (_discardInBuffer) { _discardInBuffer = false; _inBuffer.Clear(); } // Dodanie danych do bufora wejściowego i sprawdzenie czy jest tam ramka ASCII dla trybu ASCII. _inBuffer.AddRange(arg.BinaryData); if(_generalTransimssionMode == GeneralTransmissionModeEnum.ASCII && CheckForASCIIFrameInBuffer()) { int start = _inBuffer.IndexOf((byte)':'); int end = _inBuffer.IndexOf(0x0A); List<byte> frame = _inBuffer.GetRange(start, end - start + 1); _inBuffer.RemoveRange(start, end - start + 1); ProcessFrame(frame); } // Zresetowanie timera dla trybu RTU if (_generalTransimssionMode == GeneralTransmissionModeEnum.RTU) { _RTUTimer.Stop(); _RTUTimer.Start(); } // Zapewnienie ciągłości ramki _intercharInterval.Start(); break; default: break; } }