0

I need to write and read data from serial port to my device. I've test certain approach where at first, I'm receiving the data using SerialDataReceivedEventArgs and I feel it is hard to read the port where I need to define the command that send where as the command is almost 200 commands.

My first approach is using:-

private void ObjCom_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
        {
            if (!ObjCom.IsOpen) return;
            byte[] data = new byte[ObjCom.BytesToRead];
            ObjCom.Read(data, 0, data.Length);
            RaiseEventMsg("Buffer String: " + BitConverter.ToString(data).Replace("-", " "));
        }

The RaiseEventMsg is a delegate event to pass current information to Main UI. The second approach is:-

private long lngTickCount = Convert.ToInt64(1000L);
public void StartWriteToPort()
{
    byte[] Cmd = null;
    string strCmd = string.Empty;
    string strMsg = null;
    bool bCont = true;
    long lngCurrent = 0;
    long lngNow = 0;
    try
    {
        RaiseEventMsg("Start Write To Port");
        ObjCom.DiscardOutBuffer();
        ObjCom.DiscardInBuffer();

        GetFullCommandByte(ref Cmd, Convert.ToByte(123)); // Referencing Cmd with return and pass Command List(various set of command)
        ObjCom.Write(Cmd, 0, Cmd.Length);
        strCmd = ByteArrayToString(Cmd); // Convert byte array to Hex string
        RaiseEventMsg("Send: " + strCmd);
        bool bTimeout = false;
        lngCurrent = DateTime.Now.Ticks;
        while (!bTimeout)
        {
            lngNow = DateTime.Now.Ticks;
            if (lngNow > (lngCurrent + (3 * lngTickCount)))
            {
                bTimeout = true;
                break;
            }
        }

        lngCurrent = DateTime.Now.Ticks;
        while (ObjCom.BytesToRead <= 0)
        {
            lngNow = DateTime.Now.Ticks;
            if (lngNow > (lngCurrent + (1000 * lngTickCount)))
            {
                bCont = false;
                break;
            }
        }
        if (!bCont)
        {
            strMsg = "Error - Timeout Hit";
            RaiseEventMsg(strMsg);
            return;
        }

        int Idx = 0;
        string strASCIIFull = string.Empty;
        if ((ObjCom.BytesToRead > 0) & (bCont == true))
        {
            while (ObjCom.BytesToRead > 0)
            {
                var strASCII = ObjCom.ReadByte();
                var TmpHex = System.Convert.ToString(strASCII, 16).ToUpper();
                if (TmpHex.Length == 1)
                {
                    strASCIIFull += (" 0" + TmpHex);
                }
                else
                {
                    strASCIIFull += (" " + TmpHex);
                }
                lngCurrent = DateTime.Now.Ticks;
                while (ObjCom.BytesToRead <= 0)
                {
                    lngNow = DateTime.Now.Ticks;
                    if (lngNow > (lngCurrent + (2 * lngTickCount)))
                    {
                        bCont = false;
                        break;
                    }
                }
                Idx += 1;
            }
        }

        RaiseEventMsg("Recv: " + strASCIIFull);
    }
    catch (System.Exception ex)
    {
        string error = $"Exception on StartWriteToPort. Message: {ex.Message}. StackTrace: {ex.StackTrace}";
    }
}

Problem on second approach is when I call this function for second time, the timeout will hit . But for Serial event, it does not have the problem, the protocol for timeout is set to 1 seconds. My device currently connected using USB without converter. The input cable to device is type B port (like standard printer port).

Is the any other way to read directly from port or any improvement on current code?

ProgrammingLlama
  • 36,677
  • 7
  • 67
  • 86
Luiey
  • 843
  • 2
  • 23
  • 50

1 Answers1

0

You need to learn how to layer your code. At the moment you have one long function that tries to do everything.

If you had several smaller functions that did specific things like reading or writing a chunk of information then it would make what you are trying to do simpler.

For example, serial communications generally have some sort of protocol that encapsulates how the packets of information are stored. Say the protocol was "", then you know every packet starts with an STX byte (0x01), a length byte, which tells you how many bytes are in the section, and there must be an ETX byte (0x02) at the end. You could write a function that would return an array of bytes that are just the because the function would interpret the stream and extract the relevant parts.

Then it might be as simple as:

var packet1 = ReadPacket();
WritePacket(outputData);
var packet2 = ReadPacket();
Neil
  • 11,059
  • 3
  • 31
  • 56