G400 serial port receiving max data of 35?

Is there a max recieve size of buffer?
I am trying to get a string back from the serial device. This works on a PC serial port.
When I send command I get only the first 35 bytes of data stream.
This is code where I try to read serial port.

// Loop until we get a full buffer or we timeout
                while (BytesRead < expectedBytes)
                {
                    BytesRead += serialPort.Read(readBuffer, BytesRead, Math.Min(serialPort.BytesToRead, expectedBytes - BytesRead));

                    /*if (TimedOut)
                        break;
                     * */

                    Thread.Sleep(5);
                }

rx_databuffer = new byte[expectedBytes];
And expected bytes = 67

Hi, isn’t it rigth to start reading always from 0?

 
// Loop until we get a full buffer or we timeout
while (BytesRead < expectedBytes)
{
      BytesRead += serialPort.Read(readBuffer, 0 , Math.Min(serialPort.BytesToRead, expectedBytes - BytesRead));

                     /*if (TimedOut)
                         break;
                      * */

   Thread.Sleep(5);
}   

I believe so as that is what is recommended in ghi docs. I changed that to zero and eliminated math min functions as well, using just max bytes.
I increased wait time between sending and receiving.
still I only get 35 bytes back from serial method.
Again sending the command from pc get correct array back via device
Sniffed signals coming from device and it is sending data but serial methods not receiving it.
Any thoughts?

Prepare a minimal program which displays your problem and post it. Hard to figure out what is happening with only a snippet of code.

1 Like

I create a RFID reader in Application Main:

Site.RFID = new RFIDController(Settings, Logger);
                RFIDThread = new Thread(Site.RFID.Start);
                RFIDThread.Start();

Then RFID Start connects my serial port:

public void Start()
        {
            try
            {
                rfidSerialCommand = new RFIDSerialCommands("Com1", 19200, Logger);
                rfidSerialCommand.TurnOnTransmitter();
                //rfidSerialCommand.
                Thread.Sleep(Timeout.Infinite);
            }
            catch (Exception exception)
            {
                Logger.LogError(Device.RFID, "Start()", exception.Message, exception.StackTrace, exception.InnerException);
            }
        }

Controller I call RFID method:

public bool GetRawData()
        {
            try
            {
                byte[] holder = null;
                if (CheckedBlocksRead(Block00, Block15, out holder))
                {
                    holder.CopyTo(CardBlocks, 0);
                    Debug.Print(Utilities.BytesToHexString(CardBlocks));
                    return true;
                }
            }

CheckedBlocksRead is:

 ReadBlockData)
        {
            try
            {
                byte[] readBlocks = null;
                int expRetLen = (4 * (endBlock - startBlock + 1));
                if (rfidSerialCommand.ReadBlocks(startBlock, endBlock, out readBlocks))
                {
                    Utilities.CopyPassedArrayToOutArray(readBlocks, 1, expRetLen, out ReadBlockData, 0);
                    return true;
                }
            }
            catch (Exception exception)
            {
                Logger.LogError(Device.RFID, "CheckedBlocksRead()", exception.Message, exception.StackTrace, exception.InnerException);
            }
            ReadBlockData = new byte[1];
            return false;

CALLs>>>:


public virtual bool ReadBlocks(short startBlock, short endBlock, out byte[] readBlocks)
        {
            int expectedBytes = 7 + (4 * (endBlock - startBlock));
            byte lowByte;
            byte highByte;
            try
            {
                //byte[] readBlocks = null;
                CalculateCRC16(new byte[] { 0x03, 0x23, (byte)startBlock, (byte)endBlock }, out lowByte, out highByte);
                ReadBlocksCommand[4] = (byte)startBlock;
                ReadBlocksCommand[5] = (byte)endBlock;
                ReadBlocksCommand[6] = lowByte;
                ReadBlocksCommand[7] = highByte;
                if (RetrySend(ReadBlocksCommand, expectedBytes, out readBlocks)) return true;
            }
            catch (Exception exception)
            {
                Logger.LogError(Device.RFID, "ReadBlocks()", exception.Message, exception.StackTrace, exception.InnerException);
            }
            readBlocks = new byte[1];
            return false;
        private bool RetrySend(byte[] command, int expectedBytes, out byte[] bytes)
        {
            int retries = 3;
            while (retries > 0)
            {
                retries--;
                bytes = SerialRFIDConnection.Send(command, expectedBytes);
                if (Utilities.IsEmpty(bytes, 1))
                {
                    Debug.Print("Empty Bytes Returned");
                    continue;
                }       
                return true;
            }
            bytes = new byte[1];
            return false;
        }

Serial method that finally calls SerialCode:

 bytes, int expectedBytes)
        {
            BytesRead = 0;
            byte[] readBuffer = new byte[expectedBytes];
            try
            {
                if (!IsOpen)
                    Open();
                // Reset Timeout
                ResetTimeout();
                FlushBuffers();
                //serialPort.SetLength(45);
                serialPort.Write(bytes, 0, bytes.Length);
                Thread.Sleep(100);
                //BytesRead = serialPort.Read(readBuffer, 0, readBuffer.Length);
                // Loop until we get a full buffer or we timeout
                while (BytesRead < expectedBytes)
                {
                    BytesRead += serialPort.Read(readBuffer, BytesRead, Math.Min(serialPort.BytesToRead, expectedBytes - BytesRead));
                    if (TimedOut)
                        break;
                    Thread.Sleep(5);
                }
                // Read input
                if (BytesRead < expectedBytes)
                    serialPort.Read(readBuffer, BytesRead, Math.Min(serialPort.BytesToRead, expectedBytes - BytesRead));
                FlushBuffers();
            }
            catch (Exception exception)
            {
                Logger.LogError(Device.SerialPort, "Send(expectedBytes)", exception.Message, exception.StackTrace, exception.InnerException);
            }

            return readBuffer;
1 Like

Public instances of the serialport class are not thread safe:

see bottom of:

Its hard for me to tell if this is an issue in your code from just the snippets though.

Having a ‘sleep’ statement in serial port code is a big red flag to me.
You are most likely putting the serial handling code to sleep here. (serial events are not interrupts running on new threads, they is a single system thread that handles them & most other events)