Given this code for transmit:
//------------------------------
private void SerialPortSendBytesViaThread(UInt16 uiModbusReadWriteCategory, byte[] abyBuf, int iNumOfBytes)
{
gboModReceivedTimeOutFlag = false;
Thread t = new Thread(unused => threadSerialPortSendBytes(this, uiModbusReadWriteCategory, abyBuf, iNumOfBytes));
t.Start();
}//SerialPortSendBytesViaThread
//------------------------------
//------------------------------
private void threadSerialPortSendBytes(dlg_EasyDrive2Modbus pThis, UInt16 uiModbusReadWriteCategory,
byte[] abyBuf, int iNumOfBytes)
{
//Wait for a response before sending a new request ... need to do this in
// a thread so the timer can work on its own.
pThis.gTimersTimerModbusReceivedFlag.Enabled = true;
while (pThis.gboModReceivedFlag == false && pThis.gboModReceivedTimeOutFlag == false && pThis.gboFormIsClosing == false);
pThis.gboModReceivedFlag = false;
//Set the category for this transmit
pThis.guiModReadWriteCategory = uiModbusReadWriteCategory;
//Do nothing if the form is closing
if (!pThis.gboFormIsClosing)
{
// Make sure serial port is open before trying to write
try
{
if (!gSysSerialPort.IsOpen)
gSysSerialPort.Open();
gSysSerialPort.Write(abyBuf, 0, iNumOfBytes);
CommunicationHistoryTimeCapture(abyBuf, "Transmitted");
}
catch
{
gboSerialPortProblemFlag = true;
}
try
{
pThis.Invoke(new delegateListBoxInfoSent(ListBoxInfoSentDelegate), new object[] { abyBuf });
}
catch
{
}
}
}//threadSerialPortSendBytes
//------------------------------
And given this code for receive:
//------------------------------
private void CaptureSerialPortDataReceived(object sender, SerialDataReceivedEventArgs e)
{
//------------------------------------------------------------------------------------------
//.....This function is called whenever bytes are received. It will continue to receive
// bytes while in this function. After bytes are read, the buffer is cleared, but will
// add new bytes to the buffer while in this function.
//------------------------------------------------------------------------------------------
//Delay long enough to receive all bytes
Thread.Sleep(300 * g.TIME_1_MSEC);
//Do nothing if the form is closing
if (!gboFormIsClosing)
{
try
{
byte[] abyBytesReceived = new byte[gSysSerialPort.BytesToRead];
gSysSerialPort.Read(abyBytesReceived, 0, abyBytesReceived.Length);
//Initiate action to call a function that will display the chars received on a dialog.
try
{
this.BeginInvoke(new delegateHandleBytesReceived(HandleBytesReceivedDelegate), new object[] { abyBytesReceived });
}
catch
{
MessageBox.Show("The invoke in threadSerialPortSendBytes failed.");
}
}
catch
{
}
}
}//CaptureSerialPortDataReceived
//------------------------------
//------------------------------
private void HandleBytesReceivedDelegate(byte[] abyBuf)
{
//For some reason, the receive bytes handler triggers falsely after receiving bytes ... ignore
// if there are no bytes.
if (cas.boCheckReceivedByteCount(abyBuf))
{
gTimersTimerModbusReceivedFlag.Enabled = false;
SetLabelNoResponseToBlank();
CommunicationHistoryTimeCapture(abyBuf, "Received");
if (mod.CrcIsCorrect(abyBuf))
{
List<UInt16> listuiReceivedInfo = new List<UInt16>();
listuiReceivedInfo.Add(guiModReadWriteCategory);
string stReturnValue = cas.stSortAndVerifyReceivedInfoValid(abyBuf, listuiReceivedInfo);
if (stReturnValue != "")
gLBxResponse.Items.Add(stReturnValue);
else
{
DisplayInfoReceivedInListBoxes(listuiReceivedInfo);
SaveAndDisplaySomeParamsInLabels(listuiReceivedInfo);
}
}
}
}//HandleBytesReceivedDelegate
//------------------------------
Occasionally the receive captures two additional bytes (0x3F, 0x3F) in front of the bytes transmitted to the computer. A scope and a laptop monitoring the communication do not show these additional bytes. An example:
Transmitted by the computer => FE 03 26 00 01 00 5B. Transmitted to computer => FE 03 02 0F 00 A9 A0 (verified by scope and laptop monitor). Received by the computer 3F 3F FE 03 02 0F 00 A9 A0.
Note that this occurs rarely. Most of the time it is correct. Baud = 9600 Even parity.
cte677